aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-01-22 10:00:34 +1030
committerAlan Modra <amodra@gmail.com>2016-01-22 10:00:34 +1030
commitabd215c9bd3752a9bb475ee30affb5a26d65b1a7 (patch)
tree1ca07d9405e12cf71bbd5b64e874bf630d051006
parente2b337e5a957affa1cb31693e1424d015a6e8f2a (diff)
downloadgdb-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.c22
-rw-r--r--gdb/gdbarch.c2
-rw-r--r--gdb/gdbarch.h4
-rwxr-xr-xgdb/gdbarch.sh2
-rw-r--r--gdb/linux-tdep.c3
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. */