* [rfc / remote protocol] ELF segment based qOffsets
@ 2007-05-09 19:12 Daniel Jacobowitz
2007-05-09 19:47 ` Eli Zaretskii
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2007-05-09 19:12 UTC (permalink / raw)
To: gdb-patches; +Cc: gdb
[Remote protocol change, so I've CC'd gdb@.]
This patch adds two new features to the qOffsets packet.
First, if the remote target replies "Text=4000;Data=9000" GDB used to
relocate the .text and .data sections in the object file. But
sections are not a good unit of relocation on many modern systems.
What about the .rodata section? Or more esoteric things for
dynamic executables, like .dynamic and .got? They get left
behind.
So this patch lets the symfile reader (e.g. elfread) describe the
segments of the object file which can be relocated individually. In
ELF, that means PT_LOAD entries in the program headers. Conventional
executables have two, one for the code and another for the writable
data. In special circumstances there may be one, or a multitude.
The default is to assume that any fully linked executable (i.e. not a
.o or .obj file) must be relocated in a single chunk, except for
ELF where we can parse the program headers.
Now, when we get Text=4000 we relocate the entire text segment by
0x4000 bytes.
Second, I was working with a SymbianOS target where the original
segment addresses are not available on the target. In the ELF file we
may have a program header at 0x1000 and another at 0x9000; but on the
target we only have two loadable regions and those addresses are
completely gone. So I added TextSeg= and DataSeg=. They're just like
Text= except for one thing: instead of adjusting the address by the
supplied offset, the segment's base address is completely replaced.
GDB reports an error if it can't break the file down into segments.
Things not done, but easy extensions if someone needs them later:
- remote protocol support for relocating arbitrary numbers of
segments. This would be easy now; add Seg3=XXXX et cetera to
the parser in get_offsets and document it.
- segment based relocation for other commands. I think it would
be sensible to use it for add-symbol-file too but you'd have to
adjust the user interface.
Here is the documentation of the new support, and the patch is at the
end of the message. What do you all think? Eli, is the
documentation OK?
@@ -23428,14 +23428,31 @@ digits). See @code{remote.c:parse_threa
@item qOffsets
@cindex section offsets, remote request
@cindex @samp{qOffsets} packet
-Get section offsets that the target used when re-locating the downloaded
-image. @emph{Note: while a @code{Bss} offset is included in the
-response, @value{GDBN} ignores this and instead applies the @code{Data}
-offset to the @code{Bss} section.}
+Get section offsets that the target used when relocating the downloaded
+image.
Reply:
@table @samp
-@item Text=@var{xxx};Data=@var{yyy};Bss=@var{zzz}
+@item Text=@var{xxx};Data=@var{yyy}@r{[};Bss=@var{zzz}@r{]}
+Relocate the @code{Text} section by @var{xxx} from its original address.
+Relocate the @code{Data} section by @var{yyy} from its original address.
+If the object file format provides segment information (e.g.@: @sc{elf}
+@samp{PT_LOAD} program headers), @value{GDBN} will relocate entire
+segments by the supplied offsets.
+
+@emph{Note: while a @code{Bss} offset may be included in the response,
+@value{GDBN} ignores this and instead applies the @code{Data} offset
+to the @code{Bss} section.}
+
+@item TextSeg=@var{xxx}@r{[};DataSeg=@var{yyy}@r{]}
+Relocate the first segment of the object file, which conventionally
+contains program code, to a starting address of @var{xxx}. If
+@samp{DataSeg} is specified, relocate the second segment, which
+conventionally contains modifiable data, to a starting address of
+@var{yyy}. @value{GDBN} will report an error if the object file
+does not contain segment information, or does not contain at least
+as many segments as mentioned in the reply. Extra segments are
+kept at fixed offsets relative to the last relocated segment.
@end table
--
Daniel Jacobowitz
CodeSourcery
2007-05-09 Daniel Jacobowitz <dan@codesourcery.com>
* coffread.c (coff_sym_fns): Add default_symfile_segments.
* dbxread.c (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 (elf_internal_h): New.
(elfread.o): Update.
* NEWS: Mention qOffsets changes.
* gdb.texinfo (General Query Packets): Document qOffsets changes.
---
gdb/Makefile.in | 4
gdb/NEWS | 4
gdb/coffread.c | 2
gdb/dbxread.c | 2
gdb/doc/gdb.texinfo | 27 +++++-
gdb/elfread.c | 74 +++++++++++++++++
gdb/mipsread.c | 2
gdb/remote.c | 116 ++++++++++++++++++++++------
gdb/somread.c | 2
gdb/symfile.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++------
gdb/symfile.h | 39 +++++++++
gdb/xcoffread.c | 2
12 files changed, 436 insertions(+), 52 deletions(-)
Index: gdb/coffread.c
===================================================================
--- gdb/coffread.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/coffread.c 2007-05-09 11:30:13.000000000 -0400
@@ -2133,6 +2133,8 @@ static struct sym_fns coff_sym_fns =
coff_symfile_read, /* sym_read: read a symbol file into symtab */
coff_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/dbxread.c
===================================================================
--- gdb/dbxread.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/dbxread.c 2007-05-09 11:30:13.000000000 -0400
@@ -3505,6 +3505,8 @@ static struct sym_fns aout_sym_fns =
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/elfread.c
===================================================================
--- gdb/elfread.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/elfread.c 2007-05-09 11:30:13.000000000 -0400
@@ -26,6 +26,8 @@
#include "bfd.h"
#include "gdb_string.h"
#include "elf-bfd.h"
+#include "elf/common.h"
+#include "elf/internal.h"
#include "elf/mips.h"
#include "symtab.h"
#include "symfile.h"
@@ -51,6 +53,76 @@ struct elfinfo
static void free_elfinfo (void *);
+/* Locate the segments in ABFD. */
+
+static struct symfile_segment_data *
+elf_symfile_segments (bfd *abfd)
+{
+ Elf_Internal_Phdr *phdrs, **segments;
+ long phdrs_size;
+ int num_phdrs, num_segments, num_sections, i;
+ asection *sect;
+ struct symfile_segment_data *data;
+
+ phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
+ if (phdrs_size == -1)
+ return NULL;
+
+ phdrs = alloca (phdrs_size);
+ num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
+ if (num_phdrs == -1)
+ return NULL;
+
+ num_segments = 0;
+ segments = alloca (sizeof (Elf_Internal_Phdr *) * num_phdrs);
+ for (i = 0; i < num_phdrs; i++)
+ if (phdrs[i].p_type == PT_LOAD)
+ segments[num_segments++] = &phdrs[i];
+
+ if (num_segments == 0)
+ return NULL;
+
+ data = XZALLOC (struct symfile_segment_data);
+ data->num_segments = num_segments;
+ data->segment_bases = XCALLOC (num_segments, CORE_ADDR);
+ data->segment_sizes = XCALLOC (num_segments, CORE_ADDR);
+
+ for (i = 0; i < num_segments; i++)
+ {
+ data->segment_bases[i] = segments[i]->p_vaddr;
+ data->segment_sizes[i] = segments[i]->p_memsz;
+ }
+
+ num_sections = bfd_count_sections (abfd);
+ data->segment_info = XCALLOC (num_sections, int);
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ int j;
+ CORE_ADDR vma;
+
+ if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ continue;
+
+ vma = bfd_get_section_vma (abfd, sect);
+
+ for (j = 0; j < num_segments; j++)
+ if (segments[j]->p_memsz > 0
+ && vma >= segments[j]->p_vaddr
+ && vma < segments[j]->p_vaddr + segments[j]->p_memsz)
+ {
+ data->segment_info[i] = j + 1;
+ break;
+ }
+
+ if (bfd_get_section_size (sect) > 0 && j == num_segments)
+ warning (_("Loadable segment \"%s\" outside of ELF segments"),
+ bfd_section_name (abfd, sect));
+ }
+
+ return data;
+}
+
/* We are called once per section from elf_symfile_read. We
need to examine each section we are passed, check to see
if it is something we are interested in processing, and
@@ -741,6 +813,8 @@ static struct sym_fns elf_sym_fns =
elf_symfile_read, /* sym_read: read a symbol file into symtab */
elf_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ elf_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/mipsread.c
===================================================================
--- gdb/mipsread.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/mipsread.c 2007-05-09 11:30:13.000000000 -0400
@@ -394,6 +394,8 @@ static struct sym_fns ecoff_sym_fns =
mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */
mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/remote.c
===================================================================
--- gdb/remote.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/remote.c 2007-05-09 13:27:04.000000000 -0400
@@ -2008,9 +2008,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);
@@ -2039,47 +2043,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)
+ if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ {
+ ptr += 5;
+ while (*ptr && *ptr != ';')
+ bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+
+ 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;
+
+ /* 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"));
- /* 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. */
+ 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);
}
Index: gdb/somread.c
===================================================================
--- gdb/somread.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/somread.c 2007-05-09 11:30:13.000000000 -0400
@@ -697,6 +697,8 @@ static struct sym_fns som_sym_fns =
som_symfile_read, /* sym_read: read a symbol file into symtab */
som_symfile_finish, /* sym_finish: finished with file, cleanup */
som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/symfile.c
===================================================================
--- gdb/symfile.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/symfile.c 2007-05-09 11:30:13.000000000 -0400
@@ -107,7 +107,7 @@ bfd *symfile_bfd_open (char *);
int get_section_index (struct objfile *, char *);
-static void find_sym_fns (struct objfile *);
+static struct sym_fns *find_sym_fns (bfd *);
static void decrement_reading_symtab (void *);
@@ -147,6 +147,8 @@ static char *find_separate_debug_file (s
static void init_filename_language_table (void);
+static void symfile_find_segment_sections (struct objfile *objfile);
+
void _initialize_symfile (void);
/* List of all available sym_fns. On gdb startup, each object file reader
@@ -431,12 +433,19 @@ init_objfile_sect_indices (struct objfil
/* This is where things get really weird... We MUST have valid
indices for the various sect_index_* members or gdb will abort.
So if for example, there is no ".text" section, we have to
- accomodate that. Except when explicitly adding symbol files at
- some address, section_offsets contains nothing but zeros, so it
- doesn't matter which slot in section_offsets the individual
- sect_index_* members index into. So if they are all zero, it is
- safe to just point all the currently uninitialized indices to the
- first slot. */
+ accomodate that. First, check for a file with the standard
+ one or two segments. */
+
+ symfile_find_segment_sections (objfile);
+
+ /* Except when explicitly adding symbol files at some address,
+ section_offsets contains nothing but zeros, so it doesn't matter
+ which slot in section_offsets the individual sect_index_* members
+ index into. So if they are all zero, it is safe to just point
+ all the currently uninitialized indices to the first slot. But
+ beware: if this is the main executable, it may be relocated
+ later, e.g. by the remote qOffsets packet, and then this will
+ be wrong! That's why we try segments first. */
for (i = 0; i < objfile->num_sections; i++)
{
@@ -640,6 +649,70 @@ default_symfile_offsets (struct objfile
}
+/* Divide the file into segments, which are individual relocatable units.
+ This is the default version of the sym_fns.sym_segments function for
+ symbol readers that do not have an explicit representation of segments.
+ It assumes that object files do not have segments, and fully linked
+ files have a single segment. */
+
+struct symfile_segment_data *
+default_symfile_segments (bfd *abfd)
+{
+ int num_sections, i;
+ asection *sect;
+ struct symfile_segment_data *data;
+ CORE_ADDR low, high;
+
+ /* Relocatable files contain enough information to position each
+ loadable section independently; they should not be relocated
+ in segments. */
+ if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) == 0)
+ return NULL;
+
+ /* Make sure there is at least one loadable section in the file. */
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ {
+ if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ continue;
+
+ break;
+ }
+ if (sect == NULL)
+ return NULL;
+
+ low = bfd_get_section_vma (abfd, sect);
+ high = low + bfd_get_section_size (sect);
+
+ data = XZALLOC (struct symfile_segment_data);
+ data->num_segments = 1;
+ data->segment_bases = XCALLOC (1, CORE_ADDR);
+ data->segment_sizes = XCALLOC (1, CORE_ADDR);
+
+ num_sections = bfd_count_sections (abfd);
+ data->segment_info = XCALLOC (num_sections, int);
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ CORE_ADDR vma;
+
+ if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ continue;
+
+ vma = bfd_get_section_vma (abfd, sect);
+ if (vma < low)
+ low = vma;
+ if (vma + bfd_get_section_size (sect) > high)
+ high = vma + bfd_get_section_size (sect);
+
+ data->segment_info[i] = 1;
+ }
+
+ data->segment_bases[0] = low;
+ data->segment_sizes[0] = high - low;
+
+ return data;
+}
+
/* Process a symbol file, as either the main file or as a dynamically
loaded file.
@@ -686,7 +759,7 @@ syms_from_objfile (struct objfile *objfi
gdb_assert (! (addrs && offsets));
init_entry_point_info (objfile);
- find_sym_fns (objfile);
+ objfile->sf = find_sym_fns (objfile->obfd);
if (objfile->sf == NULL)
return; /* No symbols. */
@@ -1507,29 +1580,23 @@ add_symtab_fns (struct sym_fns *sf)
struct sym_fns in the objfile structure, that contains cached
information about the symbol file. */
-static void
-find_sym_fns (struct objfile *objfile)
+static struct sym_fns *
+find_sym_fns (bfd *abfd)
{
struct sym_fns *sf;
- enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd);
- char *our_target = bfd_get_target (objfile->obfd);
+ enum bfd_flavour our_flavour = bfd_get_flavour (abfd);
if (our_flavour == bfd_target_srec_flavour
|| our_flavour == bfd_target_ihex_flavour
|| our_flavour == bfd_target_tekhex_flavour)
- return; /* No symbols. */
+ return NULL; /* No symbols. */
for (sf = symtab_fns; sf != NULL; sf = sf->next)
- {
- if (our_flavour == sf->sym_flavour)
- {
- objfile->sf = sf;
- return;
- }
- }
+ if (our_flavour == sf->sym_flavour)
+ return sf;
error (_("I'm sorry, Dave, I can't do that. Symbol format `%s' unknown."),
- bfd_get_target (objfile->obfd));
+ bfd_get_target (abfd));
}
\f
@@ -3777,6 +3844,111 @@ symfile_relocate_debug_section (bfd *abf
return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
}
+struct symfile_segment_data *
+get_symfile_segment_data (bfd *abfd)
+{
+ struct sym_fns *sf = find_sym_fns (abfd);
+
+ if (sf == NULL)
+ return NULL;
+
+ return sf->sym_segments (abfd);
+}
+
+void
+free_symfile_segment_data (struct symfile_segment_data *data)
+{
+ xfree (data->segment_bases);
+ xfree (data->segment_sizes);
+ xfree (data->segment_info);
+ xfree (data);
+}
+
+int
+symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
+ struct section_offsets *offsets,
+ int num_segment_bases,
+ const CORE_ADDR *segment_bases)
+{
+ int i;
+ asection *sect;
+
+ /* If we do not have segment mappings for the object file, we
+ can not relocate it by segments. */
+ gdb_assert (data != NULL);
+ gdb_assert (data->num_segments > 0);
+
+ /* If more offsets are provided than we have segments, make sure the
+ excess offsets are all the same as the last segment's offset.
+ This allows "Text=X;Data=X" for files which have only a single
+ segment. */
+ if (num_segment_bases > data->num_segments)
+ for (i = data->num_segments; i < num_segment_bases; i++)
+ if (segment_bases[i] != segment_bases[data->num_segments - 1])
+ return 0;
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ CORE_ADDR vma;
+ int which = data->segment_info[i];
+
+ if (which > num_segment_bases)
+ offsets->offsets[i] = segment_bases[num_segment_bases - 1];
+ else if (which > 0)
+ offsets->offsets[i] = segment_bases[which - 1];
+ else
+ continue;
+
+ offsets->offsets[i] -= data->segment_bases[which - 1];
+ }
+
+ return 1;
+}
+
+static void
+symfile_find_segment_sections (struct objfile *objfile)
+{
+ bfd *abfd = objfile->obfd;
+ int i;
+ asection *sect;
+ struct symfile_segment_data *data;
+
+ data = get_symfile_segment_data (objfile->obfd);
+ if (data == NULL)
+ return;
+
+ if (data->num_segments != 1 && data->num_segments != 2)
+ {
+ free_symfile_segment_data (data);
+ return;
+ }
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ CORE_ADDR vma;
+ int which = data->segment_info[i];
+
+ if (which == 1)
+ {
+ if (objfile->sect_index_text == -1)
+ objfile->sect_index_text = sect->index;
+
+ if (objfile->sect_index_rodata == -1)
+ objfile->sect_index_rodata = sect->index;
+ }
+ else if (which == 2)
+ {
+ if (objfile->sect_index_data == -1)
+ objfile->sect_index_data = sect->index;
+
+ if (objfile->sect_index_bss == -1)
+ objfile->sect_index_bss = sect->index;
+ }
+ }
+
+ free_symfile_segment_data (data);
+}
+
void
_initialize_symfile (void)
{
Index: gdb/symfile.h
===================================================================
--- gdb/symfile.h.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/symfile.h 2007-05-09 11:30:13.000000000 -0400
@@ -84,6 +84,28 @@ struct section_addr_info
} other[1];
};
+struct symfile_segment_data
+{
+ /* How many segments are present in this file. If there are
+ two, the text segment is the first one and the data segment
+ is the second one. */
+ int num_segments;
+
+ /* If NUM_SEGMENTS is greater than zero, the original base address
+ of each segment. */
+ CORE_ADDR *segment_bases;
+
+ /* If NUM_SEGMENTS is greater than zero, the memory size of each
+ segment. */
+ CORE_ADDR *segment_sizes;
+
+ /* If NUM_SEGMENTS is greater than zero, this is an array of entries
+ recording which segment contains each BFD section. It is
+ ordered by section index. A zero means that the section is not
+ in any segment. */
+ int *segment_info;
+};
+
/* Structure to keep track of symbol reading functions for various
object file types. */
@@ -130,6 +152,12 @@ struct sym_fns
void (*sym_offsets) (struct objfile *, struct section_addr_info *);
+ /* This function produces a format-independent description of
+ the segments of ABFD. Each segment is a unit of the file
+ which may be relocated independently. */
+
+ struct symfile_segment_data *(*sym_segments) (bfd *abfd);
+
/* Finds the next struct sym_fns. They are allocated and
initialized in whatever module implements the functions pointed
to; an initializer calls add_symtab_fns to add them to the global
@@ -145,6 +173,10 @@ struct sym_fns
extern void default_symfile_offsets (struct objfile *objfile,
struct section_addr_info *);
+/* The default version of sym_fns.sym_segments for readers that don't
+ do anything special. */
+
+extern struct symfile_segment_data *default_symfile_segments (bfd *abfd);
extern void extend_psymbol_list (struct psymbol_allocation_list *,
struct objfile *);
@@ -309,6 +341,13 @@ extern void symbol_file_clear (int from_
extern bfd_byte *symfile_relocate_debug_section (bfd *abfd, asection *sectp,
bfd_byte * buf);
+extern int symfile_map_offsets_to_segments (bfd *,
+ struct symfile_segment_data *,
+ struct section_offsets *,
+ int, const CORE_ADDR *);
+struct symfile_segment_data *get_symfile_segment_data (bfd *abfd);
+void free_symfile_segment_data (struct symfile_segment_data *data);
+
/* From dwarf2read.c */
extern int dwarf2_has_info (struct objfile *);
Index: gdb/xcoffread.c
===================================================================
--- gdb/xcoffread.c.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/xcoffread.c 2007-05-09 11:30:13.000000000 -0400
@@ -3015,6 +3015,8 @@ static struct sym_fns xcoff_sym_fns =
xcoff_initial_scan, /* sym_read: read a symbol file into symtab */
xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */
xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/Makefile.in
===================================================================
--- gdb/Makefile.in.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/Makefile.in 2007-05-09 13:27:00.000000000 -0400
@@ -586,6 +586,7 @@ coff_ecoff_h = $(INCLUDE_DIR)/coff/ecoff
coff_internal_h = $(INCLUDE_DIR)/coff/internal.h
dis_asm_h = $(INCLUDE_DIR)/dis-asm.h $(bfd_h)
elf_common_h = $(INCLUDE_DIR)/elf/common.h
+elf_internal_h = $(INCLUDE_DIR)/elf/internal.h
elf_reloc_macros_h = $(INCLUDE_DIR)/elf/reloc-macros.h
elf_sh_h = $(INCLUDE_DIR)/elf/sh.h
elf_arm_h = $(INCLUDE_DIR)/elf/arm.h $(elf_reloc_macros_h)
@@ -1958,7 +1959,8 @@ dwarf2read.o: dwarf2read.c $(defs_h) $(b
$(gdb_string_h) $(gdb_assert_h)
elfread.o: elfread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(elf_bfd_h) \
$(elf_mips_h) $(symtab_h) $(symfile_h) $(objfiles_h) $(buildsym_h) \
- $(stabsread_h) $(gdb_stabs_h) $(complaints_h) $(demangle_h)
+ $(stabsread_h) $(gdb_stabs_h) $(complaints_h) $(demangle_h) \
+ $(elf_common_h) $(elf_internal_h)
environ.o: environ.c $(defs_h) $(environ_h) $(gdb_string_h)
eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
$(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \
Index: gdb/NEWS
===================================================================
--- gdb/NEWS.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/NEWS 2007-05-09 11:30:13.000000000 -0400
@@ -31,6 +31,10 @@ has been rewritten to use the standard G
* GDB can now step into C++ functions which are called through thunks.
+* The GDB remote protocol "qOffsets" packet can now honor ELF segment
+layout. It also supports a TextSeg= and DataSeg= response when only
+segment base addresses (rather than offsets) are available.
+
* New commands
set mem inaccessible-by-default
Index: gdb/doc/gdb.texinfo
===================================================================
--- gdb/doc/gdb.texinfo.orig 2007-05-09 11:30:07.000000000 -0400
+++ gdb/doc/gdb.texinfo 2007-05-09 11:30:13.000000000 -0400
@@ -23428,14 +23428,31 @@ digits). See @code{remote.c:parse_threa
@item qOffsets
@cindex section offsets, remote request
@cindex @samp{qOffsets} packet
-Get section offsets that the target used when re-locating the downloaded
-image. @emph{Note: while a @code{Bss} offset is included in the
-response, @value{GDBN} ignores this and instead applies the @code{Data}
-offset to the @code{Bss} section.}
+Get section offsets that the target used when relocating the downloaded
+image.
Reply:
@table @samp
-@item Text=@var{xxx};Data=@var{yyy};Bss=@var{zzz}
+@item Text=@var{xxx};Data=@var{yyy}@r{[};Bss=@var{zzz}@r{]}
+Relocate the @code{Text} section by @var{xxx} from its original address.
+Relocate the @code{Data} section by @var{yyy} from its original address.
+If the object file format provides segment information (e.g.@: @sc{elf}
+@samp{PT_LOAD} program headers), @value{GDBN} will relocate entire
+segments by the supplied offsets.
+
+@emph{Note: while a @code{Bss} offset may be included in the response,
+@value{GDBN} ignores this and instead applies the @code{Data} offset
+to the @code{Bss} section.}
+
+@item TextSeg=@var{xxx}@r{[};DataSeg=@var{yyy}@r{]}
+Relocate the first segment of the object file, which conventionally
+contains program code, to a starting address of @var{xxx}. If
+@samp{DataSeg} is specified, relocate the second segment, which
+conventionally contains modifiable data, to a starting address of
+@var{yyy}. @value{GDBN} will report an error if the object file
+does not contain segment information, or does not contain at least
+as many segments as mentioned in the reply. Extra segments are
+kept at fixed offsets relative to the last relocated segment.
@end table
@item qP @var{mode} @var{threadid}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [rfc / remote protocol] ELF segment based qOffsets
2007-05-09 19:12 [rfc / remote protocol] ELF segment based qOffsets Daniel Jacobowitz
@ 2007-05-09 19:47 ` Eli Zaretskii
2007-05-19 17:39 ` Pedro Alves
2007-06-18 15:48 ` Daniel Jacobowitz
2 siblings, 0 replies; 4+ messages in thread
From: Eli Zaretskii @ 2007-05-09 19:47 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches, gdb
> Date: Wed, 9 May 2007 15:12:15 -0400
> From: Daniel Jacobowitz <drow@false.org>
> Cc: gdb@sourceware.org
>
> Here is the documentation of the new support, and the patch is at the
> end of the message. What do you all think? Eli, is the
> documentation OK?
Yes, thanks.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [rfc / remote protocol] ELF segment based qOffsets
2007-05-09 19:12 [rfc / remote protocol] ELF segment based qOffsets Daniel Jacobowitz
2007-05-09 19:47 ` Eli Zaretskii
@ 2007-05-19 17:39 ` Pedro Alves
2007-06-18 15:48 ` Daniel Jacobowitz
2 siblings, 0 replies; 4+ messages in thread
From: Pedro Alves @ 2007-05-19 17:39 UTC (permalink / raw)
To: gdb-patches
(Should have sent to gdb-patches only in the first place,
since this is discussing the patch itself. Sorry.)
Hi Daniel,
Daniel Jacobowitz wrote:
> Index: gdb/elfread.c
> ===================================================================
> --- gdb/elfread.c.orig 2007-05-09 11:30:07.000000000 -0400
> +++ gdb/elfread.c 2007-05-09 11:30:13.000000000 -0400
> @@ -26,6 +26,8 @@
> +/* Locate the segments in ABFD. */
> +
> +static struct symfile_segment_data *
> +elf_symfile_segments (bfd *abfd)
> +{
> + Elf_Internal_Phdr *phdrs, **segments;
> + long phdrs_size;
> + int num_phdrs, num_segments, num_sections, i;
> + asection *sect;
> + struct symfile_segment_data *data;
> +
> + phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
> + if (phdrs_size == -1)
> + return NULL;
> +
> + phdrs = alloca (phdrs_size);
> + num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
> + if (num_phdrs == -1)
> + return NULL;
This introduces a dependency on bfd/elf.o (bfd_get_elf_phdr_upper_bound,
bfd_get_elf_phdrs) for every non elf target. See below for build log for
arm-wince-mingw32ce. I don't see where in the bfd configury, but Cygwin
already includes elf.o, I guess for core dump file support only, so we
don't see the problem there.
One way to fix it would be to patch bfd/configure.in to always
include $elf in the target backend files ($tb). Or
perhaps elf_symfile_segments should be moved elsewhere?
Cheers,
Pedro Alves
--
>(cd ../gdb; make)
rm -f gdb.exe
gcc -g3 -O0 \
-o gdb.exe gdb.o libgdb.a \
../readline/libreadline.a ../opcodes/libopcodes.a ../bfd/libb
fd.a -lintl ../libiberty/libiberty.a -lncurses -lm -liconv -lexpat ../libibe
rty/libiberty.a -luser32
libgdb.a(elfread.o): In function `elf_symfile_segments':
/cygdrive/d/cegccsf/cegcc/cegcc/src/build-gdb_server/gdb/../../gdb-server_submit
/src/gdb/elfread.c:67: undefined reference to `_bfd_get_elf_phdr_upper_bound'
/cygdrive/d/cegccsf/cegcc/cegcc/src/build-gdb_server/gdb/../../gdb-server_submit
/src/gdb/elfread.c:72: undefined reference to `_bfd_get_elf_phdrs'
Info: resolving _LINES by linking to __imp__LINES (auto-import)
Info: resolving _COLS by linking to __imp__COLS (auto-import)
Info: resolving _stdscr by linking to __imp__stdscr (auto-import)
Info: resolving _curscr by linking to __imp__curscr (auto-import)
collect2: ld returned 1 exit status
make: *** [gdb.exe] Error 1
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [rfc / remote protocol] ELF segment based qOffsets
2007-05-09 19:12 [rfc / remote protocol] ELF segment based qOffsets Daniel Jacobowitz
2007-05-09 19:47 ` Eli Zaretskii
2007-05-19 17:39 ` Pedro Alves
@ 2007-06-18 15:48 ` Daniel Jacobowitz
2 siblings, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2007-06-18 15:48 UTC (permalink / raw)
To: gdb-patches, gdb
On Wed, May 09, 2007 at 03:12:15PM -0400, Daniel Jacobowitz wrote:
> 2007-05-09 Daniel Jacobowitz <dan@codesourcery.com>
>
> * coffread.c (coff_sym_fns): Add default_symfile_segments.
> * dbxread.c (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 (elf_internal_h): New.
> (elfread.o): Update.
> * NEWS: Mention qOffsets changes.
>
> * gdb.texinfo (General Query Packets): Document qOffsets changes.
I have committed an updated version of this, below. The only change
is that it no longer breaks the build on non-ELF targets. Since the
BFD developers did not want to unconditionally build bfd/elf.lo, I
conditionally disabled gdb/elfread.o depending on whether BFD has ELF
support.
--
Daniel Jacobowitz
CodeSourcery
2007-06-18 Daniel Jacobowitz <dan@codesourcery.com>
* 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.
---
Makefile.def | 2
Makefile.in | 2
gdb/Makefile.in | 6 -
gdb/NEWS | 4
gdb/coffread.c | 2
gdb/config.in | 3
gdb/configure | 76 ++++++++++++++++++
gdb/configure.ac | 24 +++++
gdb/dbxread.c | 4
gdb/doc/gdb.texinfo | 27 +++++-
gdb/elfread.c | 74 +++++++++++++++++
gdb/mipsread.c | 2
gdb/remote.c | 116 ++++++++++++++++++++++------
gdb/somread.c | 2
gdb/symfile.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++------
gdb/symfile.h | 39 +++++++++
gdb/xcoffread.c | 2
17 files changed, 544 insertions(+), 55 deletions(-)
Index: gdb/coffread.c
===================================================================
--- gdb/coffread.c.orig 2007-06-12 14:15:25.000000000 -0400
+++ gdb/coffread.c 2007-06-12 14:28:14.000000000 -0400
@@ -2139,6 +2139,8 @@ static struct sym_fns coff_sym_fns =
coff_symfile_read, /* sym_read: read a symbol file into symtab */
coff_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: xlate external to internal form */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/dbxread.c
===================================================================
--- gdb/dbxread.c.orig 2007-06-12 14:15:28.000000000 -0400
+++ gdb/dbxread.c 2007-06-12 15:05:24.000000000 -0400
@@ -2148,11 +2148,13 @@ start_psymtab (struct objfile *objfile,
STRING_OFFSET (result) = string_table_offset;
FILE_STRING_OFFSET (result) = file_string_table_offset;
+#ifdef HAVE_ELF
/* If we're handling an ELF file, drag some section-relocation info
for this source file out of the ELF symbol table, to compensate for
Sun brain death. This replaces the section_offsets in this psymtab,
if successful. */
elfstab_offset_sections (objfile, result);
+#endif
/* Deduce the source language from the filename for this psymtab. */
psymtab_language = deduce_language_from_filename (filename);
@@ -3505,6 +3507,8 @@ static struct sym_fns aout_sym_fns =
dbx_symfile_read, /* sym_read: read a symbol file into symtab */
dbx_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: parse user's offsets to internal form */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/elfread.c
===================================================================
--- gdb/elfread.c.orig 2007-06-12 14:15:29.000000000 -0400
+++ gdb/elfread.c 2007-06-12 14:28:14.000000000 -0400
@@ -26,6 +26,8 @@
#include "bfd.h"
#include "gdb_string.h"
#include "elf-bfd.h"
+#include "elf/common.h"
+#include "elf/internal.h"
#include "elf/mips.h"
#include "symtab.h"
#include "symfile.h"
@@ -51,6 +53,76 @@ struct elfinfo
static void free_elfinfo (void *);
+/* Locate the segments in ABFD. */
+
+static struct symfile_segment_data *
+elf_symfile_segments (bfd *abfd)
+{
+ Elf_Internal_Phdr *phdrs, **segments;
+ long phdrs_size;
+ int num_phdrs, num_segments, num_sections, i;
+ asection *sect;
+ struct symfile_segment_data *data;
+
+ phdrs_size = bfd_get_elf_phdr_upper_bound (abfd);
+ if (phdrs_size == -1)
+ return NULL;
+
+ phdrs = alloca (phdrs_size);
+ num_phdrs = bfd_get_elf_phdrs (abfd, phdrs);
+ if (num_phdrs == -1)
+ return NULL;
+
+ num_segments = 0;
+ segments = alloca (sizeof (Elf_Internal_Phdr *) * num_phdrs);
+ for (i = 0; i < num_phdrs; i++)
+ if (phdrs[i].p_type == PT_LOAD)
+ segments[num_segments++] = &phdrs[i];
+
+ if (num_segments == 0)
+ return NULL;
+
+ data = XZALLOC (struct symfile_segment_data);
+ data->num_segments = num_segments;
+ data->segment_bases = XCALLOC (num_segments, CORE_ADDR);
+ data->segment_sizes = XCALLOC (num_segments, CORE_ADDR);
+
+ for (i = 0; i < num_segments; i++)
+ {
+ data->segment_bases[i] = segments[i]->p_vaddr;
+ data->segment_sizes[i] = segments[i]->p_memsz;
+ }
+
+ num_sections = bfd_count_sections (abfd);
+ data->segment_info = XCALLOC (num_sections, int);
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ int j;
+ CORE_ADDR vma;
+
+ if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ continue;
+
+ vma = bfd_get_section_vma (abfd, sect);
+
+ for (j = 0; j < num_segments; j++)
+ if (segments[j]->p_memsz > 0
+ && vma >= segments[j]->p_vaddr
+ && vma < segments[j]->p_vaddr + segments[j]->p_memsz)
+ {
+ data->segment_info[i] = j + 1;
+ break;
+ }
+
+ if (bfd_get_section_size (sect) > 0 && j == num_segments)
+ warning (_("Loadable segment \"%s\" outside of ELF segments"),
+ bfd_section_name (abfd, sect));
+ }
+
+ return data;
+}
+
/* We are called once per section from elf_symfile_read. We
need to examine each section we are passed, check to see
if it is something we are interested in processing, and
@@ -741,6 +813,8 @@ static struct sym_fns elf_sym_fns =
elf_symfile_read, /* sym_read: read a symbol file into symtab */
elf_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ elf_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/mipsread.c
===================================================================
--- gdb/mipsread.c.orig 2007-06-12 14:08:52.000000000 -0400
+++ gdb/mipsread.c 2007-06-12 14:28:14.000000000 -0400
@@ -394,6 +394,8 @@ static struct sym_fns ecoff_sym_fns =
mipscoff_symfile_read, /* sym_read: read a symbol file into symtab */
mipscoff_symfile_finish, /* sym_finish: finished with file, cleanup */
default_symfile_offsets, /* sym_offsets: dummy FIXME til implem sym reloc */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/remote.c
===================================================================
--- gdb/remote.c.orig 2007-06-12 14:15:39.000000000 -0400
+++ gdb/remote.c 2007-06-12 14:28:14.000000000 -0400
@@ -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)
+ if (!lose && strncmp (ptr, ";Bss=", 5) == 0)
+ {
+ ptr += 5;
+ while (*ptr && *ptr != ';')
+ bss_addr = (bss_addr << 4) + fromhex (*ptr++);
+
+ 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;
+
+ /* 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"));
- /* 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. */
+ 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);
}
Index: gdb/somread.c
===================================================================
--- gdb/somread.c.orig 2007-06-12 14:15:41.000000000 -0400
+++ gdb/somread.c 2007-06-12 14:28:14.000000000 -0400
@@ -438,6 +438,8 @@ static struct sym_fns som_sym_fns =
som_symfile_read, /* sym_read: read a symbol file into symtab */
som_symfile_finish, /* sym_finish: finished with file, cleanup */
som_symfile_offsets, /* sym_offsets: Translate ext. to int. relocation */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/symfile.c
===================================================================
--- gdb/symfile.c.orig 2007-06-12 14:15:42.000000000 -0400
+++ gdb/symfile.c 2007-06-12 14:28:14.000000000 -0400
@@ -106,7 +106,7 @@ bfd *symfile_bfd_open (char *);
int get_section_index (struct objfile *, char *);
-static void find_sym_fns (struct objfile *);
+static struct sym_fns *find_sym_fns (bfd *);
static void decrement_reading_symtab (void *);
@@ -146,6 +146,8 @@ static char *find_separate_debug_file (s
static void init_filename_language_table (void);
+static void symfile_find_segment_sections (struct objfile *objfile);
+
void _initialize_symfile (void);
/* List of all available sym_fns. On gdb startup, each object file reader
@@ -430,12 +432,19 @@ init_objfile_sect_indices (struct objfil
/* This is where things get really weird... We MUST have valid
indices for the various sect_index_* members or gdb will abort.
So if for example, there is no ".text" section, we have to
- accomodate that. Except when explicitly adding symbol files at
- some address, section_offsets contains nothing but zeros, so it
- doesn't matter which slot in section_offsets the individual
- sect_index_* members index into. So if they are all zero, it is
- safe to just point all the currently uninitialized indices to the
- first slot. */
+ accomodate that. First, check for a file with the standard
+ one or two segments. */
+
+ symfile_find_segment_sections (objfile);
+
+ /* Except when explicitly adding symbol files at some address,
+ section_offsets contains nothing but zeros, so it doesn't matter
+ which slot in section_offsets the individual sect_index_* members
+ index into. So if they are all zero, it is safe to just point
+ all the currently uninitialized indices to the first slot. But
+ beware: if this is the main executable, it may be relocated
+ later, e.g. by the remote qOffsets packet, and then this will
+ be wrong! That's why we try segments first. */
for (i = 0; i < objfile->num_sections; i++)
{
@@ -639,6 +648,70 @@ default_symfile_offsets (struct objfile
}
+/* Divide the file into segments, which are individual relocatable units.
+ This is the default version of the sym_fns.sym_segments function for
+ symbol readers that do not have an explicit representation of segments.
+ It assumes that object files do not have segments, and fully linked
+ files have a single segment. */
+
+struct symfile_segment_data *
+default_symfile_segments (bfd *abfd)
+{
+ int num_sections, i;
+ asection *sect;
+ struct symfile_segment_data *data;
+ CORE_ADDR low, high;
+
+ /* Relocatable files contain enough information to position each
+ loadable section independently; they should not be relocated
+ in segments. */
+ if ((bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) == 0)
+ return NULL;
+
+ /* Make sure there is at least one loadable section in the file. */
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ {
+ if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ continue;
+
+ break;
+ }
+ if (sect == NULL)
+ return NULL;
+
+ low = bfd_get_section_vma (abfd, sect);
+ high = low + bfd_get_section_size (sect);
+
+ data = XZALLOC (struct symfile_segment_data);
+ data->num_segments = 1;
+ data->segment_bases = XCALLOC (1, CORE_ADDR);
+ data->segment_sizes = XCALLOC (1, CORE_ADDR);
+
+ num_sections = bfd_count_sections (abfd);
+ data->segment_info = XCALLOC (num_sections, int);
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ CORE_ADDR vma;
+
+ if ((bfd_get_section_flags (abfd, sect) & SEC_ALLOC) == 0)
+ continue;
+
+ vma = bfd_get_section_vma (abfd, sect);
+ if (vma < low)
+ low = vma;
+ if (vma + bfd_get_section_size (sect) > high)
+ high = vma + bfd_get_section_size (sect);
+
+ data->segment_info[i] = 1;
+ }
+
+ data->segment_bases[0] = low;
+ data->segment_sizes[0] = high - low;
+
+ return data;
+}
+
/* Process a symbol file, as either the main file or as a dynamically
loaded file.
@@ -685,7 +758,7 @@ syms_from_objfile (struct objfile *objfi
gdb_assert (! (addrs && offsets));
init_entry_point_info (objfile);
- find_sym_fns (objfile);
+ objfile->sf = find_sym_fns (objfile->obfd);
if (objfile->sf == NULL)
return; /* No symbols. */
@@ -1505,29 +1578,23 @@ add_symtab_fns (struct sym_fns *sf)
struct sym_fns in the objfile structure, that contains cached
information about the symbol file. */
-static void
-find_sym_fns (struct objfile *objfile)
+static struct sym_fns *
+find_sym_fns (bfd *abfd)
{
struct sym_fns *sf;
- enum bfd_flavour our_flavour = bfd_get_flavour (objfile->obfd);
- char *our_target = bfd_get_target (objfile->obfd);
+ enum bfd_flavour our_flavour = bfd_get_flavour (abfd);
if (our_flavour == bfd_target_srec_flavour
|| our_flavour == bfd_target_ihex_flavour
|| our_flavour == bfd_target_tekhex_flavour)
- return; /* No symbols. */
+ return NULL; /* No symbols. */
for (sf = symtab_fns; sf != NULL; sf = sf->next)
- {
- if (our_flavour == sf->sym_flavour)
- {
- objfile->sf = sf;
- return;
- }
- }
+ if (our_flavour == sf->sym_flavour)
+ return sf;
error (_("I'm sorry, Dave, I can't do that. Symbol format `%s' unknown."),
- bfd_get_target (objfile->obfd));
+ bfd_get_target (abfd));
}
\f
@@ -3771,6 +3838,111 @@ symfile_relocate_debug_section (bfd *abf
return bfd_simple_get_relocated_section_contents (abfd, sectp, buf, NULL);
}
+struct symfile_segment_data *
+get_symfile_segment_data (bfd *abfd)
+{
+ struct sym_fns *sf = find_sym_fns (abfd);
+
+ if (sf == NULL)
+ return NULL;
+
+ return sf->sym_segments (abfd);
+}
+
+void
+free_symfile_segment_data (struct symfile_segment_data *data)
+{
+ xfree (data->segment_bases);
+ xfree (data->segment_sizes);
+ xfree (data->segment_info);
+ xfree (data);
+}
+
+int
+symfile_map_offsets_to_segments (bfd *abfd, struct symfile_segment_data *data,
+ struct section_offsets *offsets,
+ int num_segment_bases,
+ const CORE_ADDR *segment_bases)
+{
+ int i;
+ asection *sect;
+
+ /* If we do not have segment mappings for the object file, we
+ can not relocate it by segments. */
+ gdb_assert (data != NULL);
+ gdb_assert (data->num_segments > 0);
+
+ /* If more offsets are provided than we have segments, make sure the
+ excess offsets are all the same as the last segment's offset.
+ This allows "Text=X;Data=X" for files which have only a single
+ segment. */
+ if (num_segment_bases > data->num_segments)
+ for (i = data->num_segments; i < num_segment_bases; i++)
+ if (segment_bases[i] != segment_bases[data->num_segments - 1])
+ return 0;
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ CORE_ADDR vma;
+ int which = data->segment_info[i];
+
+ if (which > num_segment_bases)
+ offsets->offsets[i] = segment_bases[num_segment_bases - 1];
+ else if (which > 0)
+ offsets->offsets[i] = segment_bases[which - 1];
+ else
+ continue;
+
+ offsets->offsets[i] -= data->segment_bases[which - 1];
+ }
+
+ return 1;
+}
+
+static void
+symfile_find_segment_sections (struct objfile *objfile)
+{
+ bfd *abfd = objfile->obfd;
+ int i;
+ asection *sect;
+ struct symfile_segment_data *data;
+
+ data = get_symfile_segment_data (objfile->obfd);
+ if (data == NULL)
+ return;
+
+ if (data->num_segments != 1 && data->num_segments != 2)
+ {
+ free_symfile_segment_data (data);
+ return;
+ }
+
+ for (i = 0, sect = abfd->sections; sect != NULL; i++, sect = sect->next)
+ {
+ CORE_ADDR vma;
+ int which = data->segment_info[i];
+
+ if (which == 1)
+ {
+ if (objfile->sect_index_text == -1)
+ objfile->sect_index_text = sect->index;
+
+ if (objfile->sect_index_rodata == -1)
+ objfile->sect_index_rodata = sect->index;
+ }
+ else if (which == 2)
+ {
+ if (objfile->sect_index_data == -1)
+ objfile->sect_index_data = sect->index;
+
+ if (objfile->sect_index_bss == -1)
+ objfile->sect_index_bss = sect->index;
+ }
+ }
+
+ free_symfile_segment_data (data);
+}
+
void
_initialize_symfile (void)
{
Index: gdb/symfile.h
===================================================================
--- gdb/symfile.h.orig 2007-06-12 14:15:43.000000000 -0400
+++ gdb/symfile.h 2007-06-12 14:28:14.000000000 -0400
@@ -85,6 +85,28 @@ struct section_addr_info
} other[1];
};
+struct symfile_segment_data
+{
+ /* How many segments are present in this file. If there are
+ two, the text segment is the first one and the data segment
+ is the second one. */
+ int num_segments;
+
+ /* If NUM_SEGMENTS is greater than zero, the original base address
+ of each segment. */
+ CORE_ADDR *segment_bases;
+
+ /* If NUM_SEGMENTS is greater than zero, the memory size of each
+ segment. */
+ CORE_ADDR *segment_sizes;
+
+ /* If NUM_SEGMENTS is greater than zero, this is an array of entries
+ recording which segment contains each BFD section. It is
+ ordered by section index. A zero means that the section is not
+ in any segment. */
+ int *segment_info;
+};
+
/* Structure to keep track of symbol reading functions for various
object file types. */
@@ -131,6 +153,12 @@ struct sym_fns
void (*sym_offsets) (struct objfile *, struct section_addr_info *);
+ /* This function produces a format-independent description of
+ the segments of ABFD. Each segment is a unit of the file
+ which may be relocated independently. */
+
+ struct symfile_segment_data *(*sym_segments) (bfd *abfd);
+
/* Finds the next struct sym_fns. They are allocated and
initialized in whatever module implements the functions pointed
to; an initializer calls add_symtab_fns to add them to the global
@@ -146,6 +174,10 @@ struct sym_fns
extern void default_symfile_offsets (struct objfile *objfile,
struct section_addr_info *);
+/* The default version of sym_fns.sym_segments for readers that don't
+ do anything special. */
+
+extern struct symfile_segment_data *default_symfile_segments (bfd *abfd);
extern void extend_psymbol_list (struct psymbol_allocation_list *,
struct objfile *);
@@ -313,6 +345,13 @@ extern void simple_overlay_update (struc
extern bfd_byte *symfile_relocate_debug_section (bfd *abfd, asection *sectp,
bfd_byte * buf);
+extern int symfile_map_offsets_to_segments (bfd *,
+ struct symfile_segment_data *,
+ struct section_offsets *,
+ int, const CORE_ADDR *);
+struct symfile_segment_data *get_symfile_segment_data (bfd *abfd);
+void free_symfile_segment_data (struct symfile_segment_data *data);
+
/* From dwarf2read.c */
extern int dwarf2_has_info (struct objfile *);
Index: gdb/xcoffread.c
===================================================================
--- gdb/xcoffread.c.orig 2007-06-12 14:15:45.000000000 -0400
+++ gdb/xcoffread.c 2007-06-12 14:28:14.000000000 -0400
@@ -3015,6 +3015,8 @@ static struct sym_fns xcoff_sym_fns =
xcoff_initial_scan, /* sym_read: read a symbol file into symtab */
xcoff_symfile_finish, /* sym_finish: finished with file, cleanup */
xcoff_symfile_offsets, /* sym_offsets: xlate offsets ext->int form */
+ default_symfile_segments, /* sym_segments: Get segment information from
+ a file. */
NULL /* next: pointer to next struct sym_fns */
};
Index: gdb/Makefile.in
===================================================================
--- gdb/Makefile.in.orig 2007-06-12 14:15:22.000000000 -0400
+++ gdb/Makefile.in 2007-06-12 14:51:21.000000000 -0400
@@ -586,6 +586,7 @@ coff_ecoff_h = $(INCLUDE_DIR)/coff/ecoff
coff_internal_h = $(INCLUDE_DIR)/coff/internal.h
dis_asm_h = $(INCLUDE_DIR)/dis-asm.h $(bfd_h)
elf_common_h = $(INCLUDE_DIR)/elf/common.h
+elf_internal_h = $(INCLUDE_DIR)/elf/internal.h
elf_reloc_macros_h = $(INCLUDE_DIR)/elf/reloc-macros.h
elf_sh_h = $(INCLUDE_DIR)/elf/sh.h
elf_arm_h = $(INCLUDE_DIR)/elf/arm.h $(elf_reloc_macros_h)
@@ -946,7 +947,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $
signals.o \
gdb-events.o \
exec.o bcache.o objfiles.o observer.o minsyms.o maint.o demangle.o \
- dbxread.o coffread.o coff-pe-read.o elfread.o \
+ dbxread.o coffread.o coff-pe-read.o \
dwarf2read.o mipsread.o stabsread.o corefile.o \
dwarf2expr.o dwarf2loc.o dwarf2-frame.o \
ada-lang.o c-lang.o f-lang.o objc-lang.o \
@@ -1958,7 +1959,8 @@ dwarf2read.o: dwarf2read.c $(defs_h) $(b
$(gdb_string_h) $(gdb_assert_h)
elfread.o: elfread.c $(defs_h) $(bfd_h) $(gdb_string_h) $(elf_bfd_h) \
$(elf_mips_h) $(symtab_h) $(symfile_h) $(objfiles_h) $(buildsym_h) \
- $(stabsread_h) $(gdb_stabs_h) $(complaints_h) $(demangle_h)
+ $(stabsread_h) $(gdb_stabs_h) $(complaints_h) $(demangle_h) \
+ $(elf_common_h) $(elf_internal_h)
environ.o: environ.c $(defs_h) $(environ_h) $(gdb_string_h)
eval.o: eval.c $(defs_h) $(gdb_string_h) $(symtab_h) $(gdbtypes_h) \
$(value_h) $(expression_h) $(target_h) $(frame_h) $(language_h) \
Index: gdb/NEWS
===================================================================
--- gdb/NEWS.orig 2007-06-12 14:15:22.000000000 -0400
+++ gdb/NEWS 2007-06-12 14:28:14.000000000 -0400
@@ -37,6 +37,10 @@ has been rewritten to use the standard G
* GDB for the Cell/B.E. SPU now supports overlay debugging.
+* The GDB remote protocol "qOffsets" packet can now honor ELF segment
+layout. It also supports a TextSeg= and DataSeg= response when only
+segment base addresses (rather than offsets) are available.
+
* New commands
set remoteflow
Index: gdb/doc/gdb.texinfo
===================================================================
--- gdb/doc/gdb.texinfo.orig 2007-06-12 14:15:51.000000000 -0400
+++ gdb/doc/gdb.texinfo 2007-06-12 14:28:14.000000000 -0400
@@ -23433,14 +23433,31 @@ digits). See @code{remote.c:parse_threa
@item qOffsets
@cindex section offsets, remote request
@cindex @samp{qOffsets} packet
-Get section offsets that the target used when re-locating the downloaded
-image. @emph{Note: while a @code{Bss} offset is included in the
-response, @value{GDBN} ignores this and instead applies the @code{Data}
-offset to the @code{Bss} section.}
+Get section offsets that the target used when relocating the downloaded
+image.
Reply:
@table @samp
-@item Text=@var{xxx};Data=@var{yyy};Bss=@var{zzz}
+@item Text=@var{xxx};Data=@var{yyy}@r{[};Bss=@var{zzz}@r{]}
+Relocate the @code{Text} section by @var{xxx} from its original address.
+Relocate the @code{Data} section by @var{yyy} from its original address.
+If the object file format provides segment information (e.g.@: @sc{elf}
+@samp{PT_LOAD} program headers), @value{GDBN} will relocate entire
+segments by the supplied offsets.
+
+@emph{Note: while a @code{Bss} offset may be included in the response,
+@value{GDBN} ignores this and instead applies the @code{Data} offset
+to the @code{Bss} section.}
+
+@item TextSeg=@var{xxx}@r{[};DataSeg=@var{yyy}@r{]}
+Relocate the first segment of the object file, which conventionally
+contains program code, to a starting address of @var{xxx}. If
+@samp{DataSeg} is specified, relocate the second segment, which
+conventionally contains modifiable data, to a starting address of
+@var{yyy}. @value{GDBN} will report an error if the object file
+does not contain segment information, or does not contain at least
+as many segments as mentioned in the reply. Extra segments are
+kept at fixed offsets relative to the last relocated segment.
@end table
@item qP @var{mode} @var{threadid}
Index: Makefile.def
===================================================================
--- Makefile.def.orig 2007-06-12 14:49:04.000000000 -0400
+++ Makefile.def 2007-06-12 14:49:47.000000000 -0400
@@ -314,10 +314,10 @@ dependencies = { module=configure-mpfr;
// Host modules specific to gdb.
dependencies = { module=configure-gdb; on=configure-intl; };
dependencies = { module=configure-gdb; on=configure-sim; };
+dependencies = { module=configure-gdb; on=all-bfd; };
dependencies = { module=all-gdb; on=all-intl; };
dependencies = { module=all-gdb; on=all-libiberty; };
dependencies = { module=all-gdb; on=all-opcodes; };
-dependencies = { module=all-gdb; on=all-bfd; };
dependencies = { module=all-gdb; on=all-readline; };
dependencies = { module=all-gdb; on=all-build-bison; };
dependencies = { module=all-gdb; on=all-build-byacc; };
Index: Makefile.in
===================================================================
--- Makefile.in.orig 2007-06-12 14:49:53.000000000 -0400
+++ Makefile.in 2007-06-12 14:49:55.000000000 -0400
@@ -49016,10 +49016,10 @@ configure-stageprofile-mpfr: maybe-all-s
configure-stagefeedback-mpfr: maybe-all-stagefeedback-gmp
configure-gdb: maybe-configure-intl
configure-gdb: maybe-configure-sim
+configure-gdb: maybe-all-bfd
all-gdb: maybe-all-intl
all-gdb: maybe-all-libiberty
all-gdb: maybe-all-opcodes
-all-gdb: maybe-all-bfd
all-gdb: maybe-all-readline
all-gdb: maybe-all-build-bison
all-gdb: maybe-all-build-byacc
Index: gdb/config.in
===================================================================
--- gdb/config.in.orig 2007-06-12 15:03:24.000000000 -0400
+++ gdb/config.in 2007-06-12 15:03:32.000000000 -0400
@@ -110,6 +110,9 @@
*/
#undef HAVE_DIRENT_H
+/* Define if ELF support should be included. */
+#undef HAVE_ELF
+
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
Index: gdb/configure
===================================================================
--- gdb/configure.orig 2007-06-12 14:50:51.000000000 -0400
+++ gdb/configure 2007-06-12 15:30:33.000000000 -0400
@@ -21797,6 +21797,82 @@ _ACEOF
esac
+# Add ELF support to GDB, but only if BFD includes ELF support.
+OLD_CFLAGS=$CFLAGS
+OLD_LDFLAGS=$LDFLAGS
+OLD_LIBS=$LIBS
+CFLAGS="$CFLAGS -I${srcdir}/../include -I${objdir}/../bfd -I${srcdir}/../bfd"
+LDFLAGS="$LDFLAGS -L../bfd -L../libiberty"
+LIBS="$LIBS -lbfd -liberty"
+echo "$as_me:$LINENO: checking for ELF support in BFD" >&5
+echo $ECHO_N "checking for ELF support in BFD... $ECHO_C" >&6
+if test "${gdb_cv_var_elf+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include "bfd.h"
+#include "elf-bfd.h"
+
+int
+main ()
+{
+bfd *abfd = NULL; bfd_get_elf_phdr_upper_bound (abfd);
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ gdb_cv_var_elf=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+gdb_cv_var_elf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $gdb_cv_var_elf" >&5
+echo "${ECHO_T}$gdb_cv_var_elf" >&6
+if test $gdb_cv_var_elf = yes; then
+ CONFIG_OBS="$CONFIG_OBS elfread.o"
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ELF 1
+_ACEOF
+
+fi
+CFLAGS=$OLD_CFLAGS
+LDFLAGS=$OLD_LDFLAGS
+LIBS=$OLD_LIBS
+
# Add any host-specific objects to GDB.
CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}"
Index: gdb/configure.ac
===================================================================
--- gdb/configure.ac.orig 2007-06-12 14:42:00.000000000 -0400
+++ gdb/configure.ac 2007-06-12 15:30:25.000000000 -0400
@@ -1255,6 +1255,30 @@ case ${host} in
esac
AC_SUBST(WIN32LIBS)
+# Add ELF support to GDB, but only if BFD includes ELF support.
+OLD_CFLAGS=$CFLAGS
+OLD_LDFLAGS=$LDFLAGS
+OLD_LIBS=$LIBS
+CFLAGS="$CFLAGS -I${srcdir}/../include -I${objdir}/../bfd -I${srcdir}/../bfd"
+LDFLAGS="$LDFLAGS -L../bfd -L../libiberty"
+LIBS="$LIBS -lbfd -liberty"
+AC_CACHE_CHECK([for ELF support in BFD], gdb_cv_var_elf,
+[AC_TRY_LINK(
+[#include <stdlib.h>
+#include "bfd.h"
+#include "elf-bfd.h"
+],
+[bfd *abfd = NULL; bfd_get_elf_phdr_upper_bound (abfd); ],
+gdb_cv_var_elf=yes, gdb_cv_var_elf=no)])
+if test $gdb_cv_var_elf = yes; then
+ CONFIG_OBS="$CONFIG_OBS elfread.o"
+ AC_DEFINE(HAVE_ELF, 1,
+ [Define if ELF support should be included.])
+fi
+CFLAGS=$OLD_CFLAGS
+LDFLAGS=$OLD_LDFLAGS
+LIBS=$OLD_LIBS
+
# Add any host-specific objects to GDB.
CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}"
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2007-06-18 15:48 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-05-09 19:12 [rfc / remote protocol] ELF segment based qOffsets Daniel Jacobowitz
2007-05-09 19:47 ` Eli Zaretskii
2007-05-19 17:39 ` Pedro Alves
2007-06-18 15:48 ` Daniel Jacobowitz
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox