mirror of
https://github.com/darlinghq/darling-gdb.git
synced 2024-11-25 13:09:48 +00:00
* syms.c: Include "bfdlink.h".
(struct stab_find_info): Define. (_bfd_stab_section_find_nearest_line): New function. * libbfd-in.h (_bfd_stab_section_find_nearest_line): Declare. * libbfd.h: Rebuild. * elf-bfd.h (struct elf_obj_tdata): Add line_info field. * elf.c (_bfd_elf_find_nearest_line): Try calling _bfd_stab_section_find_nearest_line before searching the ELF symbol table. Find the closest STT_FUNC symbol, not the last one. * libcoff-in.h (coff_data_type): Add line_info field. * libcoff.h: Rebuild. * coffgen.c (coff_find_nearest_line): Try calling _bfd_stab_section_find_nearest_line before searching the COFF symbol table. * Makefile.in: Rebuild dependencies.
This commit is contained in:
parent
a77bf669dc
commit
86aac8eabe
@ -1,3 +1,27 @@
|
||||
Fri Jan 26 18:33:35 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* syms.c: Include "bfdlink.h".
|
||||
(struct stab_find_info): Define.
|
||||
(_bfd_stab_section_find_nearest_line): New function.
|
||||
* libbfd-in.h (_bfd_stab_section_find_nearest_line): Declare.
|
||||
* libbfd.h: Rebuild.
|
||||
* elf-bfd.h (struct elf_obj_tdata): Add line_info field.
|
||||
* elf.c (_bfd_elf_find_nearest_line): Try calling
|
||||
_bfd_stab_section_find_nearest_line before searching the ELF
|
||||
symbol table. Find the closest STT_FUNC symbol, not the last one.
|
||||
* libcoff-in.h (coff_data_type): Add line_info field.
|
||||
* libcoff.h: Rebuild.
|
||||
* coffgen.c (coff_find_nearest_line): Try calling
|
||||
_bfd_stab_section_find_nearest_line before searching the COFF
|
||||
symbol table.
|
||||
* Makefile.in: Rebuild dependencies.
|
||||
|
||||
Fri Jan 26 16:11:19 1996 Michael Meissner <meissner@tiktok.cygnus.com>
|
||||
|
||||
* elf32-ppc.c (R_PPC_EMB_SDA21 relocations): Make relocation size
|
||||
4 bytes, so we get the correct value when updating the register
|
||||
field in little endian mode.
|
||||
|
||||
Thu Jan 25 12:14:16 1996 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* libcoff-in.h (struct xcoff_tdata): Remove toc_section and
|
||||
|
@ -1,5 +1,6 @@
|
||||
# Makefile template for Configure for the BFD library.
|
||||
# Copyright (C) 1990, 91, 92, 93, 94, 1995 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1990, 91, 92, 93, 94, 95, 1996
|
||||
# Free Software Foundation, Inc.
|
||||
# Written by Cygnus Support.
|
||||
#
|
||||
# This file is part of BFD, the Binary File Descriptor library.
|
||||
@ -713,7 +714,8 @@ libbfd.o: libbfd.c
|
||||
opncls.o: opncls.c
|
||||
reloc.o: reloc.c $(INCDIR)/bfdlink.h
|
||||
section.o: section.c
|
||||
syms.o: syms.c $(INCDIR)/aout/stab_gnu.h $(INCDIR)/aout/stab.def
|
||||
syms.o: syms.c $(INCDIR)/bfdlink.h $(INCDIR)/aout/stab_gnu.h \
|
||||
$(INCDIR)/aout/stab.def
|
||||
targets.o: targets.c
|
||||
hash.o: hash.c
|
||||
linker.o: linker.c $(INCDIR)/bfdlink.h genlink.h
|
||||
@ -852,7 +854,7 @@ elf32-ppc.o: elf32-ppc.c $(INCDIR)/bfdlink.h elf-bfd.h \
|
||||
$(INCDIR)/elf/ppc.h elf32-target.h
|
||||
elf32-sparc.o: elf32-sparc.c $(INCDIR)/bfdlink.h elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
|
||||
elf32-target.h
|
||||
$(INCDIR)/elf/sparc.h elf32-target.h
|
||||
elf32.o: elf32.c elfcode.h $(INCDIR)/bfdlink.h elf-bfd.h \
|
||||
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
|
||||
elfcore.h elflink.h
|
||||
@ -962,8 +964,8 @@ aout64.o: aout64.c aoutx.h $(INCDIR)/bfdlink.h libaout.h \
|
||||
$(INCDIR)/aout/ar.h
|
||||
coff-alpha.o: coff-alpha.c $(INCDIR)/bfdlink.h $(INCDIR)/coff/internal.h \
|
||||
$(INCDIR)/coff/sym.h $(INCDIR)/coff/symconst.h $(INCDIR)/coff/ecoff.h \
|
||||
$(INCDIR)/coff/alpha.h libcoff.h libecoff.h coffswap.h \
|
||||
ecoffswap.h
|
||||
$(INCDIR)/coff/alpha.h $(INCDIR)/aout/ar.h libcoff.h \
|
||||
libecoff.h coffswap.h ecoffswap.h
|
||||
demo64.o: demo64.c aoutf1.h $(INCDIR)/aout/sun4.h libaout.h \
|
||||
$(INCDIR)/bfdlink.h $(INCDIR)/aout/aout64.h $(INCDIR)/aout/stab_gnu.h \
|
||||
$(INCDIR)/aout/stab.def $(INCDIR)/aout/ar.h aout-target.h
|
||||
@ -987,8 +989,7 @@ hpux-core.o: hpux-core.c
|
||||
irix-core.o: irix-core.c
|
||||
lynx-core.o: lynx-core.c
|
||||
osf-core.o: osf-core.c
|
||||
trad-core.o: trad-core.c libaout.h $(INCDIR)/bfdlink.h \
|
||||
hosts/i386bsd.h
|
||||
trad-core.o: trad-core.c libaout.h $(INCDIR)/bfdlink.h
|
||||
cisco-core.o: cisco-core.c
|
||||
i386dynix.o: i386dynix.c $(INCDIR)/aout/dynix3.h aoutx.h \
|
||||
$(INCDIR)/bfdlink.h libaout.h $(INCDIR)/aout/aout64.h \
|
||||
|
123
bfd/elf-bfd.h
123
bfd/elf-bfd.h
@ -102,6 +102,11 @@ struct elf_link_hash_entry
|
||||
require an entry in the procedure linkage table. */
|
||||
bfd_vma plt_offset;
|
||||
|
||||
/* If this symbol is used in the linker created sections, the processor
|
||||
specific backend uses this field to map the field into the offset
|
||||
from the beginning of the section. */
|
||||
struct elf_linker_section_pointers *linker_section_pointer;
|
||||
|
||||
/* Symbol type (STT_NOTYPE, STT_OBJECT, etc.). */
|
||||
char type;
|
||||
|
||||
@ -482,6 +487,52 @@ struct bfd_elf_section_data
|
||||
#define get_elf_backend_data(abfd) \
|
||||
((struct elf_backend_data *) (abfd)->xvec->backend_data)
|
||||
|
||||
/* Enumeration to specify the special section. */
|
||||
typedef enum elf_linker_section_enum
|
||||
{
|
||||
LINKER_SECTION_UNKNOWN, /* not used */
|
||||
LINKER_SECTION_GOT, /* .got section for global offset pointers */
|
||||
LINKER_SECTION_PLT, /* .plt section for generated procedure stubs */
|
||||
LINKER_SECTION_SDATA, /* .sdata/.sbss section for PowerPC */
|
||||
LINKER_SECTION_SDATA2, /* .sdata2/.sbss2 section for PowerPC */
|
||||
LINKER_SECTION_MAX /* # of linker sections */
|
||||
} elf_linker_section_enum_t;
|
||||
|
||||
/* Sections created by the linker. */
|
||||
|
||||
typedef struct elf_linker_section
|
||||
{
|
||||
char *name; /* name of the section */
|
||||
char *rel_name; /* name of the associated .rel{,a}. section */
|
||||
char *bss_name; /* name of a related .bss section */
|
||||
char *sym_name; /* name of symbol to reference this section */
|
||||
asection *section; /* pointer to the section */
|
||||
asection *bss_section; /* pointer to the bss section associated with this */
|
||||
asection *rel_section; /* pointer to the relocations needed for this section */
|
||||
struct elf_link_hash_entry *sym_hash; /* pointer to the created symbol hash value */
|
||||
bfd_vma initial_size; /* initial size before any linker generated allocations */
|
||||
bfd_vma sym_offset; /* offset of symbol from beginning of section */
|
||||
bfd_vma hole_size; /* size of reserved address hole in allocation */
|
||||
bfd_vma hole_offset; /* current offset for the hole */
|
||||
bfd_vma max_hole_offset; /* maximum offset for the hole */
|
||||
elf_linker_section_enum_t which; /* which section this is */
|
||||
boolean hole_written_p; /* whether the hole has been initialized */
|
||||
int alignment; /* alignment for the section */
|
||||
flagword flags; /* flags to use to create the section */
|
||||
} elf_linker_section_t;
|
||||
|
||||
/* Linked list of allocated pointer entries. This hangs off of the symbol lists, and
|
||||
provides allows us to return different pointers, based on different addend's. */
|
||||
|
||||
typedef struct elf_linker_section_pointers
|
||||
{
|
||||
struct elf_linker_section_pointers *next; /* next allocated pointer for this symbol */
|
||||
bfd_vma offset; /* offset of pointer from beginning of section */
|
||||
bfd_signed_vma addend; /* addend used */
|
||||
elf_linker_section_enum_t which; /* which linker section this is */
|
||||
boolean written_address_p; /* whether address was written yet */
|
||||
} elf_linker_section_pointers_t;
|
||||
|
||||
/* Some private data is stashed away for future use using the tdata pointer
|
||||
in the bfd structure. */
|
||||
|
||||
@ -494,7 +545,7 @@ struct elf_obj_tdata
|
||||
struct bfd_strtab_hash *strtab_ptr;
|
||||
int num_locals;
|
||||
int num_globals;
|
||||
asymbol **section_syms; /* STT_SECTION symbols for each section */
|
||||
asymbol **section_syms; /* STT_SECTION symbols for each section */
|
||||
Elf_Internal_Shdr symtab_hdr;
|
||||
Elf_Internal_Shdr shstrtab_hdr;
|
||||
Elf_Internal_Shdr strtab_hdr;
|
||||
@ -503,10 +554,10 @@ struct elf_obj_tdata
|
||||
unsigned int symtab_section, shstrtab_section;
|
||||
unsigned int strtab_section, dynsymtab_section;
|
||||
file_ptr next_file_pos;
|
||||
void *prstatus; /* The raw /proc prstatus structure */
|
||||
void *prpsinfo; /* The raw /proc prpsinfo structure */
|
||||
bfd_vma gp; /* The gp value (MIPS only, for now) */
|
||||
unsigned int gp_size; /* The gp size (MIPS only, for now) */
|
||||
void *prstatus; /* The raw /proc prstatus structure */
|
||||
void *prpsinfo; /* The raw /proc prpsinfo structure */
|
||||
bfd_vma gp; /* The gp value (MIPS only, for now) */
|
||||
unsigned int gp_size; /* The gp size (MIPS only, for now) */
|
||||
|
||||
/* This is set to true if the object was created by the backend
|
||||
linker. */
|
||||
@ -521,6 +572,10 @@ struct elf_obj_tdata
|
||||
table, used when linking. This is indexed by the symbol index. */
|
||||
bfd_vma *local_got_offsets;
|
||||
|
||||
/* A mapping from local symbols to offsets into the various linker
|
||||
sections added. This is index by the symbol index. */
|
||||
elf_linker_section_pointers_t **linker_section_pointers;
|
||||
|
||||
/* The linker ELF emulation code needs to let the backend ELF linker
|
||||
know what filename should be used for a dynamic object if the
|
||||
dynamic object is found using a search. This field is used to
|
||||
@ -537,6 +592,9 @@ struct elf_obj_tdata
|
||||
/* Records the result of `get_program_header_size'. */
|
||||
bfd_size_type program_header_size;
|
||||
|
||||
/* Used by find_nearest_line entry point. */
|
||||
PTR line_info;
|
||||
|
||||
/* Used by MIPS ELF find_nearest_line entry point. The structure
|
||||
could be included directly in this one, but there's no point to
|
||||
wasting the memory just for the infrequently called
|
||||
@ -545,6 +603,9 @@ struct elf_obj_tdata
|
||||
|
||||
/* Used to determine if the e_flags field has been initialized */
|
||||
boolean flags_init;
|
||||
|
||||
/* Linker sections that we are interested in. */
|
||||
struct elf_linker_section *linker_section[ (int)LINKER_SECTION_MAX ];
|
||||
};
|
||||
|
||||
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
|
||||
@ -562,9 +623,11 @@ struct elf_obj_tdata
|
||||
#define elf_gp_size(bfd) (elf_tdata(bfd) -> gp_size)
|
||||
#define elf_sym_hashes(bfd) (elf_tdata(bfd) -> sym_hashes)
|
||||
#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got_offsets)
|
||||
#define elf_local_ptr_offsets(bfd) (elf_tdata(bfd) -> linker_section_pointers)
|
||||
#define elf_dt_needed_name(bfd) (elf_tdata(bfd) -> dt_needed_name)
|
||||
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
|
||||
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
|
||||
#define elf_linker_section(bfd,n) (elf_tdata(bfd) -> linker_section[(int)n])
|
||||
|
||||
extern int _bfd_elf_section_from_bfd_section PARAMS ((bfd *, asection *));
|
||||
extern char *bfd_elf_string_from_elf_section
|
||||
@ -661,6 +724,56 @@ boolean _bfd_elf_create_dynamic_sections PARAMS ((bfd *,
|
||||
boolean _bfd_elf_create_got_section PARAMS ((bfd *,
|
||||
struct bfd_link_info *));
|
||||
|
||||
elf_linker_section_t *_bfd_elf_create_linker_section
|
||||
PARAMS ((bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
enum elf_linker_section_enum,
|
||||
elf_linker_section_t *defaults));
|
||||
|
||||
elf_linker_section_pointers_t *_bfd_elf_find_pointer_linker_section
|
||||
PARAMS ((elf_linker_section_pointers_t *linker_pointers,
|
||||
bfd_signed_vma addend,
|
||||
elf_linker_section_enum_t which));
|
||||
|
||||
boolean bfd_elf32_create_pointer_linker_section
|
||||
PARAMS ((bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
elf_linker_section_t *lsect,
|
||||
struct elf_link_hash_entry *h,
|
||||
const Elf32_Internal_Rela *rel));
|
||||
|
||||
bfd_vma bfd_elf32_finish_pointer_linker_section
|
||||
PARAMS ((bfd *output_abfd,
|
||||
bfd *input_bfd,
|
||||
struct bfd_link_info *info,
|
||||
elf_linker_section_t *lsect,
|
||||
struct elf_link_hash_entry *h,
|
||||
bfd_vma relocation,
|
||||
const Elf32_Internal_Rela *rel,
|
||||
int relative_reloc));
|
||||
|
||||
boolean bfd_elf64_create_pointer_linker_section
|
||||
PARAMS ((bfd *abfd,
|
||||
struct bfd_link_info *info,
|
||||
elf_linker_section_t *lsect,
|
||||
struct elf_link_hash_entry *h,
|
||||
const Elf64_Internal_Rela *rel));
|
||||
|
||||
bfd_vma bfd_elf64_finish_pointer_linker_section
|
||||
PARAMS ((bfd *output_abfd,
|
||||
bfd *input_bfd,
|
||||
struct bfd_link_info *info,
|
||||
elf_linker_section_t *lsect,
|
||||
struct elf_link_hash_entry *h,
|
||||
bfd_vma relocation,
|
||||
const Elf64_Internal_Rela *rel,
|
||||
int relative_reloc));
|
||||
|
||||
boolean _bfd_elf_make_linker_section_rela
|
||||
PARAMS ((bfd *dynobj,
|
||||
elf_linker_section_t *lsect,
|
||||
int alignment));
|
||||
|
||||
extern const bfd_target *bfd_elf32_object_p PARAMS ((bfd *));
|
||||
extern const bfd_target *bfd_elf32_core_file_p PARAMS ((bfd *));
|
||||
extern char *bfd_elf32_core_file_failing_command PARAMS ((bfd *));
|
||||
|
22
bfd/elf.c
22
bfd/elf.c
@ -554,6 +554,7 @@ _bfd_elf_link_hash_newfunc (entry, table, string)
|
||||
ret->weakdef = NULL;
|
||||
ret->got_offset = (bfd_vma) -1;
|
||||
ret->plt_offset = (bfd_vma) -1;
|
||||
ret->linker_section_pointer = (elf_linker_section_pointers_t *)0;
|
||||
ret->type = STT_NOTYPE;
|
||||
ret->elf_link_hash_flags = 0;
|
||||
}
|
||||
@ -3142,15 +3143,26 @@ _bfd_elf_find_nearest_line (abfd,
|
||||
CONST char **functionname_ptr;
|
||||
unsigned int *line_ptr;
|
||||
{
|
||||
boolean found;
|
||||
const char *filename;
|
||||
asymbol *func;
|
||||
bfd_vma low_func;
|
||||
asymbol **p;
|
||||
|
||||
if (! _bfd_stab_section_find_nearest_line (abfd, symbols, section, offset,
|
||||
&found, filename_ptr,
|
||||
functionname_ptr, line_ptr,
|
||||
&elf_tdata (abfd)->line_info))
|
||||
return false;
|
||||
if (found)
|
||||
return true;
|
||||
|
||||
if (symbols == NULL)
|
||||
return false;
|
||||
|
||||
filename = NULL;
|
||||
func = NULL;
|
||||
low_func = 0;
|
||||
|
||||
for (p = symbols; *p != NULL; p++)
|
||||
{
|
||||
@ -3169,9 +3181,13 @@ _bfd_elf_find_nearest_line (abfd,
|
||||
filename = bfd_asymbol_name (&q->symbol);
|
||||
break;
|
||||
case STT_FUNC:
|
||||
if (func == NULL
|
||||
|| q->symbol.value <= offset)
|
||||
func = (asymbol *) q;
|
||||
if (q->symbol.section == section
|
||||
&& q->symbol.value >= low_func
|
||||
&& q->symbol.value <= offset)
|
||||
{
|
||||
func = (asymbol *) q;
|
||||
low_func = q->symbol.value;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -89,6 +89,9 @@ typedef struct coff_tdata
|
||||
int *local_toc_sym_map;
|
||||
|
||||
struct bfd_link_info *link_info;
|
||||
|
||||
/* Used by coff_find_nearest_line. */
|
||||
PTR line_info;
|
||||
} coff_data_type;
|
||||
|
||||
/* Tdata for pe image files. */
|
||||
@ -117,11 +120,11 @@ struct xcoff_tdata
|
||||
/* TOC value. */
|
||||
bfd_vma toc;
|
||||
|
||||
/* Section holding TOC. */
|
||||
asection *toc_section;
|
||||
/* Index of section holding TOC. */
|
||||
int sntoc;
|
||||
|
||||
/* Section holding entry point. */
|
||||
asection *entry_section;
|
||||
/* Index of section holding entry point. */
|
||||
int snentry;
|
||||
|
||||
/* .text alignment from optional header. */
|
||||
int text_align_power;
|
||||
@ -223,11 +226,6 @@ struct coff_link_hash_entry
|
||||
|
||||
/* Pointer to array of auxiliary entries, if any. */
|
||||
union internal_auxent *aux;
|
||||
|
||||
/* If this symbol requires an entry in the table of contents, the
|
||||
processor specific backend uses this field to hold the offset
|
||||
into the .toc section. */
|
||||
bfd_vma toc_offset;
|
||||
};
|
||||
|
||||
/* COFF linker hash table. */
|
||||
|
@ -89,6 +89,9 @@ typedef struct coff_tdata
|
||||
int *local_toc_sym_map;
|
||||
|
||||
struct bfd_link_info *link_info;
|
||||
|
||||
/* Used by coff_find_nearest_line. */
|
||||
PTR line_info;
|
||||
} coff_data_type;
|
||||
|
||||
/* Tdata for pe image files. */
|
||||
@ -117,11 +120,11 @@ struct xcoff_tdata
|
||||
/* TOC value. */
|
||||
bfd_vma toc;
|
||||
|
||||
/* Section holding TOC. */
|
||||
asection *toc_section;
|
||||
/* Index of section holding TOC. */
|
||||
int sntoc;
|
||||
|
||||
/* Section holding entry point. */
|
||||
asection *entry_section;
|
||||
/* Index of section holding entry point. */
|
||||
int snentry;
|
||||
|
||||
/* .text alignment from optional header. */
|
||||
int text_align_power;
|
||||
@ -223,11 +226,6 @@ struct coff_link_hash_entry
|
||||
|
||||
/* Pointer to array of auxiliary entries, if any. */
|
||||
union internal_auxent *aux;
|
||||
|
||||
/* If this symbol requires an entry in the table of contents, the
|
||||
processor specific backend uses this field to hold the offset
|
||||
into the .toc section. */
|
||||
bfd_vma toc_offset;
|
||||
};
|
||||
|
||||
/* COFF linker hash table. */
|
||||
|
430
bfd/syms.c
430
bfd/syms.c
@ -48,6 +48,7 @@ SECTION
|
||||
@menu
|
||||
@* Reading Symbols::
|
||||
@* Writing Symbols::
|
||||
@* Mini Symbols::
|
||||
@* typedef asymbol::
|
||||
@* symbol handling functions::
|
||||
@end menu
|
||||
@ -91,7 +92,7 @@ SUBSECTION
|
||||
|
||||
|
||||
INODE
|
||||
Writing Symbols, Mini symbols, Reading Symbols, Symbols
|
||||
Writing Symbols, Mini Symbols, Reading Symbols, Symbols
|
||||
SUBSECTION
|
||||
Writing symbols
|
||||
|
||||
@ -138,9 +139,9 @@ SUBSECTION
|
||||
be described.
|
||||
|
||||
INODE
|
||||
Mini symbols, typedef asymbol, Writing Symbols, Symbols
|
||||
Mini Symbols, typedef asymbol, Writing Symbols, Symbols
|
||||
SUBSECTION
|
||||
Mini symbols
|
||||
Mini Symbols
|
||||
|
||||
Mini symbols provide read-only access to the symbol table.
|
||||
They use less memory space, but require more time to access.
|
||||
@ -166,7 +167,7 @@ SUBSECTION
|
||||
/*
|
||||
DOCDD
|
||||
INODE
|
||||
typedef asymbol, symbol handling functions, Mini symbols, Symbols
|
||||
typedef asymbol, symbol handling functions, Mini Symbols, Symbols
|
||||
|
||||
*/
|
||||
/*
|
||||
@ -262,15 +263,14 @@ CODE_FRAGMENT
|
||||
. {* Signal that the symbol is the label of constructor section. *}
|
||||
.#define BSF_CONSTRUCTOR 0x800
|
||||
.
|
||||
. {* Signal that the symbol is a warning symbol. If the symbol
|
||||
. is a warning symbol, then the value field (I know this is
|
||||
. tacky) will point to the asymbol which when referenced will
|
||||
. cause the warning. *}
|
||||
. {* Signal that the symbol is a warning symbol. The name is a
|
||||
. warning. The name of the next symbol is the one to warn about;
|
||||
. if a reference is made to a symbol with the same name as the next
|
||||
. symbol, a warning is issued by the linker. *}
|
||||
.#define BSF_WARNING 0x1000
|
||||
.
|
||||
. {* Signal that the symbol is indirect. The value of the symbol
|
||||
. is a pointer to an undefined asymbol which contains the
|
||||
. name to use instead. *}
|
||||
. {* Signal that the symbol is indirect. This symbol is an indirect
|
||||
. pointer to the symbol with the same name as the next symbol. *}
|
||||
.#define BSF_INDIRECT 0x2000
|
||||
.
|
||||
. {* BSF_FILE marks symbols that contain a file name. This is used
|
||||
@ -299,8 +299,8 @@ CODE_FRAGMENT
|
||||
|
||||
#include "bfd.h"
|
||||
#include "sysdep.h"
|
||||
|
||||
#include "libbfd.h"
|
||||
#include "bfdlink.h"
|
||||
#include "aout/stab_gnu.h"
|
||||
|
||||
/*
|
||||
@ -634,12 +634,9 @@ _bfd_generic_read_minisymbols (abfd, dynamic, minisymsp, sizep)
|
||||
if (storage < 0)
|
||||
goto error_return;
|
||||
|
||||
syms = (asymbol **) malloc ((size_t) storage);
|
||||
syms = (asymbol **) bfd_malloc ((size_t) storage);
|
||||
if (syms == NULL)
|
||||
{
|
||||
bfd_set_error (bfd_error_no_memory);
|
||||
goto error_return;
|
||||
}
|
||||
goto error_return;
|
||||
|
||||
if (dynamic)
|
||||
symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
|
||||
@ -672,3 +669,402 @@ _bfd_generic_minisymbol_to_symbol (abfd, dynamic, minisym, sym)
|
||||
{
|
||||
return *(asymbol **) minisym;
|
||||
}
|
||||
|
||||
/* Look through stabs debugging information in .stab and .stabstr
|
||||
sections to find the source file and line closest to a desired
|
||||
location. This is used by COFF and ELF targets. It sets *pfound
|
||||
to true if it finds some information. The *pinfo field is used to
|
||||
pass cached information in and out of this routine; this first time
|
||||
the routine is called for a BFD, *pinfo should be NULL. The value
|
||||
placed in *pinfo should be saved with the BFD, and passed back each
|
||||
time this function is called. */
|
||||
|
||||
/* A pointer to this structure is stored in *pinfo. */
|
||||
|
||||
struct stab_find_info
|
||||
{
|
||||
/* The .stab section. */
|
||||
asection *stabsec;
|
||||
/* The .stabstr section. */
|
||||
asection *strsec;
|
||||
/* The contents of the .stab section. */
|
||||
bfd_byte *stabs;
|
||||
/* The contents of the .stabstr section. */
|
||||
bfd_byte *strs;
|
||||
/* An malloc buffer to hold the file name. */
|
||||
char *filename;
|
||||
/* Cached values to restart quickly. */
|
||||
bfd_vma cached_offset;
|
||||
bfd_byte *cached_stab;
|
||||
bfd_byte *cached_str;
|
||||
bfd_size_type cached_stroff;
|
||||
};
|
||||
|
||||
boolean
|
||||
_bfd_stab_section_find_nearest_line (abfd, symbols, section, offset, pfound,
|
||||
pfilename, pfnname, pline, pinfo)
|
||||
bfd *abfd;
|
||||
asymbol **symbols;
|
||||
asection *section;
|
||||
bfd_vma offset;
|
||||
boolean *pfound;
|
||||
const char **pfilename;
|
||||
const char **pfnname;
|
||||
unsigned int *pline;
|
||||
PTR *pinfo;
|
||||
{
|
||||
struct stab_find_info *info;
|
||||
bfd_size_type stabsize, strsize;
|
||||
bfd_byte *stab, *stabend, *str;
|
||||
bfd_size_type stroff;
|
||||
bfd_vma fnaddr;
|
||||
char *directory_name, *main_file_name, *current_file_name, *line_file_name;
|
||||
char *fnname;
|
||||
bfd_vma low_func_vma, low_line_vma;
|
||||
|
||||
*pfound = false;
|
||||
*pfilename = bfd_get_filename (abfd);
|
||||
*pfnname = NULL;
|
||||
*pline = 0;
|
||||
|
||||
info = (struct stab_find_info *) *pinfo;
|
||||
if (info != NULL)
|
||||
{
|
||||
if (info->stabsec == NULL || info->strsec == NULL)
|
||||
{
|
||||
/* No stabs debugging information. */
|
||||
return true;
|
||||
}
|
||||
|
||||
stabsize = info->stabsec->_raw_size;
|
||||
strsize = info->strsec->_raw_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
long reloc_size, reloc_count;
|
||||
arelent **reloc_vector;
|
||||
|
||||
info = (struct stab_find_info *) bfd_zalloc (abfd, sizeof *info);
|
||||
if (info == NULL)
|
||||
return false;
|
||||
|
||||
/* FIXME: When using the linker --split-by-file or
|
||||
--split-by-reloc options, it is possible for the .stab and
|
||||
.stabstr sections to be split. We should handle that. */
|
||||
|
||||
info->stabsec = bfd_get_section_by_name (abfd, ".stab");
|
||||
info->strsec = bfd_get_section_by_name (abfd, ".stabstr");
|
||||
|
||||
if (info->stabsec == NULL || info->strsec == NULL)
|
||||
{
|
||||
/* No stabs debugging information. Set *pinfo so that we
|
||||
can return quickly in the info != NULL case above. */
|
||||
*pinfo = info;
|
||||
return true;
|
||||
}
|
||||
|
||||
stabsize = info->stabsec->_raw_size;
|
||||
strsize = info->strsec->_raw_size;
|
||||
|
||||
info->stabs = (bfd_byte *) bfd_alloc (abfd, stabsize);
|
||||
info->strs = (bfd_byte *) bfd_alloc (abfd, strsize);
|
||||
if (info->stabs == NULL || info->strs == NULL)
|
||||
return false;
|
||||
|
||||
if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs, 0,
|
||||
stabsize)
|
||||
|| ! bfd_get_section_contents (abfd, info->strsec, info->strs, 0,
|
||||
strsize))
|
||||
return false;
|
||||
|
||||
/* If this is a relocateable object file, we have to relocate
|
||||
the entries in .stab. This should always be simple 32 bit
|
||||
relocations against symbols defined in this object file, so
|
||||
this should be no big deal. */
|
||||
reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);
|
||||
if (reloc_size < 0)
|
||||
return false;
|
||||
reloc_vector = (arelent **) bfd_malloc (reloc_size);
|
||||
if (reloc_vector == NULL && reloc_size != 0)
|
||||
return false;
|
||||
reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,
|
||||
symbols);
|
||||
if (reloc_count < 0)
|
||||
{
|
||||
if (reloc_vector != NULL)
|
||||
free (reloc_vector);
|
||||
return false;
|
||||
}
|
||||
if (reloc_count > 0)
|
||||
{
|
||||
arelent **pr;
|
||||
|
||||
for (pr = reloc_vector; *pr != NULL; pr++)
|
||||
{
|
||||
arelent *r;
|
||||
unsigned long val;
|
||||
asymbol *sym;
|
||||
|
||||
r = *pr;
|
||||
if (r->howto->rightshift != 0
|
||||
|| r->howto->size != 2
|
||||
|| r->howto->bitsize != 32
|
||||
|| r->howto->pc_relative
|
||||
|| r->howto->bitpos != 0
|
||||
|| r->howto->dst_mask != 0xffffffff)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
("Unsupported .stab relocation");
|
||||
bfd_set_error (bfd_error_invalid_operation);
|
||||
if (reloc_vector != NULL)
|
||||
free (reloc_vector);
|
||||
return false;
|
||||
}
|
||||
|
||||
val = bfd_get_32 (abfd, info->stabs + r->address);
|
||||
val &= r->howto->src_mask;
|
||||
sym = *r->sym_ptr_ptr;
|
||||
val += sym->value + sym->section->vma + r->addend;
|
||||
bfd_put_32 (abfd, val, info->stabs + r->address);
|
||||
}
|
||||
}
|
||||
|
||||
if (reloc_vector != NULL)
|
||||
free (reloc_vector);
|
||||
|
||||
*pinfo = info;
|
||||
}
|
||||
|
||||
/* We are passed a section relative offset. The offsets in the
|
||||
stabs information are absolute. */
|
||||
offset += bfd_get_section_vma (abfd, section);
|
||||
|
||||
/* Stabs entries use a 12 byte format:
|
||||
4 byte string table index
|
||||
1 byte stab type
|
||||
1 byte stab other field
|
||||
2 byte stab desc field
|
||||
4 byte stab value
|
||||
FIXME: This will have to change for a 64 bit object format.
|
||||
|
||||
The stabs symbols are divided into compilation units. For the
|
||||
first entry in each unit, the type of 0, the value is the length
|
||||
of the string table for this unit, and the desc field is the
|
||||
number of stabs symbols for this unit. */
|
||||
|
||||
#define STRDXOFF (0)
|
||||
#define TYPEOFF (4)
|
||||
#define OTHEROFF (5)
|
||||
#define DESCOFF (6)
|
||||
#define VALOFF (8)
|
||||
#define STABSIZE (12)
|
||||
|
||||
/* It would be nice if we could skip ahead to the stabs symbols for
|
||||
the next compilation unit to quickly scan through the compilation
|
||||
units. Unfortunately, since each line number gets a separate
|
||||
stabs entry, it is entirely plausible that a large source file
|
||||
will overflow the 16 bit count of stabs entries. */
|
||||
fnaddr = 0;
|
||||
directory_name = NULL;
|
||||
main_file_name = NULL;
|
||||
current_file_name = NULL;
|
||||
line_file_name = NULL;
|
||||
fnname = NULL;
|
||||
low_func_vma = 0;
|
||||
low_line_vma = 0;
|
||||
|
||||
stabend = info->stabs + stabsize;
|
||||
|
||||
if (info->cached_stab == NULL || offset < info->cached_offset)
|
||||
{
|
||||
stab = info->stabs;
|
||||
str = info->strs;
|
||||
stroff = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stab = info->cached_stab;
|
||||
str = info->cached_str;
|
||||
stroff = info->cached_stroff;
|
||||
}
|
||||
|
||||
info->cached_offset = offset;
|
||||
|
||||
for (; stab < stabend; stab += STABSIZE)
|
||||
{
|
||||
boolean done;
|
||||
bfd_vma val;
|
||||
char *name;
|
||||
|
||||
done = false;
|
||||
|
||||
switch (stab[TYPEOFF])
|
||||
{
|
||||
case 0:
|
||||
/* This is the first entry in a compilation unit. */
|
||||
if ((bfd_size_type) ((info->strs + strsize) - str) < stroff)
|
||||
{
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
str += stroff;
|
||||
stroff = bfd_get_32 (abfd, stab + VALOFF);
|
||||
break;
|
||||
|
||||
case N_SO:
|
||||
/* The main file name. */
|
||||
|
||||
val = bfd_get_32 (abfd, stab + VALOFF);
|
||||
if (val > offset)
|
||||
{
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
|
||||
name = str + bfd_get_32 (abfd, stab + STRDXOFF);
|
||||
|
||||
/* An empty string indicates the end of the compilation
|
||||
unit. */
|
||||
if (*name == '\0')
|
||||
{
|
||||
/* If there are functions in different sections, they
|
||||
may have addresses larger than val, but we don't want
|
||||
to forget the file name. When there are functions in
|
||||
different cases, there is supposed to be an N_FUN at
|
||||
the end of the function indicating where it ends. */
|
||||
if (low_func_vma < val || fnname == NULL)
|
||||
main_file_name = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We know that we have to get to at least this point in the
|
||||
stabs entries for this offset. */
|
||||
info->cached_stab = stab;
|
||||
info->cached_str = str;
|
||||
info->cached_stroff = stroff;
|
||||
|
||||
current_file_name = name;
|
||||
|
||||
/* Look ahead to the next symbol. Two consecutive N_SO
|
||||
symbols are a directory and a file name. */
|
||||
if (stab + STABSIZE >= stabend
|
||||
|| *(stab + STABSIZE + TYPEOFF) != N_SO)
|
||||
directory_name = NULL;
|
||||
else
|
||||
{
|
||||
stab += STABSIZE;
|
||||
directory_name = current_file_name;
|
||||
current_file_name = str + bfd_get_32 (abfd, stab + STRDXOFF);
|
||||
}
|
||||
|
||||
main_file_name = current_file_name;
|
||||
|
||||
break;
|
||||
|
||||
case N_SOL:
|
||||
/* The name of an include file. */
|
||||
current_file_name = str + bfd_get_32 (abfd, stab + STRDXOFF);
|
||||
break;
|
||||
|
||||
case N_SLINE:
|
||||
case N_DSLINE:
|
||||
case N_BSLINE:
|
||||
/* A line number. The value is relative to the start of the
|
||||
current function. */
|
||||
val = fnaddr + bfd_get_32 (abfd, stab + VALOFF);
|
||||
if (val >= low_line_vma && val <= offset)
|
||||
{
|
||||
*pline = bfd_get_16 (abfd, stab + DESCOFF);
|
||||
low_line_vma = val;
|
||||
line_file_name = current_file_name;
|
||||
}
|
||||
break;
|
||||
|
||||
case N_FUN:
|
||||
/* A function name. */
|
||||
val = bfd_get_32 (abfd, stab + VALOFF);
|
||||
name = str + bfd_get_32 (abfd, stab + STRDXOFF);
|
||||
|
||||
/* An empty string here indicates the end of a function, and
|
||||
the value is relative to fnaddr. */
|
||||
|
||||
if (*name == '\0')
|
||||
{
|
||||
val += fnaddr;
|
||||
if (val >= low_func_vma && val < offset)
|
||||
fnname = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (val >= low_func_vma && val <= offset)
|
||||
{
|
||||
fnname = name;
|
||||
low_func_vma = val;
|
||||
}
|
||||
|
||||
fnaddr = val;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
|
||||
if (main_file_name == NULL)
|
||||
{
|
||||
/* No information found. */
|
||||
return true;
|
||||
}
|
||||
|
||||
*pfound = true;
|
||||
|
||||
if (*pline != 0)
|
||||
main_file_name = line_file_name;
|
||||
|
||||
if (main_file_name != NULL)
|
||||
{
|
||||
if (main_file_name[0] == '/' || directory_name == NULL)
|
||||
*pfilename = main_file_name;
|
||||
else
|
||||
{
|
||||
size_t dirlen;
|
||||
|
||||
dirlen = strlen (directory_name);
|
||||
if (info->filename == NULL
|
||||
|| strncmp (info->filename, directory_name, dirlen) != 0
|
||||
|| strcmp (info->filename + dirlen, main_file_name) != 0)
|
||||
{
|
||||
if (info->filename != NULL)
|
||||
free (info->filename);
|
||||
info->filename = (char *) bfd_malloc (dirlen +
|
||||
strlen (main_file_name)
|
||||
+ 1);
|
||||
if (info->filename == NULL)
|
||||
return false;
|
||||
strcpy (info->filename, directory_name);
|
||||
strcpy (info->filename + dirlen, main_file_name);
|
||||
}
|
||||
|
||||
*pfilename = info->filename;
|
||||
}
|
||||
}
|
||||
|
||||
if (fnname != NULL)
|
||||
{
|
||||
char *s;
|
||||
|
||||
/* This will typically be something like main:F(0,1), so we want
|
||||
to clobber the colon. It's OK to change the name, since the
|
||||
string is in our own local storage anyhow. */
|
||||
|
||||
s = strchr (fnname, ':');
|
||||
if (s != NULL)
|
||||
*s = '\0';
|
||||
|
||||
*pfnname = fnname;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user