aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Jacobowitz <drow@false.org>2007-06-18 15:46:38 +0000
committerDaniel Jacobowitz <drow@false.org>2007-06-18 15:46:38 +0000
commit31d99776c73d6fca13163da59c852b0fa99f89b8 (patch)
tree4dace09d40a34a22c8a02adcc688ae8c991973bb /gdb/remote.c
parent* rclex.c: (cpp_line): Add code_page pragma support. (diff)
downloadbinutils-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.c116
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);
}