diff options
author | Andreas Arnez <arnez@linux.vnet.ibm.com> | 2014-09-04 15:26:43 +0000 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2014-09-30 09:14:32 +0200 |
commit | 5aa82d050d61784823767fe3c982b6862fa47391 (patch) | |
tree | 54b683b4d6e67dbbe25d400bf4575a7b3fad98e3 /gdb/linux-tdep.c | |
parent | 6a5f3f4353a317dc16d7371fda2ec80835036af5 (diff) | |
download | gdb-5aa82d050d61784823767fe3c982b6862fa47391.zip gdb-5aa82d050d61784823767fe3c982b6862fa47391.tar.gz gdb-5aa82d050d61784823767fe3c982b6862fa47391.tar.bz2 |
Replace 'core_regset_sections' by iterator method
The core_regset_sections list in gdbarch (needed for multi-arch
capable core file generation support) is replaced by an iterator
method. Overall, this reduces the code a bit, and it allows for more
flexibility.
gdb/ChangeLog:
* amd64-linux-tdep.c (amd64_linux_regset_sections): Remove.
(amd64_linux_iterate_over_regset_sections): New.
(amd64_linux_init_abi_common): Don't install the regset section
list, but the new iterator in gdbarch.
* arm-linux-tdep.c (arm_linux_fpa_regset_sections)
(arm_linux_vfp_regset_sections): Remove. Move combined logic...
(arm_linux_iterate_over_regset_sections): ...here. New function.
(arm_linux_init_abi): Set iterator instead of section list.
* corelow.c (get_core_registers_cb): New function, logic moved
from...
(get_core_registers): ...loop body here. Use new iterator method
instead of walking through the regset section list.
* gdbarch.sh: Remove 'core_regset_sections'. New method
'iterate_over_regset_sections'. New typedef
'iterate_over_regset_sections_cb'.
* gdbarch.c: Regenerate.
* gdbarch.h: Likewise.
* i386-linux-tdep.c (i386_linux_regset_sections)
(i386_linux_sse_regset_sections, i386_linux_avx_regset_sections):
Remove.
(i386_linux_iterate_over_regset_sections): New.
(i386_linux_init_abi): Don't choose a regset section list, but
install new iterator in gdbarch.
* linux-tdep.c (struct linux_collect_regset_section_cb_data): New.
(linux_collect_regset_section_cb): New function, logic moved
from...
(linux_collect_thread_registers): ...loop body here. Use iterator
method instead of walking through list.
(linux_make_corefile_notes_1): Check for presence of iterator
method instead of regset section list.
* ppc-linux-tdep.c (ppc_linux_vsx_regset_sections)
(ppc_linux_vmx_regset_sections, ppc_linux_fp_regset_sections)
(ppc64_linux_vsx_regset_sections, ppc64_linux_vmx_regset_sections)
(ppc64_linux_fp_regset_sections): Remove. Move combined logic...
(ppc_linux_iterate_over_regset_sections): ...here. New function.
(ppc_linux_init_abi): Don't choose from above regset section
lists, but install new iterator in gdbarch.
* regset.h (struct core_regset_section): Remove.
* s390-linux-tdep.c (struct gdbarch_tdep): Add new fields
have_linux_v1, have_linux_v2, and have_tdb.
(s390_linux32_regset_sections, s390_linux32v1_regset_sections)
(s390_linux32v2_regset_sections, s390_linux64_regset_sections)
(s390_linux64v1_regset_sections, s390_linux64v2_regset_sections)
(s390x_linux64_regset_sections, s390x_linux64v1_regset_sections)
(s390x_linux64v2_regset_sections): Remove. Move combined logic...
(s390_iterate_over_regset_sections): ...here. New function. Use
new tdep fields.
(s390_gdbarch_init): Set new tdep fields. Don't choose from above
regset section lists, but install new iterator.
Diffstat (limited to 'gdb/linux-tdep.c')
-rw-r--r-- | gdb/linux-tdep.c | 107 |
1 files changed, 68 insertions, 39 deletions
diff --git a/gdb/linux-tdep.c b/gdb/linux-tdep.c index dae59c5..3d8b1fc 100644 --- a/gdb/linux-tdep.c +++ b/gdb/linux-tdep.c @@ -1084,6 +1084,57 @@ linux_make_mappings_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, return note_data; } +/* Structure for passing information from + linux_collect_thread_registers via an iterator to + linux_collect_regset_section_cb. */ + +struct linux_collect_regset_section_cb_data +{ + struct gdbarch *gdbarch; + const struct regcache *regcache; + bfd *obfd; + char *note_data; + int *note_size; + unsigned long lwp; + enum gdb_signal stop_signal; + int abort_iteration; +}; + +/* Callback for iterate_over_regset_sections that records a single + regset in the corefile note section. */ + +static void +linux_collect_regset_section_cb (const char *sect_name, int size, + const char *human_name, void *cb_data) +{ + const struct regset *regset; + char *buf; + struct linux_collect_regset_section_cb_data *data = cb_data; + + if (data->abort_iteration) + return; + + regset = gdbarch_regset_from_core_section (data->gdbarch, sect_name, size); + gdb_assert (regset && regset->collect_regset); + + buf = xmalloc (size); + regset->collect_regset (regset, data->regcache, -1, buf, size); + + /* PRSTATUS still needs to be treated specially. */ + if (strcmp (sect_name, ".reg") == 0) + data->note_data = (char *) elfcore_write_prstatus + (data->obfd, data->note_data, data->note_size, data->lwp, + gdb_signal_to_host (data->stop_signal), buf); + else + data->note_data = (char *) elfcore_write_register_note + (data->obfd, data->note_data, data->note_size, + sect_name, buf, size); + xfree (buf); + + if (data->note_data == NULL) + data->abort_iteration = 1; +} + /* Records the thread's register state for the corefile note section. */ @@ -1094,47 +1145,25 @@ linux_collect_thread_registers (const struct regcache *regcache, enum gdb_signal stop_signal) { struct gdbarch *gdbarch = get_regcache_arch (regcache); - struct core_regset_section *sect_list; - unsigned long lwp; + struct linux_collect_regset_section_cb_data data; - sect_list = gdbarch_core_regset_sections (gdbarch); - gdb_assert (sect_list); + data.gdbarch = gdbarch; + data.regcache = regcache; + data.obfd = obfd; + data.note_data = note_data; + data.note_size = note_size; + data.stop_signal = stop_signal; + data.abort_iteration = 0; /* For remote targets the LWP may not be available, so use the TID. */ - lwp = ptid_get_lwp (ptid); - if (!lwp) - lwp = ptid_get_tid (ptid); - - while (sect_list->sect_name != NULL) - { - const struct regset *regset; - char *buf; - - regset = gdbarch_regset_from_core_section (gdbarch, - sect_list->sect_name, - sect_list->size); - gdb_assert (regset && regset->collect_regset); - - buf = xmalloc (sect_list->size); - regset->collect_regset (regset, regcache, -1, buf, sect_list->size); - - /* PRSTATUS still needs to be treated specially. */ - if (strcmp (sect_list->sect_name, ".reg") == 0) - note_data = (char *) elfcore_write_prstatus - (obfd, note_data, note_size, lwp, - gdb_signal_to_host (stop_signal), buf); - else - note_data = (char *) elfcore_write_register_note - (obfd, note_data, note_size, - sect_list->sect_name, buf, sect_list->size); - xfree (buf); - sect_list++; - - if (!note_data) - return NULL; - } - - return note_data; + data.lwp = ptid_get_lwp (ptid); + if (!data.lwp) + data.lwp = ptid_get_tid (ptid); + + gdbarch_iterate_over_regset_sections (gdbarch, + linux_collect_regset_section_cb, + &data, regcache); + return data.note_data; } /* Fetch the siginfo data for the current thread, if it exists. If @@ -1524,7 +1553,7 @@ linux_make_corefile_notes_1 (struct gdbarch *gdbarch, bfd *obfd, int *note_size) converted to gdbarch_core_regset_sections, we no longer need to fall back to the target method at this point. */ - if (!gdbarch_core_regset_sections (gdbarch)) + if (!gdbarch_iterate_over_regset_sections_p (gdbarch)) return target_make_corefile_notes (obfd, note_size); else return linux_make_corefile_notes (gdbarch, obfd, note_size, |