output symbols, the application provides BFD with a table of
pointers to pointers to <<asymbol>>s. This allows applications
like the linker to output a symbol as it was read, since the ``behind
- the scenes'' information will be still available.
+ the scenes'' information will be still available.
@menu
@* Reading Symbols::
@* Writing Symbols::
allocating storage, and the actual reading process. This is an
excerpt from an application which reads the symbol table:
-| unsigned int storage_needed;
+| long storage_needed;
| asymbol **symbol_table;
-| unsigned int number_of_symbols;
-| unsigned int i;
-|
-| storage_needed = get_symtab_upper_bound (abfd);
-|
+| long number_of_symbols;
+| long i;
+|
+| storage_needed = bfd_get_symtab_upper_bound (abfd);
+|
+| if (storage_needed < 0)
+| FAIL
+|
| if (storage_needed == 0) {
| return ;
| }
-| symbol_table = (asymbol **) bfd_xmalloc (storage_needed);
+| symbol_table = (asymbol **) xmalloc (storage_needed);
| ...
-| number_of_symbols =
-| bfd_canonicalize_symtab (abfd, symbol_table);
-|
+| number_of_symbols =
+| bfd_canonicalize_symtab (abfd, symbol_table);
+|
+| if (number_of_symbols < 0)
+| FAIL
+|
| for (i = 0; i < number_of_symbols; i++) {
| process_symbol (symbol_table[i]);
| }
example showing the creation of a symbol table with only one element:
| #include "bfd.h"
-| main()
+| main()
| {
| bfd *abfd;
| asymbol *ptrs[2];
| asymbol *new;
-|
+|
| abfd = bfd_openw("foo","a.out-sunos-big");
| bfd_set_format(abfd, bfd_object);
| new = bfd_make_empty_symbol(abfd);
| new->section = bfd_make_section_old_way(abfd, ".text");
| new->flags = BSF_GLOBAL;
| new->value = 0x12345;
-|
+|
| ptrs[0] = new;
| ptrs[1] = (asymbol *)0;
-|
+|
| bfd_set_symtab(abfd, ptrs, 1);
| bfd_close(abfd);
| }
-|
-| ./makesym
+|
+| ./makesym
| nm foo
| 00012345 A dummy_symbol
instance, the <<a.out>> object format does not allow an
arbitary number of sections. A symbol pointing to a section
which is not one of <<.text>>, <<.data>> or <<.bss>> cannot
- be described.
+ be described.
*/
CODE_FRAGMENT
.
-.typedef struct symbol_cache_entry
+.typedef struct symbol_cache_entry
.{
. {* A pointer to the BFD which owns the symbol. This information
. is necessary so that a back end can work out what additional
. for ELF STT_FILE symbols. *}
.#define BSF_FILE 0x4000
.
+. {* Symbol is from dynamic linking information. *}
+.#define BSF_DYNAMIC 0x8000
+.
. 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
-. sections for undefined and absolute symbols *}
+. sections for undefined and absolute symbols. *}
. struct sec *section;
.
-. {* Back end special data. This is being phased out in favour
-. of making this a union. *}
-. PTR udata;
+. {* Back end special data. *}
+. union
+. {
+. PTR p;
+. bfd_vma i;
+. } udata;
.
.} asymbol;
*/
#include "libbfd.h"
#include "aout/stab_gnu.h"
-
+
/*
DOCDD
INODE
/*
FUNCTION
- get_symtab_upper_bound
+ bfd_get_symtab_upper_bound
DESCRIPTION
Return the number of bytes required to store a vector of pointers
to <<asymbols>> for all the symbols in the BFD @var{abfd},
including a terminal NULL pointer. If there are no symbols in
- the BFD, then return 0.
+ the BFD, then return 0. If an error occurs, return -1.
-.#define get_symtab_upper_bound(abfd) \
-. BFD_SEND (abfd, _get_symtab_upper_bound, (abfd))
+.#define bfd_get_symtab_upper_bound(abfd) \
+. BFD_SEND (abfd, _bfd_get_symtab_upper_bound, (abfd))
*/
+/*
+FUNCTION
+ bfd_is_local_label
+
+SYNOPSIS
+ boolean bfd_is_local_label(bfd *abfd, asymbol *sym);
+
+DESCRIPTION
+ Return true if the given symbol @var{sym} in the BFD @var{abfd} is
+ a compiler generated local label, else return false.
+.#define bfd_is_local_label(abfd, sym) \
+. BFD_SEND (abfd, _bfd_is_local_label,(abfd, sym))
+*/
+
/*
FUNCTION
bfd_canonicalize_symtab
DESCRIPTION
Read the symbols from the BFD @var{abfd}, and fills in
the vector @var{location} with pointers to the symbols and
- a trailing NULL.
+ a trailing NULL.
Return the actual number of symbol pointers, not
including the NULL.
asymbol **location;
unsigned int symcount;
{
- if ((abfd->format != bfd_object) || (bfd_read_p (abfd))) {
- bfd_error = invalid_operation;
- return false;
- }
+ if ((abfd->format != bfd_object) || (bfd_read_p (abfd)))
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ return false;
+ }
bfd_get_outsymbols (abfd) = location;
bfd_get_symcount (abfd) = symcount;
stream @var{file}.
*/
void
-DEFUN(bfd_print_symbol_vandf,(file, symbol),
-FILE *file AND
-asymbol *symbol)
+bfd_print_symbol_vandf (arg, symbol)
+ PTR arg;
+ asymbol *symbol;
{
+ FILE *file = (FILE *) arg;
flagword type = symbol->flags;
- if (symbol->section != (asection *)NULL)
- {
- fprintf_vma(file, symbol->value+symbol->section->vma);
- }
- else
- {
- fprintf_vma(file, symbol->value);
- }
- fprintf(file," %c%c%c%c%c%c%c",
- (type & BSF_LOCAL) ? 'l':' ',
- (type & BSF_GLOBAL) ? 'g' : ' ',
- (type & BSF_WEAK) ? 'w' : ' ',
- (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
- (type & BSF_WARNING) ? 'W' : ' ',
- (type & BSF_INDIRECT) ? 'I' : ' ',
- (type & BSF_DEBUGGING) ? 'd' :' ');
-
+ if (symbol->section != (asection *) NULL)
+ {
+ fprintf_vma (file, symbol->value + symbol->section->vma);
+ }
+ else
+ {
+ fprintf_vma (file, symbol->value);
+ }
+
+ /* This presumes that a symbol can not be both BSF_DEBUGGING and
+ BSF_DYNAMIC, nor both BSF_FUNCTION and BSF_FILE. */
+ fprintf (file, " %c%c%c%c%c%c%c",
+ ((type & BSF_LOCAL)
+ ? (type & BSF_GLOBAL) ? '!' : 'l'
+ : (type & BSF_GLOBAL) ? 'g' : ' '),
+ (type & BSF_WEAK) ? 'w' : ' ',
+ (type & BSF_CONSTRUCTOR) ? 'C' : ' ',
+ (type & BSF_WARNING) ? 'W' : ' ',
+ (type & BSF_INDIRECT) ? 'I' : ' ',
+ (type & BSF_DEBUGGING) ? 'd' : (type & BSF_DYNAMIC) ? 'D' : ' ',
+ (type & BSF_FUNCTION) ? 'F' : (type & BSF_FILE) ? 'f' : ' ');
}
/* Map section names to POSIX/BSD single-character symbol types.
This table is probably incomplete. It is sorted for convenience of
adding entries. Since it is so short, a linear search is used. */
-static CONST struct section_to_type stt[] = {
+static CONST struct section_to_type stt[] =
+{
{"*DEBUG*", 'N'},
{".bss", 'b'},
{".data", 'd'},
- {".sbss", 's'}, /* Small BSS (uninitialized data) */
- {".scommon", 'c'}, /* Small common */
- {".sdata", 'g'}, /* Small initialized data */
+ {".rdata", 'r'}, /* Read only data. */
+ {".rodata", 'r'}, /* Read only data. */
+ {".sbss", 's'}, /* Small BSS (uninitialized data). */
+ {".scommon", 'c'}, /* Small common. */
+ {".sdata", 'g'}, /* Small initialized data. */
{".text", 't'},
{0, 0}
};
/* Return the single-character symbol type corresponding to
- section S, or '?' for an unknown COFF section. */
+ section S, or '?' for an unknown COFF section.
+
+ Check for any leading string which matches, so .text5 returns
+ 't' as well as .text */
static char
coff_section_type (s)
{
CONST struct section_to_type *t;
- for (t = &stt[0]; t->section; t++)
- if (!strcmp (s, t->section))
+ for (t = &stt[0]; t->section; t++)
+ if (!strncmp (s, t->section, strlen (t->section)))
return t->type;
+
return '?';
}
int bfd_decode_symclass(asymbol *symbol);
*/
int
-DEFUN(bfd_decode_symclass,(symbol),
-asymbol *symbol)
+bfd_decode_symclass (symbol)
+ asymbol *symbol;
{
char c;
if (bfd_is_com_section (symbol->section))
return 'C';
- if (symbol->section == &bfd_und_section)
+ if (bfd_is_und_section (symbol->section))
return 'U';
- if (symbol->section == &bfd_ind_section)
+ if (bfd_is_ind_section (symbol->section))
return 'I';
- if (!(symbol->flags & (BSF_GLOBAL|BSF_LOCAL)))
+ if (symbol->flags & BSF_WEAK)
+ return 'W';
+ if (!(symbol->flags & (BSF_GLOBAL | BSF_LOCAL)))
return '?';
- if (symbol->section == &bfd_abs_section)
+ if (bfd_is_abs_section (symbol->section))
c = 'a';
else if (symbol->section)
c = coff_section_type (symbol->section->name);
return c;
/* We don't have to handle these cases just yet, but we will soon:
- N_SETV: 'v';
- N_SETA: 'l';
+ N_SETV: 'v';
+ N_SETA: 'l';
N_SETT: 'x';
N_SETD: 'z';
N_SETB: 's';
*/
void
-DEFUN(bfd_symbol_info,(symbol, ret),
- asymbol *symbol AND
- symbol_info *ret)
+bfd_symbol_info (symbol, ret)
+ asymbol *symbol;
+ symbol_info *ret;
{
ret->type = bfd_decode_symclass (symbol);
if (ret->type != 'U')
- ret->value = symbol->value+symbol->section->vma;
+ ret->value = symbol->value + symbol->section->vma;
else
ret->value = 0;
ret->name = symbol->name;
}
void
-bfd_symbol_is_absolute()
+bfd_symbol_is_absolute ()
{
- abort();
+ abort ();
}
+/*
+FUNCTION
+ bfd_copy_private_symbol_data
+
+SYNOPSIS
+ boolean bfd_copy_private_symbol_data(bfd *ibfd, asymbol *isym, bfd *obfd, asymbol *osym);
+
+DESCRIPTION
+ Copy private symbol information from @var{isym} in the BFD
+ @var{ibfd} to the symbol @var{osym} in the BFD @var{obfd}.
+ Return <<true>> on success, <<false>> on error. Possible error
+ returns are:
+
+ o <<bfd_error_no_memory>> -
+ Not enough memory exists to create private data for @var{osec}.
+
+.#define bfd_copy_private_symbol_data(ibfd, isymbol, obfd, osymbol) \
+. BFD_SEND (ibfd, _bfd_copy_private_symbol_data, \
+. (ibfd, isymbol, obfd, osymbol))
+
+*/