diff options
author | Alan Modra <amodra@gmail.com> | 2016-01-22 10:00:34 +1030 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2016-01-22 10:00:34 +1030 |
commit | abd215c9bd3752a9bb475ee30affb5a26d65b1a7 (patch) | |
tree | 1ca07d9405e12cf71bbd5b64e874bf630d051006 | |
parent | e2b337e5a957affa1cb31693e1424d015a6e8f2a (diff) | |
download | gdb-abd215c9bd3752a9bb475ee30affb5a26d65b1a7.zip gdb-abd215c9bd3752a9bb475ee30affb5a26d65b1a7.tar.gz gdb-abd215c9bd3752a9bb475ee30affb5a26d65b1a7.tar.bz2 |
x32 write_linux_prstatus
x32 uses an elf_gregset64_t in the prstatus struct, which aligns the
struct to eight bytes. This means four bytes of padding at the end of
the struct.
* amd64-linux-tdep.c: Include elf-bfd.h.
(amd64_x32_write_linux_prstatus): New function.
(amd64_x32_linux_init_abi): Use it.
* linux-tdep.c (linux_collect_regset_section_cb): Allocate an
extra four bytes for regset buffer.
* gdbarch.sh (elfcore_write_linux_prstatus): Remove const from info.
* gdbarch.c: Regenerate.
* gdbarch.h: Regenerate.
-rw-r--r-- | gdb/amd64-linux-tdep.c | 22 | ||||
-rw-r--r-- | gdb/gdbarch.c | 2 | ||||
-rw-r--r-- | gdb/gdbarch.h | 4 | ||||
-rwxr-xr-x | gdb/gdbarch.sh | 2 | ||||
-rw-r--r-- | gdb/linux-tdep.c | 3 |
5 files changed, 27 insertions, 6 deletions
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index c545cd0..cdde600 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -28,6 +28,7 @@ #include "gdbtypes.h" #include "reggroups.h" #include "regset.h" +#include "elf-bfd.h" /* for elfcore_write_* */ #include "parser-defs.h" #include "user-regs.h" #include "amd64-linux-tdep.h" @@ -1646,6 +1647,25 @@ amd64_linux_iterate_over_regset_sections (struct gdbarch *gdbarch, &amd64_linux_xstateregset, "XSAVE extended state", cb_data); } +/* The standard elfcore_write_linux_prstatus32 isn't quite correct + for x32, which needs an extra 4 bytes of padding at the end of + the note. */ + +static char * +amd64_x32_write_linux_prstatus (bfd *obfd, + char *buf, + int *bufsize, + struct elf_internal_linux_prstatus *prstatus) +{ + /* Tack pr_fpvalid to end of pr_regs. */ + bfd_put_32 (obfd, prstatus->pr_fpvalid, + (char *) prstatus->pr_reg + prstatus->pr_reg_size); + prstatus->pr_reg_size += 4; + /* pr_fpvalid becomes padding. */ + prstatus->pr_fpvalid = 0; + return elfcore_write_linux_prstatus32 (obfd, buf, bufsize, prstatus); +} + /* The instruction sequences used in x86_64 machines for a disabled is-enabled probe. */ @@ -2075,7 +2095,7 @@ amd64_x32_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* x32's layout is not compatible with the 32-bit layout. */ set_gdbarch_elfcore_write_linux_prstatus - (gdbarch, gdb_deprecated_elfcore_write_linux_prstatus); + (gdbarch, amd64_x32_write_linux_prstatus); amd64_x32_init_abi (info, gdbarch); diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index fe0acbc..58f8ce5 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -3481,7 +3481,7 @@ gdbarch_elfcore_write_linux_prstatus_p (struct gdbarch *gdbarch) } char * -gdbarch_elfcore_write_linux_prstatus (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prstatus *info) +gdbarch_elfcore_write_linux_prstatus (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, struct elf_internal_linux_prstatus *info) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->elfcore_write_linux_prstatus != NULL); diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 5e00b32..7e6e8ca 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -833,8 +833,8 @@ extern void set_gdbarch_elfcore_write_linux_prpsinfo (struct gdbarch *gdbarch, g extern int gdbarch_elfcore_write_linux_prstatus_p (struct gdbarch *gdbarch); -typedef char * (gdbarch_elfcore_write_linux_prstatus_ftype) (bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prstatus *info); -extern char * gdbarch_elfcore_write_linux_prstatus (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prstatus *info); +typedef char * (gdbarch_elfcore_write_linux_prstatus_ftype) (bfd *obfd, char *note_data, int *note_size, struct elf_internal_linux_prstatus *info); +extern char * gdbarch_elfcore_write_linux_prstatus (struct gdbarch *gdbarch, bfd *obfd, char *note_data, int *note_size, struct elf_internal_linux_prstatus *info); extern void set_gdbarch_elfcore_write_linux_prstatus (struct gdbarch *gdbarch, gdbarch_elfcore_write_linux_prstatus_ftype *elfcore_write_linux_prstatus); /* Find core file memory regions */ diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 71e3e8c..c10ac6a 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -703,7 +703,7 @@ M:char *:make_corefile_notes:bfd *obfd, int *note_size:obfd, note_size # as we call the Linux generic routines in bfd to write notes by # default. F:char *:elfcore_write_linux_prpsinfo:bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prpsinfo *info:obfd, note_data, note_size, info -F:char *:elfcore_write_linux_prstatus:bfd *obfd, char *note_data, int *note_size, const struct elf_internal_linux_prstatus *info:obfd, note_data, note_size, info +F:char *:elfcore_write_linux_prstatus:bfd *obfd, char *note_data, int *note_size, struct elf_internal_linux_prstatus *info:obfd, note_data, note_size, info # Find core file memory regions M:int:find_memory_regions:find_memory_region_ftype func, void *data:func, data diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index d432c47..a49a0f0 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1574,7 +1574,8 @@ linux_collect_regset_section_cb (const char *sect_name, int size, gdb_assert (regset && regset->collect_regset); - buf = (char *) xmalloc (size); + /* Extra 4 bytes for use by amd64_x32_write_linux_prstatus. */ + buf = (char *) xmalloc (size + 4); regset->collect_regset (regset, data->regcache, -1, buf, size); /* PRSTATUS still needs to be treated specially. */ |