Line 1... |
Line 1... |
/* Generic symbol-table support for the BFD library.
|
/* Generic symbol-table support for the BFD library.
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
2000, 2001, 2002, 2003, 2004, 2007
|
2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
|
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
Written by Cygnus Support.
|
Written by Cygnus Support.
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
Line 207... |
Line 207... |
. {* Attributes of a symbol. *}
|
. {* Attributes of a symbol. *}
|
.#define BSF_NO_FLAGS 0x00
|
.#define BSF_NO_FLAGS 0x00
|
.
|
.
|
. {* The symbol has local scope; <<static>> in <<C>>. The value
|
. {* The symbol has local scope; <<static>> in <<C>>. The value
|
. is the offset into the section of the data. *}
|
. is the offset into the section of the data. *}
|
.#define BSF_LOCAL 0x01
|
.#define BSF_LOCAL (1 << 0)
|
.
|
.
|
. {* The symbol has global scope; initialized data in <<C>>. The
|
. {* The symbol has global scope; initialized data in <<C>>. The
|
. value is the offset into the section of the data. *}
|
. value is the offset into the section of the data. *}
|
.#define BSF_GLOBAL 0x02
|
.#define BSF_GLOBAL (1 << 1)
|
.
|
.
|
. {* The symbol has global scope and is exported. The value is
|
. {* The symbol has global scope and is exported. The value is
|
. the offset into the section of the data. *}
|
. the offset into the section of the data. *}
|
.#define BSF_EXPORT BSF_GLOBAL {* No real difference. *}
|
.#define BSF_EXPORT BSF_GLOBAL {* No real difference. *}
|
.
|
.
|
. {* A normal C symbol would be one of:
|
. {* A normal C symbol would be one of:
|
. <<BSF_LOCAL>>, <<BSF_FORT_COMM>>, <<BSF_UNDEFINED>> or
|
. <<BSF_LOCAL>>, <<BSF_COMMON>>, <<BSF_UNDEFINED>> or
|
. <<BSF_GLOBAL>>. *}
|
. <<BSF_GLOBAL>>. *}
|
.
|
.
|
. {* The symbol is a debugging record. The value has an arbitrary
|
. {* The symbol is a debugging record. The value has an arbitrary
|
. meaning, unless BSF_DEBUGGING_RELOC is also set. *}
|
. meaning, unless BSF_DEBUGGING_RELOC is also set. *}
|
.#define BSF_DEBUGGING 0x08
|
.#define BSF_DEBUGGING (1 << 2)
|
.
|
.
|
. {* The symbol denotes a function entry point. Used in ELF,
|
. {* The symbol denotes a function entry point. Used in ELF,
|
. perhaps others someday. *}
|
. perhaps others someday. *}
|
.#define BSF_FUNCTION 0x10
|
.#define BSF_FUNCTION (1 << 3)
|
.
|
.
|
. {* Used by the linker. *}
|
. {* Used by the linker. *}
|
.#define BSF_KEEP 0x20
|
.#define BSF_KEEP (1 << 5)
|
.#define BSF_KEEP_G 0x40
|
.#define BSF_KEEP_G (1 << 6)
|
.
|
.
|
. {* A weak global symbol, overridable without warnings by
|
. {* A weak global symbol, overridable without warnings by
|
. a regular global symbol of the same name. *}
|
. a regular global symbol of the same name. *}
|
.#define BSF_WEAK 0x80
|
.#define BSF_WEAK (1 << 7)
|
.
|
.
|
. {* This symbol was created to point to a section, e.g. ELF's
|
. {* This symbol was created to point to a section, e.g. ELF's
|
. STT_SECTION symbols. *}
|
. STT_SECTION symbols. *}
|
.#define BSF_SECTION_SYM 0x100
|
.#define BSF_SECTION_SYM (1 << 8)
|
.
|
.
|
. {* The symbol used to be a common symbol, but now it is
|
. {* The symbol used to be a common symbol, but now it is
|
. allocated. *}
|
. allocated. *}
|
.#define BSF_OLD_COMMON 0x200
|
.#define BSF_OLD_COMMON (1 << 9)
|
.
|
|
. {* The default value for common data. *}
|
|
.#define BFD_FORT_COMM_DEFAULT_VALUE 0
|
|
.
|
.
|
. {* In some files the type of a symbol sometimes alters its
|
. {* In some files the type of a symbol sometimes alters its
|
. location in an output file - ie in coff a <<ISFCN>> symbol
|
. location in an output file - ie in coff a <<ISFCN>> symbol
|
. which is also <<C_EXT>> symbol appears where it was
|
. which is also <<C_EXT>> symbol appears where it was
|
. declared and not at the end of a section. This bit is set
|
. declared and not at the end of a section. This bit is set
|
. by the target BFD part to convey this information. *}
|
. by the target BFD part to convey this information. *}
|
.#define BSF_NOT_AT_END 0x400
|
.#define BSF_NOT_AT_END (1 << 10)
|
.
|
.
|
. {* Signal that the symbol is the label of constructor section. *}
|
. {* Signal that the symbol is the label of constructor section. *}
|
.#define BSF_CONSTRUCTOR 0x800
|
.#define BSF_CONSTRUCTOR (1 << 11)
|
.
|
.
|
. {* Signal that the symbol is a warning symbol. The name is a
|
. {* 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;
|
. 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
|
. if a reference is made to a symbol with the same name as the next
|
. symbol, a warning is issued by the linker. *}
|
. symbol, a warning is issued by the linker. *}
|
.#define BSF_WARNING 0x1000
|
.#define BSF_WARNING (1 << 12)
|
.
|
.
|
. {* Signal that the symbol is indirect. This symbol is an indirect
|
. {* Signal that the symbol is indirect. This symbol is an indirect
|
. pointer to the symbol with the same name as the next symbol. *}
|
. pointer to the symbol with the same name as the next symbol. *}
|
.#define BSF_INDIRECT 0x2000
|
.#define BSF_INDIRECT (1 << 13)
|
.
|
.
|
. {* BSF_FILE marks symbols that contain a file name. This is used
|
. {* BSF_FILE marks symbols that contain a file name. This is used
|
. for ELF STT_FILE symbols. *}
|
. for ELF STT_FILE symbols. *}
|
.#define BSF_FILE 0x4000
|
.#define BSF_FILE (1 << 14)
|
.
|
.
|
. {* Symbol is from dynamic linking information. *}
|
. {* Symbol is from dynamic linking information. *}
|
.#define BSF_DYNAMIC 0x8000
|
.#define BSF_DYNAMIC (1 << 15)
|
.
|
.
|
. {* The symbol denotes a data object. Used in ELF, and perhaps
|
. {* The symbol denotes a data object. Used in ELF, and perhaps
|
. others someday. *}
|
. others someday. *}
|
.#define BSF_OBJECT 0x10000
|
.#define BSF_OBJECT (1 << 16)
|
.
|
.
|
. {* This symbol is a debugging symbol. The value is the offset
|
. {* This symbol is a debugging symbol. The value is the offset
|
. into the section of the data. BSF_DEBUGGING should be set
|
. into the section of the data. BSF_DEBUGGING should be set
|
. as well. *}
|
. as well. *}
|
.#define BSF_DEBUGGING_RELOC 0x20000
|
.#define BSF_DEBUGGING_RELOC (1 << 17)
|
.
|
.
|
. {* This symbol is thread local. Used in ELF. *}
|
. {* This symbol is thread local. Used in ELF. *}
|
.#define BSF_THREAD_LOCAL 0x40000
|
.#define BSF_THREAD_LOCAL (1 << 18)
|
.
|
.
|
. {* This symbol represents a complex relocation expression,
|
. {* This symbol represents a complex relocation expression,
|
. with the expression tree serialized in the symbol name. *}
|
. with the expression tree serialized in the symbol name. *}
|
.#define BSF_RELC 0x80000
|
.#define BSF_RELC (1 << 19)
|
.
|
.
|
. {* This symbol represents a signed complex relocation expression,
|
. {* This symbol represents a signed complex relocation expression,
|
. with the expression tree serialized in the symbol name. *}
|
. with the expression tree serialized in the symbol name. *}
|
.#define BSF_SRELC 0x100000
|
.#define BSF_SRELC (1 << 20)
|
|
.
|
|
. {* This symbol was created by bfd_get_synthetic_symtab. *}
|
|
.#define BSF_SYNTHETIC (1 << 21)
|
|
.
|
|
. {* This symbol is an indirect code object. Unrelated to BSF_INDIRECT.
|
|
. The dynamic linker will compute the value of this symbol by
|
|
. calling the function that it points to. BSF_FUNCTION must
|
|
. also be also set. *}
|
|
.#define BSF_GNU_INDIRECT_FUNCTION (1 << 22)
|
|
. {* This symbol is a globally unique data object. The dynamic linker
|
|
. will make sure that in the entire process there is just one symbol
|
|
. with this name and type in use. BSF_OBJECT must also be set. *}
|
|
.#define BSF_GNU_UNIQUE (1 << 23)
|
.
|
.
|
. flagword flags;
|
. flagword flags;
|
.
|
.
|
. {* A pointer to the section to which this symbol is
|
. {* A pointer to the section to which this symbol is
|
. relative. This will always be non NULL, there are special
|
. relative. This will always be non NULL, there are special
|
Line 462... |
Line 472... |
stream @var{file}.
|
stream @var{file}.
|
*/
|
*/
|
void
|
void
|
bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol)
|
bfd_print_symbol_vandf (bfd *abfd, void *arg, asymbol *symbol)
|
{
|
{
|
FILE *file = arg;
|
FILE *file = (FILE *) arg;
|
|
|
flagword type = symbol->flags;
|
flagword type = symbol->flags;
|
|
|
if (symbol->section != NULL)
|
if (symbol->section != NULL)
|
bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma);
|
bfd_fprintf_vma (abfd, file, symbol->value + symbol->section->vma);
|
Line 477... |
Line 487... |
BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and
|
BSF_DYNAMIC, nor more than one of BSF_FUNCTION, BSF_FILE, and
|
BSF_OBJECT. */
|
BSF_OBJECT. */
|
fprintf (file, " %c%c%c%c%c%c%c",
|
fprintf (file, " %c%c%c%c%c%c%c",
|
((type & BSF_LOCAL)
|
((type & BSF_LOCAL)
|
? (type & BSF_GLOBAL) ? '!' : 'l'
|
? (type & BSF_GLOBAL) ? '!' : 'l'
|
: (type & BSF_GLOBAL) ? 'g' : ' '),
|
: (type & BSF_GLOBAL) ? 'g'
|
|
: (type & BSF_GNU_UNIQUE) ? 'u' : ' '),
|
(type & BSF_WEAK) ? 'w' : ' ',
|
(type & BSF_WEAK) ? 'w' : ' ',
|
(type & BSF_CONSTRUCTOR) ? 'C' : ' ',
|
(type & BSF_CONSTRUCTOR) ? 'C' : ' ',
|
(type & BSF_WARNING) ? 'W' : ' ',
|
(type & BSF_WARNING) ? 'W' : ' ',
|
(type & BSF_INDIRECT) ? 'I' : ' ',
|
(type & BSF_INDIRECT) ? 'I' : (type & BSF_GNU_INDIRECT_FUNCTION) ? 'i' : ' ',
|
(type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
|
(type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
|
((type & BSF_FUNCTION)
|
((type & BSF_FUNCTION)
|
? 'F'
|
? 'F'
|
: ((type & BSF_FILE)
|
: ((type & BSF_FILE)
|
? 'f'
|
? 'f'
|
Line 526... |
Line 537... |
|
|
asymbol *
|
asymbol *
|
_bfd_generic_make_empty_symbol (bfd *abfd)
|
_bfd_generic_make_empty_symbol (bfd *abfd)
|
{
|
{
|
bfd_size_type amt = sizeof (asymbol);
|
bfd_size_type amt = sizeof (asymbol);
|
asymbol *new = bfd_zalloc (abfd, amt);
|
asymbol *new_symbol = (asymbol *) bfd_zalloc (abfd, amt);
|
if (new)
|
if (new_symbol)
|
new->the_bfd = abfd;
|
new_symbol->the_bfd = abfd;
|
return new;
|
return new_symbol;
|
}
|
}
|
|
|
/*
|
/*
|
FUNCTION
|
FUNCTION
|
bfd_make_debug_symbol
|
bfd_make_debug_symbol
|
Line 667... |
Line 678... |
else
|
else
|
return 'U';
|
return 'U';
|
}
|
}
|
if (bfd_is_ind_section (symbol->section))
|
if (bfd_is_ind_section (symbol->section))
|
return 'I';
|
return 'I';
|
|
if (symbol->flags & BSF_GNU_INDIRECT_FUNCTION)
|
|
return 'i';
|
if (symbol->flags & BSF_WEAK)
|
if (symbol->flags & BSF_WEAK)
|
{
|
{
|
/* If weak, determine if it's specifically an object
|
/* If weak, determine if it's specifically an object
|
or non-object weak. */
|
or non-object weak. */
|
if (symbol->flags & BSF_OBJECT)
|
if (symbol->flags & BSF_OBJECT)
|
return 'V';
|
return 'V';
|
else
|
else
|
return 'W';
|
return 'W';
|
}
|
}
|
|
if (symbol->flags & BSF_GNU_UNIQUE)
|
|
return 'u';
|
if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
|
if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
|
return '?';
|
return '?';
|
|
|
if (bfd_is_abs_section (symbol->section))
|
if (bfd_is_abs_section (symbol->section))
|
c = 'a';
|
c = 'a';
|
Line 794... |
Line 809... |
if (storage < 0)
|
if (storage < 0)
|
goto error_return;
|
goto error_return;
|
if (storage == 0)
|
if (storage == 0)
|
return 0;
|
return 0;
|
|
|
syms = bfd_malloc (storage);
|
syms = (asymbol **) bfd_malloc (storage);
|
if (syms == NULL)
|
if (syms == NULL)
|
goto error_return;
|
goto error_return;
|
|
|
if (dynamic)
|
if (dynamic)
|
symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
|
symcount = bfd_canonicalize_dynamic_symtab (abfd, syms);
|
Line 861... |
Line 876... |
/* Compare two indexentry structures. This is called via qsort. */
|
/* Compare two indexentry structures. This is called via qsort. */
|
|
|
static int
|
static int
|
cmpindexentry (const void *a, const void *b)
|
cmpindexentry (const void *a, const void *b)
|
{
|
{
|
const struct indexentry *contestantA = a;
|
const struct indexentry *contestantA = (const struct indexentry *) a;
|
const struct indexentry *contestantB = b;
|
const struct indexentry *contestantB = (const struct indexentry *) b;
|
|
|
if (contestantA->val < contestantB->val)
|
if (contestantA->val < contestantB->val)
|
return -1;
|
return -1;
|
else if (contestantA->val > contestantB->val)
|
else if (contestantA->val > contestantB->val)
|
return 1;
|
return 1;
|
Line 949... |
Line 964... |
#define OTHEROFF (5)
|
#define OTHEROFF (5)
|
#define DESCOFF (6)
|
#define DESCOFF (6)
|
#define VALOFF (8)
|
#define VALOFF (8)
|
#define STABSIZE (12)
|
#define STABSIZE (12)
|
|
|
info = *pinfo;
|
info = (struct stab_find_info *) *pinfo;
|
if (info != NULL)
|
if (info != NULL)
|
{
|
{
|
if (info->stabsec == NULL || info->strsec == NULL)
|
if (info->stabsec == NULL || info->strsec == NULL)
|
{
|
{
|
/* No stabs debugging information. */
|
/* No stabs debugging information. */
|
Line 974... |
Line 989... |
int i;
|
int i;
|
char *name;
|
char *name;
|
char *function_name;
|
char *function_name;
|
bfd_size_type amt = sizeof *info;
|
bfd_size_type amt = sizeof *info;
|
|
|
info = bfd_zalloc (abfd, amt);
|
info = (struct stab_find_info *) bfd_zalloc (abfd, amt);
|
if (info == NULL)
|
if (info == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
/* FIXME: When using the linker --split-by-file or
|
/* FIXME: When using the linker --split-by-file or
|
--split-by-reloc options, it is possible for the .stab and
|
--split-by-reloc options, it is possible for the .stab and
|
Line 1007... |
Line 1022... |
: info->stabsec->size);
|
: info->stabsec->size);
|
strsize = (info->strsec->rawsize
|
strsize = (info->strsec->rawsize
|
? info->strsec->rawsize
|
? info->strsec->rawsize
|
: info->strsec->size);
|
: info->strsec->size);
|
|
|
info->stabs = bfd_alloc (abfd, stabsize);
|
info->stabs = (bfd_byte *) bfd_alloc (abfd, stabsize);
|
info->strs = bfd_alloc (abfd, strsize);
|
info->strs = (bfd_byte *) bfd_alloc (abfd, strsize);
|
if (info->stabs == NULL || info->strs == NULL)
|
if (info->stabs == NULL || info->strs == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs,
|
if (! bfd_get_section_contents (abfd, info->stabsec, info->stabs,
|
0, stabsize)
|
0, stabsize)
|
Line 1025... |
Line 1040... |
relocations against symbols defined in this object file, so
|
relocations against symbols defined in this object file, so
|
this should be no big deal. */
|
this should be no big deal. */
|
reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);
|
reloc_size = bfd_get_reloc_upper_bound (abfd, info->stabsec);
|
if (reloc_size < 0)
|
if (reloc_size < 0)
|
return FALSE;
|
return FALSE;
|
reloc_vector = bfd_malloc (reloc_size);
|
reloc_vector = (arelent **) bfd_malloc (reloc_size);
|
if (reloc_vector == NULL && reloc_size != 0)
|
if (reloc_vector == NULL && reloc_size != 0)
|
return FALSE;
|
return FALSE;
|
reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,
|
reloc_count = bfd_canonicalize_reloc (abfd, info->stabsec, reloc_vector,
|
symbols);
|
symbols);
|
if (reloc_count < 0)
|
if (reloc_count < 0)
|
Line 1122... |
Line 1137... |
return TRUE;
|
return TRUE;
|
++info->indextablesize;
|
++info->indextablesize;
|
|
|
amt = info->indextablesize;
|
amt = info->indextablesize;
|
amt *= sizeof (struct indexentry);
|
amt *= sizeof (struct indexentry);
|
info->indextable = bfd_alloc (abfd, amt);
|
info->indextable = (struct indexentry *) bfd_alloc (abfd, amt);
|
if (info->indextable == NULL)
|
if (info->indextable == NULL)
|
return FALSE;
|
return FALSE;
|
|
|
file_name = NULL;
|
file_name = NULL;
|
directory_name = NULL;
|
directory_name = NULL;
|
Line 1374... |
Line 1389... |
|| strncmp (info->filename, directory_name, dirlen) != 0
|
|| strncmp (info->filename, directory_name, dirlen) != 0
|
|| strcmp (info->filename + dirlen, file_name) != 0)
|
|| strcmp (info->filename + dirlen, file_name) != 0)
|
{
|
{
|
size_t len;
|
size_t len;
|
|
|
if (info->filename != NULL)
|
/* Don't free info->filename here. objdump and other
|
free (info->filename);
|
apps keep a copy of a previously returned file name
|
|
pointer. */
|
len = strlen (file_name) + 1;
|
len = strlen (file_name) + 1;
|
info->filename = bfd_malloc (dirlen + len);
|
info->filename = (char *) bfd_alloc (abfd, dirlen + len);
|
if (info->filename == NULL)
|
if (info->filename == NULL)
|
return FALSE;
|
return FALSE;
|
memcpy (info->filename, directory_name, dirlen);
|
memcpy (info->filename, directory_name, dirlen);
|
memcpy (info->filename + dirlen, file_name, len);
|
memcpy (info->filename + dirlen, file_name, len);
|
}
|
}
|