]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x32 write_linux_prstatus
authorAlan Modra <amodra@gmail.com>
Thu, 21 Jan 2016 23:30:34 +0000 (10:00 +1030)
committerAlan Modra <amodra@gmail.com>
Thu, 21 Jan 2016 23:30:34 +0000 (10:00 +1030)
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.

gdb/amd64-linux-tdep.c
gdb/gdbarch.c
gdb/gdbarch.h
gdb/gdbarch.sh
gdb/linux-tdep.c

index c545cd02a5605b2b02bcab9a1881534d41a8f6a1..cdde600b65738b92ecec476e171848b860599af4 100644 (file)
@@ -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);
 
index fe0acbc8640518795f8a6ac15fad3b8f8f36ac14..58f8ce51decfb870f2af4b83e11354dba318ee04 100644 (file)
@@ -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);
index 5e00b32c9f4b23b091f37845507648b1eabb428a..7e6e8ca8d0a66251b0baf1bedd083ec20a869e9a 100644 (file)
@@ -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 */
index 71e3e8c580f176c1cab402952d2c54ac894e107d..c10ac6a1e0aa7366e45290c2f93072284d81d94b 100755 (executable)
@@ -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
index d432c471438580f5e6197783078976464ce74f56..a49a0f012ecca769cf3f72c8a05c6bd3cc19ff1e 100644 (file)
@@ -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.  */