diff options
author | Daniel Jacobowitz <drow@false.org> | 2007-06-18 15:46:38 +0000 |
---|---|---|
committer | Daniel Jacobowitz <drow@false.org> | 2007-06-18 15:46:38 +0000 |
commit | 31d99776c73d6fca13163da59c852b0fa99f89b8 (patch) | |
tree | 4dace09d40a34a22c8a02adcc688ae8c991973bb /gdb/remote.c | |
parent | * rclex.c: (cpp_line): Add code_page pragma support. (diff) | |
download | binutils-gdb-31d99776c73d6fca13163da59c852b0fa99f89b8.tar.gz binutils-gdb-31d99776c73d6fca13163da59c852b0fa99f89b8.tar.bz2 binutils-gdb-31d99776c73d6fca13163da59c852b0fa99f89b8.zip |
* coffread.c (coff_sym_fns): Add default_symfile_segments.
* dbxread.c (start_psymtab): Check HAVE_ELF.
(aout_sym_fns): Likewise.
* elfread.c (elf_symfile_segments): New.
(elf_sym_fns): Add elf_symfile_segments.
* mipsread.c (ecoff_sym_fns): Add default_symfile_segments.
* remote.c (get_offsets): Use symfile_map_offsets_to_segments.
Skip if there is no symfile_objfile. Handle TextSeg and DataSeg.
* somread.c (som_sym_fns): Use default_symfile_segments.
* symfile.c (find_sym_fns): Take a BFD and return the sym_fns.
(init_objfile_sect_indices): Call symfile_find_segment_sections.
(default_symfile_segments): New function.
(syms_from_objfile): Update call to find_sym_fns.
(symfile_get_segment_data, free_symfile_segment_data): New.
(symfile_map_offsets_to_segments): New.
(symfile_find_segment_sections): New.
* symfile.h (struct symfile_segment_data): New.
(struct sym_fns): Add sym_segments.
(default_symfile_segments, symfile_get_segment_data)
(free_symfile_segment_data): New prototypes.
(symfile_map_offsets_to_segments): Likewise.
* xcoffread.c (xcoff_sym_fns): Add default_symfile_segments.
* Makefile.in (COMMON_OBS): Remove elfread.o.
(elf_internal_h): New.
(elfread.o): Update.
* configure.ac: Add elfread.o to COMMON_OBS if bfd/elf.o was
compiled.
* config.in, configure: Regenerated.
* NEWS: Mention qOffsets changes.
* gdb.texinfo (General Query Packets): Document qOffsets changes.
* Makefile.def: Add dependency from configure-gdb to all-bfd.
* Makefile.in: Regenerated.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r-- | gdb/remote.c | 116 |
1 files changed, 91 insertions, 25 deletions
diff --git a/gdb/remote.c b/gdb/remote.c index f4f267b420d..3990a34285a 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -2016,9 +2016,13 @@ get_offsets (void) struct remote_state *rs = get_remote_state (); char *buf; char *ptr; - int lose; - CORE_ADDR text_addr, data_addr, bss_addr; + int lose, num_segments = 0, do_sections, do_segments; + CORE_ADDR text_addr, data_addr, bss_addr, segments[2]; struct section_offsets *offs; + struct symfile_segment_data *data; + + if (symfile_objfile == NULL) + return; putpkt ("qOffsets"); getpkt (&rs->buf, &rs->buf_size, 0); @@ -2047,47 +2051,109 @@ get_offsets (void) /* Don't use strtol, could lose on big values. */ while (*ptr && *ptr != ';') text_addr = (text_addr << 4) + fromhex (*ptr++); - } - else - lose = 1; - if (!lose && strncmp (ptr, ";Data=", 6) == 0) - { - ptr += 6; - while (*ptr && *ptr != ';') - data_addr = (data_addr << 4) + fromhex (*ptr++); - } - else - lose = 1; + if (strncmp (ptr, ";Data=", 6) == 0) + { + ptr += 6; + while (*ptr && *ptr != ';') + data_addr = (data_addr << 4) + fromhex (*ptr++); + } + else + lose = 1; + + if (!lose && strncmp (ptr, ";Bss=", 5) == 0) + { + ptr += 5; + while (*ptr && *ptr != ';') + bss_addr = (bss_addr << 4) + fromhex (*ptr++); - if (!lose && strncmp (ptr, ";Bss=", 5) == 0) + if (bss_addr != data_addr) + warning (_("Target reported unsupported offsets: %s"), buf); + } + else + lose = 1; + } + else if (strncmp (ptr, "TextSeg=", 8) == 0) { - ptr += 5; + ptr += 8; + /* Don't use strtol, could lose on big values. */ while (*ptr && *ptr != ';') - bss_addr = (bss_addr << 4) + fromhex (*ptr++); + text_addr = (text_addr << 4) + fromhex (*ptr++); + num_segments = 1; + + if (strncmp (ptr, ";DataSeg=", 9) == 0) + { + ptr += 9; + while (*ptr && *ptr != ';') + data_addr = (data_addr << 4) + fromhex (*ptr++); + num_segments++; + } } else lose = 1; if (lose) error (_("Malformed response to offset query, %s"), buf); - - if (symfile_objfile == NULL) - return; + else if (*ptr != '\0') + warning (_("Target reported unsupported offsets: %s"), buf); offs = ((struct section_offsets *) alloca (SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections))); memcpy (offs, symfile_objfile->section_offsets, SIZEOF_N_SECTION_OFFSETS (symfile_objfile->num_sections)); - offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr; + data = get_symfile_segment_data (symfile_objfile->obfd); + do_segments = (data != NULL); + do_sections = num_segments == 0; - /* This is a temporary kludge to force data and bss to use the same offsets - because that's what nlmconv does now. The real solution requires changes - to the stub and remote.c that I don't have time to do right now. */ + /* Text= and Data= specify offsets for the text and data sections, + but symfile_map_offsets_to_segments expects base addresses + instead of offsets. If we have two segments, we can still + try to relocate the whole segments instead of just ".text" + and ".data". */ + if (num_segments == 0) + { + do_sections = 1; + if (data == NULL || data->num_segments != 2) + do_segments = 0; + else + { + segments[0] = data->segment_bases[0] + text_addr; + segments[1] = data->segment_bases[1] + data_addr; + } + } + else + { + do_sections = 0; + segments[0] = text_addr; + segments[1] = data_addr; + } + + if (do_segments) + { + int ret = symfile_map_offsets_to_segments (symfile_objfile->obfd, data, + offs, num_segments, segments); + + if (ret == 0 && !do_sections) + error (_("Can not handle qOffsets TextSeg response with this symbol file")); + + if (ret > 0) + do_sections = 0; + } - offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr; - offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr; + free_symfile_segment_data (data); + + if (do_sections) + { + offs->offsets[SECT_OFF_TEXT (symfile_objfile)] = text_addr; + + /* This is a temporary kludge to force data and bss to use the same offsets + because that's what nlmconv does now. The real solution requires changes + to the stub and remote.c that I don't have time to do right now. */ + + offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr; + offs->offsets[SECT_OFF_BSS (symfile_objfile)] = data_addr; + } objfile_relocate (symfile_objfile, offs); } |