* 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.
This commit is contained in:
Daniel Jacobowitz 2007-06-18 15:46:38 +00:00
parent d856f2ddfa
commit 31d99776c7
20 changed files with 585 additions and 55 deletions

View File

@ -1,3 +1,8 @@
2007-06-18 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.def: Add dependency from configure-gdb to all-bfd.
* Makefile.in: Regenerated.
2007-06-14 Paolo Bonzini <bonzini@gnu.org>
* Makefile.tpl (cleanstrap): Don't delete the toplevel Makefile.

View File

@ -314,10 +314,10 @@ dependencies = { module=configure-mpfr; on=all-gmp; };
// 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; };

View File

@ -49030,10 +49030,10 @@ configure-stageprofile-mpfr: maybe-all-stageprofile-gmp
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

View File

@ -1,3 +1,35 @@
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.
2007-06-16 Ulrich Weigand <uweigand@de.ibm.com>
* gdbtypes.h (builtin_type_m2_char, builtin_type_m2_int,

View File

@ -586,6 +586,7 @@ coff_ecoff_h = $(INCLUDE_DIR)/coff/ecoff.h
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) $(YYOBJ) \
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) $(bfd_h) $(symtab_h) $(gdbtypes_h) \
$(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) \

View File

@ -37,6 +37,10 @@ has been rewritten to use the standard GDB remote protocol.
* 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

View File

@ -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 */
};

View File

@ -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

76
gdb/configure vendored
View File

@ -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}"

View File

@ -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}"

View File

@ -2148,11 +2148,13 @@ start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
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 */
};

View File

@ -1,3 +1,7 @@
2007-06-18 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (General Query Packets): Document qOffsets changes.
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (Target Description Format): Add version attribute

View File

@ -23433,14 +23433,31 @@ digits). See @code{remote.c:parse_threadlist_response()}.
@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}

View File

@ -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 */
};

View File

@ -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 */
};

View File

@ -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;
/* 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;
}
offs->offsets[SECT_OFF_DATA (symfile_objfile)] = data_addr;
offs->offsets[SECT_OFF_BSS (symfile_objfile)] = 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;
}
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);
}

View File

@ -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 */
};

View File

@ -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 (struct objfile *objfile);
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 objfile *objfile)
/* 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 *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 *objfile,
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));
}
@ -3771,6 +3838,111 @@ symfile_relocate_debug_section (bfd *abfd, asection *sectp, bfd_byte *buf)
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)
{

View File

@ -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 (struct obj_section *);
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 *);

View File

@ -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 */
};