+2017-10-11 Maciej W. Rozycki <macro@imgtec.com>
+
+ * elf-bfd.h (elf_backend_data): Add `linux_prpsinfo64_ugid16'
+ member.
+ * elf-linux-core.h (elf_external_linux_prpsinfo64): Rename to...
+ (elf_external_linux_prpsinfo64_ugid32): ... this.
+ (swap_linux_prpsinfo32_out): Rename to...
+ (swap_linux_prpsinfo32_ugid32_out): ... this.
+ (elf_external_linux_prpsinfo64_ugid16): New structure.
+ (swap_linux_prpsinfo64_ugid16_out): New function.
+ * elfxx-target.h [!elf_backend_linux_prpsinfo64_ugid16]
+ (elf_backend_linux_prpsinfo64_ugid16): Define.
+ (elfNN_bed): Initialize `linux_prpsinfo64_ugid16' member.
+ * elf.c (elfcore_write_linux_prpsinfo64): Handle both variants
+ of the 64-bit Linux core PRPSINFO note.
+ * elf64-sh64.c (elf_backend_linux_prpsinfo64_ugid16): Define.
+
2017-10-11 Maciej W. Rozycki <macro@imgtec.com>
* elf-bfd.h (elf_backend_data): Add `linux_prpsinfo32_ugid16'
ABI-defined, thus we choose to use char arrays here in order to
avoid dealing with different types in different architectures.
+ This is the variant for targets which use a 32-bit data type for
+ UID and GID, as most Linux ports do. The SH64 port uses a 16-bit
+ data type instead; see below for the alternative variant.
+
This structure will ultimately be written in the corefile's note
section, as the PRPSINFO. */
-struct elf_external_linux_prpsinfo64
+struct elf_external_linux_prpsinfo64_ugid32
{
char pr_state; /* Numeric process state. */
char pr_sname; /* Char for pr_state. */
};
/* Helper function to copy an elf_internal_linux_prpsinfo in host
- endian to an elf_external_linux_prpsinfo64 in target endian. */
+ endian to an elf_external_linux_prpsinfo64_ugid32 in target endian. */
static inline void
-swap_linux_prpsinfo64_out (bfd *obfd,
- const struct elf_internal_linux_prpsinfo *from,
- struct elf_external_linux_prpsinfo64 *to)
+swap_linux_prpsinfo64_ugid32_out
+ (bfd *obfd,
+ const struct elf_internal_linux_prpsinfo *from,
+ struct elf_external_linux_prpsinfo64_ugid32 *to)
{
bfd_put_8 (obfd, from->pr_state, &to->pr_state);
bfd_put_8 (obfd, from->pr_sname, &to->pr_sname);
strncpy (to->pr_psargs, from->pr_psargs, sizeof (to->pr_psargs));
}
+/* External 64-bit structure for PRPSINFO. This structure is
+ ABI-defined, thus we choose to use char arrays here in order to
+ avoid dealing with different types in different architectures.
+
+ This is the variant for the SH64 port which uses a 16-bit data
+ type for UID and GID. Most Linux ports use a 32-bit data type
+ instead; see above for the alternative variant.
+
+ This structure will ultimately be written in the corefile's note
+ section, as the PRPSINFO. */
+
+struct elf_external_linux_prpsinfo64_ugid16
+ {
+ char pr_state; /* Numeric process state. */
+ char pr_sname; /* Char for pr_state. */
+ char pr_zomb; /* Zombie. */
+ char pr_nice; /* Nice val. */
+ char gap[4];
+ char pr_flag[8]; /* Flags. */
+ char pr_uid[2];
+ char pr_gid[2];
+ char pr_pid[4];
+ char pr_ppid[4];
+ char pr_pgrp[4];
+ char pr_sid[4];
+ char pr_fname[16]; /* Filename of executable. */
+ char pr_psargs[80]; /* Initial part of arg list. */
+ };
+
+/* Helper function to copy an elf_internal_linux_prpsinfo in host
+ endian to an elf_external_linux_prpsinfo64_ugid16 in target endian. */
+
+static inline void
+swap_linux_prpsinfo64_ugid16_out
+ (bfd *obfd,
+ const struct elf_internal_linux_prpsinfo *from,
+ struct elf_external_linux_prpsinfo64_ugid16 *to)
+{
+ bfd_put_8 (obfd, from->pr_state, &to->pr_state);
+ bfd_put_8 (obfd, from->pr_sname, &to->pr_sname);
+ bfd_put_8 (obfd, from->pr_zomb, &to->pr_zomb);
+ bfd_put_8 (obfd, from->pr_nice, &to->pr_nice);
+ bfd_put_64 (obfd, from->pr_flag, to->pr_flag);
+ bfd_put_16 (obfd, from->pr_uid, to->pr_uid);
+ bfd_put_16 (obfd, from->pr_gid, to->pr_gid);
+ bfd_put_32 (obfd, from->pr_pid, to->pr_pid);
+ bfd_put_32 (obfd, from->pr_ppid, to->pr_ppid);
+ bfd_put_32 (obfd, from->pr_pgrp, to->pr_pgrp);
+ bfd_put_32 (obfd, from->pr_sid, to->pr_sid);
+ strncpy (to->pr_fname, from->pr_fname, sizeof (to->pr_fname));
+ strncpy (to->pr_psargs, from->pr_psargs, sizeof (to->pr_psargs));
+}
+
#endif
(bfd *abfd, char *buf, int *bufsiz,
const struct elf_internal_linux_prpsinfo *prpsinfo)
{
- struct elf_external_linux_prpsinfo64 data;
+ if (get_elf_backend_data (abfd)->linux_prpsinfo64_ugid16)
+ {
+ struct elf_external_linux_prpsinfo64_ugid16 data;
- swap_linux_prpsinfo64_out (abfd, prpsinfo, &data);
- return elfcore_write_note (abfd, buf, bufsiz,
- "CORE", NT_PRPSINFO, &data, sizeof (data));
+ swap_linux_prpsinfo64_ugid16_out (abfd, prpsinfo, &data);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", NT_PRPSINFO, &data, sizeof (data));
+ }
+ else
+ {
+ struct elf_external_linux_prpsinfo64_ugid32 data;
+
+ swap_linux_prpsinfo64_ugid32_out (abfd, prpsinfo, &data);
+ return elfcore_write_note (abfd, buf, bufsiz,
+ "CORE", NT_PRPSINFO, &data, sizeof (data));
+ }
}
char *
#ifndef elf_backend_linux_prpsinfo32_ugid16
#define elf_backend_linux_prpsinfo32_ugid16 FALSE
#endif
+#ifndef elf_backend_linux_prpsinfo64_ugid16
+#define elf_backend_linux_prpsinfo64_ugid16 FALSE
+#endif
#ifndef elf_backend_stack_align
#define elf_backend_stack_align 16
#endif
elf_backend_caches_rawsize,
elf_backend_extern_protected_data,
elf_backend_always_renumber_dynsyms,
- elf_backend_linux_prpsinfo32_ugid16
+ elf_backend_linux_prpsinfo32_ugid16,
+ elf_backend_linux_prpsinfo64_ugid16
};
/* Forward declaration for use when initialising alternative_target field. */