mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-27 22:48:57 +08:00
Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com)
* ldindr.c (add_indirect): Keep more information in the alias symbol chain. * ldlang.c (wild_doit): Don't inherit NEVER_LOAD section attribute from an input section. * ldmain.c (Q_enter_file_symbols): Common section is NEVER_LOAD by default. (Q_enter_file_symbos): Indirect symbols now are known by their section, not a special symbol flag. * ldsym.c (write_file_locals): Indirect symbols aren't local. (write_file_globals): Write the mapping for an indirect symbol. * relax.c (build_it): When forced to write a NEVER_LOAD section, fill it with zeros.
This commit is contained in:
574
ld/ldsym.c
574
ld/ldsym.c
@ -1,7 +1,7 @@
|
||||
/* All symbol handling for the linker
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
Written by Steve Chamberlain steve@cygnus.com
|
||||
|
||||
|
||||
This file is part of GLD, the Gnu Linker.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
@ -18,7 +18,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/*
|
||||
/*
|
||||
We keep a hash table of global symbols. Each entry in a hash table
|
||||
is called an ldsym_type. Each has three chains; a pointer to a
|
||||
chain of definitions for the symbol (hopefully one long), a pointer
|
||||
@ -38,7 +38,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
+----------+ +----------+ | |
|
||||
| coms | | | +---------+
|
||||
+----------+ +----------+ | udata |-----> another canonical symbol
|
||||
+---------+
|
||||
+---------+
|
||||
|
||||
|
||||
|
||||
@ -63,7 +63,7 @@ extern strip_symbols_type strip_symbols;
|
||||
extern discard_locals_type discard_locals;
|
||||
/* Head and tail of global symbol table chronological list */
|
||||
|
||||
ldsym_type *symbol_head = (ldsym_type *)NULL;
|
||||
ldsym_type *symbol_head = (ldsym_type *) NULL;
|
||||
ldsym_type **symbol_tail_ptr = &symbol_head;
|
||||
CONST char *keepsyms_file;
|
||||
int kept_syms;
|
||||
@ -76,58 +76,61 @@ struct obstack global_sym_obstack;
|
||||
|
||||
/*
|
||||
incremented for each symbol in the ldsym_type table
|
||||
no matter what flavour it is
|
||||
no matter what flavour it is
|
||||
*/
|
||||
unsigned int global_symbol_count;
|
||||
|
||||
/* IMPORTS */
|
||||
|
||||
extern boolean option_longmap ;
|
||||
extern boolean option_longmap;
|
||||
|
||||
/* LOCALS */
|
||||
#define TABSIZE 1009
|
||||
static ldsym_type *global_symbol_hash_table[TABSIZE];
|
||||
|
||||
/* Compute the hash code for symbol name KEY. */
|
||||
static
|
||||
static
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
__inline
|
||||
#endif
|
||||
|
||||
int
|
||||
DEFUN(hash_string,(key),
|
||||
CONST char *key)
|
||||
DEFUN (hash_string, (key),
|
||||
CONST char *key)
|
||||
{
|
||||
register CONST char *cp;
|
||||
register int k;
|
||||
register int l = 0;
|
||||
cp = key;
|
||||
k = 0;
|
||||
while (*cp && l < symbol_truncate) {
|
||||
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
|
||||
l++;
|
||||
}
|
||||
while (*cp && l < symbol_truncate)
|
||||
{
|
||||
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
|
||||
l++;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
static
|
||||
#ifdef __GNUC__
|
||||
__inline
|
||||
__inline
|
||||
#endif
|
||||
ldsym_type *
|
||||
DEFUN(search,(key,hashval) ,
|
||||
CONST char *key AND
|
||||
int hashval)
|
||||
ldsym_type *
|
||||
DEFUN (search, (key, hashval),
|
||||
CONST char *key AND
|
||||
int hashval)
|
||||
{
|
||||
ldsym_type *bp;
|
||||
ldsym_type *bp;
|
||||
for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
|
||||
if (! strncmp (key, bp->name, symbol_truncate)) {
|
||||
if (bp->flags & SYM_INDIRECT) {
|
||||
/* Use the symbol we're aliased to instead */
|
||||
return (ldsym_type *)(bp->sdefs_chain);
|
||||
if (!strncmp (key, bp->name, symbol_truncate))
|
||||
{
|
||||
if (bp->flags & SYM_INDIRECT)
|
||||
{
|
||||
/* Use the symbol we're aliased to instead */
|
||||
return (ldsym_type *) (bp->sdefs_chain);
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
return bp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -135,8 +138,8 @@ DEFUN(search,(key,hashval) ,
|
||||
/* Get the symbol table entry for the global symbol named KEY.
|
||||
Create one if there is none. */
|
||||
ldsym_type *
|
||||
DEFUN(ldsym_get,(key),
|
||||
CONST char *key)
|
||||
DEFUN (ldsym_get, (key),
|
||||
CONST char *key)
|
||||
{
|
||||
register int hashval;
|
||||
register ldsym_type *bp;
|
||||
@ -146,18 +149,19 @@ DEFUN(ldsym_get,(key),
|
||||
hashval = hash_string (key) % TABSIZE;
|
||||
|
||||
/* Search the bucket. */
|
||||
bp = search(key, hashval);
|
||||
if(bp) {
|
||||
return bp;
|
||||
}
|
||||
bp = search (key, hashval);
|
||||
if (bp)
|
||||
{
|
||||
return bp;
|
||||
}
|
||||
|
||||
/* Nothing was found; create a new symbol table entry. */
|
||||
|
||||
bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type)(sizeof (ldsym_type)));
|
||||
bp->srefs_chain = (asymbol **)NULL;
|
||||
bp->sdefs_chain = (asymbol **)NULL;
|
||||
bp->scoms_chain = (asymbol **)NULL;
|
||||
bp->name = obstack_copy(&global_sym_obstack, key, strlen(key)+1);
|
||||
bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type) (sizeof (ldsym_type)));
|
||||
bp->srefs_chain = (asymbol **) NULL;
|
||||
bp->sdefs_chain = (asymbol **) NULL;
|
||||
bp->scoms_chain = (asymbol **) NULL;
|
||||
bp->name = obstack_copy (&global_sym_obstack, key, strlen (key) + 1);
|
||||
bp->flags = 0;
|
||||
/* Add the entry to the bucket. */
|
||||
|
||||
@ -176,8 +180,8 @@ DEFUN(ldsym_get,(key),
|
||||
/* Like `ldsym_get' but return 0 if the symbol is not already known. */
|
||||
|
||||
ldsym_type *
|
||||
DEFUN(ldsym_get_soft,(key),
|
||||
CONST char *key)
|
||||
DEFUN (ldsym_get_soft, (key),
|
||||
CONST char *key)
|
||||
{
|
||||
register int hashval;
|
||||
/* Determine which bucket. */
|
||||
@ -185,12 +189,12 @@ DEFUN(ldsym_get_soft,(key),
|
||||
hashval = hash_string (key) % TABSIZE;
|
||||
|
||||
/* Search the bucket. */
|
||||
return search(key, hashval);
|
||||
return search (key, hashval);
|
||||
}
|
||||
|
||||
static asymbol **
|
||||
process_keepsyms (table, size)
|
||||
asymbol ** table;
|
||||
asymbol **table;
|
||||
int size;
|
||||
{
|
||||
struct obstack obstack;
|
||||
@ -279,7 +283,7 @@ process_keepsyms (table, size)
|
||||
|| s->flags & BSF_KEEP_G)
|
||||
KEEP (sym);
|
||||
}
|
||||
egress:
|
||||
egress:
|
||||
obstack_free (&obstack, start_of_obstack);
|
||||
if (ks_file)
|
||||
fclose (ks_file);
|
||||
@ -288,69 +292,73 @@ process_keepsyms (table, size)
|
||||
|
||||
static void
|
||||
list_file_locals (entry)
|
||||
lang_input_statement_type *entry;
|
||||
lang_input_statement_type *entry;
|
||||
{
|
||||
asymbol **q;
|
||||
fprintf (config.map_file, "\nLocal symbols of ");
|
||||
minfo("%I", entry);
|
||||
minfo ("%I", entry);
|
||||
fprintf (config.map_file, ":\n\n");
|
||||
if (entry->asymbols) {
|
||||
for (q = entry->asymbols; *q; q++)
|
||||
{
|
||||
asymbol *p = *q;
|
||||
/* If this is a definition,
|
||||
if (entry->asymbols)
|
||||
{
|
||||
for (q = entry->asymbols; *q; q++)
|
||||
{
|
||||
asymbol *p = *q;
|
||||
/* If this is a definition,
|
||||
update it if necessary by this file's start address. */
|
||||
if (p->flags & BSF_LOCAL)
|
||||
info(" %V %s\n",p->value, p->name);
|
||||
}
|
||||
}
|
||||
if (p->flags & BSF_LOCAL)
|
||||
info (" %V %s\n", p->value, p->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
DEFUN(print_file_stuff,(f),
|
||||
lang_input_statement_type *f)
|
||||
DEFUN (print_file_stuff, (f),
|
||||
lang_input_statement_type * f)
|
||||
{
|
||||
fprintf (config.map_file," %s\n", f->filename);
|
||||
if (f->just_syms_flag)
|
||||
{
|
||||
fprintf (config.map_file, " symbols only\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
asection *s;
|
||||
if (true || option_longmap) {
|
||||
for (s = f->the_bfd->sections;
|
||||
s != (asection *)NULL;
|
||||
s = s->next) {
|
||||
print_address(s->output_offset);
|
||||
if (s->reloc_done)
|
||||
{
|
||||
fprintf (config.map_file, " %08x 2**%2ud %s\n",
|
||||
(unsigned)bfd_get_section_size_after_reloc(s),
|
||||
s->alignment_power, s->name);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fprintf (config.map_file, " %08x 2**%2ud %s\n",
|
||||
(unsigned)bfd_get_section_size_before_reloc(s),
|
||||
s->alignment_power, s->name);
|
||||
}
|
||||
}
|
||||
fprintf (config.map_file, " %s\n", f->filename);
|
||||
if (f->just_syms_flag)
|
||||
{
|
||||
fprintf (config.map_file, " symbols only\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s = f->the_bfd->sections;
|
||||
s != (asection *)NULL;
|
||||
s = s->next) {
|
||||
fprintf(config.map_file, "%s ", s->name);
|
||||
print_address(s->output_offset);
|
||||
fprintf(config.map_file, "(%x)", (unsigned)bfd_get_section_size_after_reloc(s));
|
||||
}
|
||||
fprintf(config.map_file, "hex \n");
|
||||
else
|
||||
{
|
||||
asection *s;
|
||||
if (true || option_longmap)
|
||||
{
|
||||
for (s = f->the_bfd->sections;
|
||||
s != (asection *) NULL;
|
||||
s = s->next)
|
||||
{
|
||||
print_address (s->output_offset);
|
||||
if (s->reloc_done)
|
||||
{
|
||||
fprintf (config.map_file, " %08x 2**%2ud %s\n",
|
||||
(unsigned) bfd_get_section_size_after_reloc (s),
|
||||
s->alignment_power, s->name);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
fprintf (config.map_file, " %08x 2**%2ud %s\n",
|
||||
(unsigned) bfd_get_section_size_before_reloc (s),
|
||||
s->alignment_power, s->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (s = f->the_bfd->sections;
|
||||
s != (asection *) NULL;
|
||||
s = s->next)
|
||||
{
|
||||
fprintf (config.map_file, "%s ", s->name);
|
||||
print_address (s->output_offset);
|
||||
fprintf (config.map_file, "(%x)", (unsigned) bfd_get_section_size_after_reloc (s));
|
||||
}
|
||||
fprintf (config.map_file, "hex \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf (config.map_file, "\n");
|
||||
}
|
||||
|
||||
@ -359,155 +367,177 @@ ldsym_print_symbol_table ()
|
||||
{
|
||||
fprintf (config.map_file, "**FILES**\n\n");
|
||||
|
||||
lang_for_each_file(print_file_stuff);
|
||||
lang_for_each_file (print_file_stuff);
|
||||
|
||||
fprintf(config.map_file, "**GLOBAL SYMBOLS**\n\n");
|
||||
fprintf(config.map_file, "offset section offset symbol\n");
|
||||
fprintf (config.map_file, "**GLOBAL SYMBOLS**\n\n");
|
||||
fprintf (config.map_file, "offset section offset symbol\n");
|
||||
{
|
||||
register ldsym_type *sp;
|
||||
|
||||
for (sp = symbol_head; sp; sp = sp->next)
|
||||
{
|
||||
if (sp->flags & SYM_INDIRECT) {
|
||||
fprintf(config.map_file,"indirect %s to %s\n",
|
||||
sp->name, (((ldsym_type *)(sp->sdefs_chain))->name));
|
||||
}
|
||||
else {
|
||||
if (sp->sdefs_chain)
|
||||
{
|
||||
asymbol *defsym = *(sp->sdefs_chain);
|
||||
asection *defsec = bfd_get_section(defsym);
|
||||
print_address(defsym->value);
|
||||
if (defsec)
|
||||
{
|
||||
fprintf(config.map_file, " %-10s",
|
||||
bfd_section_name(output_bfd,
|
||||
defsec));
|
||||
print_space();
|
||||
print_address(defsym->value+defsec->vma);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(config.map_file, " .......");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (sp->scoms_chain) {
|
||||
fprintf(config.map_file, "common ");
|
||||
print_address((*(sp->scoms_chain))->value);
|
||||
fprintf(config.map_file, " %s ",sp->name);
|
||||
if (sp->flags & SYM_INDIRECT)
|
||||
{
|
||||
fprintf (config.map_file, "indirect %s to %s\n",
|
||||
sp->name, (((ldsym_type *) (sp->sdefs_chain))->name));
|
||||
}
|
||||
else if (sp->sdefs_chain) {
|
||||
fprintf(config.map_file, " %s ",sp->name);
|
||||
}
|
||||
else {
|
||||
fprintf(config.map_file, "undefined ");
|
||||
fprintf(config.map_file, "%s ",sp->name);
|
||||
else
|
||||
{
|
||||
if (sp->sdefs_chain)
|
||||
{
|
||||
asymbol *defsym = *(sp->sdefs_chain);
|
||||
asection *defsec = bfd_get_section (defsym);
|
||||
print_address (defsym->value);
|
||||
if (defsec)
|
||||
{
|
||||
fprintf (config.map_file, " %-10s",
|
||||
bfd_section_name (output_bfd,
|
||||
defsec));
|
||||
print_space ();
|
||||
print_address (defsym->value + defsec->vma);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (config.map_file, " .......");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (sp->scoms_chain)
|
||||
{
|
||||
fprintf (config.map_file, "common ");
|
||||
print_address ((*(sp->scoms_chain))->value);
|
||||
fprintf (config.map_file, " %s ", sp->name);
|
||||
}
|
||||
else if (sp->sdefs_chain)
|
||||
{
|
||||
fprintf (config.map_file, " %s ", sp->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (config.map_file, "undefined ");
|
||||
fprintf (config.map_file, "%s ", sp->name);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
print_nl();
|
||||
print_nl ();
|
||||
|
||||
}
|
||||
}
|
||||
if (option_longmap) {
|
||||
lang_for_each_file(list_file_locals);
|
||||
}
|
||||
if (option_longmap)
|
||||
{
|
||||
lang_for_each_file (list_file_locals);
|
||||
}
|
||||
}
|
||||
|
||||
extern lang_output_section_statement_type *create_object_symbols;
|
||||
extern char lprefix;
|
||||
static asymbol **
|
||||
write_file_locals(output_buffer)
|
||||
asymbol **output_buffer;
|
||||
write_file_locals (output_buffer)
|
||||
asymbol **output_buffer;
|
||||
{
|
||||
LANG_FOR_EACH_INPUT_STATEMENT(entry)
|
||||
LANG_FOR_EACH_INPUT_STATEMENT (entry)
|
||||
{
|
||||
/* Run trough the symbols and work out what to do with them */
|
||||
unsigned int i;
|
||||
|
||||
/* Add one for the filename symbol if needed */
|
||||
if (create_object_symbols
|
||||
!= (lang_output_section_statement_type *)NULL) {
|
||||
asection *s;
|
||||
for (s = entry->the_bfd->sections;
|
||||
s != (asection *)NULL;
|
||||
s = s->next) {
|
||||
if (s->output_section == create_object_symbols->bfd_section) {
|
||||
/* Add symbol to this section */
|
||||
asymbol * newsym =
|
||||
(asymbol *)bfd_make_empty_symbol(entry->the_bfd);
|
||||
newsym->name = entry->local_sym_name;
|
||||
/* The symbol belongs to the output file's text section */
|
||||
if (create_object_symbols
|
||||
!= (lang_output_section_statement_type *) NULL)
|
||||
{
|
||||
asection *s;
|
||||
for (s = entry->the_bfd->sections;
|
||||
s != (asection *) NULL;
|
||||
s = s->next)
|
||||
{
|
||||
if (s->output_section == create_object_symbols->bfd_section)
|
||||
{
|
||||
/* Add symbol to this section */
|
||||
asymbol *newsym =
|
||||
(asymbol *) bfd_make_empty_symbol (entry->the_bfd);
|
||||
newsym->name = entry->local_sym_name;
|
||||
/* The symbol belongs to the output file's text section */
|
||||
|
||||
/* The value is the start of this section in the output file*/
|
||||
newsym->value = 0;
|
||||
/* FIXME: Usurping BSF_KEEP_G flag, since it's defined as
|
||||
/* The value is the start of this section in the output file*/
|
||||
newsym->value = 0;
|
||||
/* FIXME: Usurping BSF_KEEP_G flag, since it's defined as
|
||||
"used by the linker" and I can't find any other code that
|
||||
uses it. Should be a cleaner way of doing this (like an
|
||||
"application flags" field in the symbol structure?). */
|
||||
newsym->flags = BSF_LOCAL | BSF_KEEP_G;
|
||||
newsym->section = s;
|
||||
*output_buffer++ = newsym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < entry->symbol_count; i++)
|
||||
{
|
||||
asymbol *p = entry->asymbols[i];
|
||||
/* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
|
||||
|
||||
if (p->section == 0)
|
||||
p->section = &bfd_abs_section;
|
||||
if (flag_is_global(p->flags) )
|
||||
{
|
||||
/* We are only interested in outputting
|
||||
globals at this stage in special circumstances */
|
||||
if (bfd_asymbol_bfd(p) == entry->the_bfd
|
||||
&& flag_is_not_at_end(p->flags)) {
|
||||
/* And this is one of them */
|
||||
*(output_buffer++) = p;
|
||||
p->flags |= BSF_KEEP;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (flag_is_debugger(p->flags))
|
||||
{
|
||||
/* Only keep the debugger symbols if no stripping required */
|
||||
if (strip_symbols == STRIP_NONE) {
|
||||
*output_buffer++ = p;
|
||||
newsym->flags = BSF_LOCAL | BSF_KEEP_G;
|
||||
newsym->section = s;
|
||||
*output_buffer++ = newsym;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < entry->symbol_count; i++)
|
||||
{
|
||||
asymbol *p = entry->asymbols[i];
|
||||
/* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
|
||||
|
||||
if (p->section == 0)
|
||||
p->section = &bfd_abs_section;
|
||||
if (flag_is_global (p->flags))
|
||||
{
|
||||
/* We are only interested in outputting
|
||||
globals at this stage in special circumstances */
|
||||
if (bfd_asymbol_bfd (p) == entry->the_bfd
|
||||
&& flag_is_not_at_end (p->flags))
|
||||
{
|
||||
/* And this is one of them */
|
||||
*(output_buffer++) = p;
|
||||
p->flags |= BSF_KEEP;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (p->section == &bfd_ind_section)
|
||||
{
|
||||
/* Dont think about indirect symbols */
|
||||
}
|
||||
else if (flag_is_debugger (p->flags))
|
||||
{
|
||||
/* Only keep the debugger symbols if no stripping required */
|
||||
if (strip_symbols == STRIP_NONE)
|
||||
{
|
||||
*output_buffer++ = p;
|
||||
}
|
||||
}
|
||||
else if (p->section == &bfd_und_section
|
||||
|| bfd_is_com_section (p->section))
|
||||
{
|
||||
/* These must be global. */
|
||||
}
|
||||
else if (flag_is_ordinary_local (p->flags))
|
||||
{
|
||||
if (discard_locals == DISCARD_ALL)
|
||||
{
|
||||
}
|
||||
else if (discard_locals == DISCARD_L &&
|
||||
(p->name[0] == lprefix))
|
||||
{
|
||||
}
|
||||
else if (p->flags == BSF_WARNING)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
*output_buffer++ = p;
|
||||
}
|
||||
}
|
||||
else if (p->flags & BSF_CTOR)
|
||||
{
|
||||
/* Throw it away */
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL ();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (p->section == &bfd_und_section
|
||||
|| bfd_is_com_section (p->section))
|
||||
{
|
||||
/* These must be global. */
|
||||
}
|
||||
else if (flag_is_ordinary_local(p->flags))
|
||||
{
|
||||
if (discard_locals == DISCARD_ALL)
|
||||
{ }
|
||||
else if (discard_locals == DISCARD_L &&
|
||||
(p->name[0] == lprefix))
|
||||
{ }
|
||||
else if (p->flags == BSF_WARNING)
|
||||
{ }
|
||||
else
|
||||
{ *output_buffer++ = p; }
|
||||
}
|
||||
else if (p->flags & BSF_CTOR) {
|
||||
/* Throw it away */
|
||||
}
|
||||
else
|
||||
{
|
||||
FAIL();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -516,55 +546,79 @@ asymbol **output_buffer;
|
||||
|
||||
|
||||
static asymbol **
|
||||
write_file_globals(symbol_table)
|
||||
asymbol **symbol_table;
|
||||
write_file_globals (symbol_table)
|
||||
asymbol **symbol_table;
|
||||
{
|
||||
FOR_EACH_LDSYM(sp)
|
||||
{
|
||||
if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **)NULL) {
|
||||
FOR_EACH_LDSYM (sp)
|
||||
{
|
||||
if (sp->flags & SYM_INDIRECT)
|
||||
{
|
||||
asymbol *bufp = (*(sp->srefs_chain));
|
||||
ldsym_type *aliased_to = (ldsym_type *) (sp->sdefs_chain);
|
||||
if (aliased_to->sdefs_chain)
|
||||
{
|
||||
asymbol *p = aliased_to->sdefs_chain[0];
|
||||
bufp->value = p->value;
|
||||
bufp->section = p->section;
|
||||
bufp->flags = p->flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufp->value = 0;
|
||||
bufp->flags = 0;
|
||||
bufp->section = &bfd_und_section;
|
||||
}
|
||||
*symbol_table++ = bufp;
|
||||
}
|
||||
else if ((sp->flags & SYM_INDIRECT) == 0 && sp->sdefs_chain != (asymbol **) NULL)
|
||||
{
|
||||
asymbol *bufp = (*(sp->sdefs_chain));
|
||||
|
||||
if ((bufp->flags & BSF_KEEP) ==0) {
|
||||
ASSERT(bufp != (asymbol *)NULL);
|
||||
if ((bufp->flags & BSF_KEEP) == 0)
|
||||
{
|
||||
ASSERT (bufp != (asymbol *) NULL);
|
||||
|
||||
bufp->name = sp->name;
|
||||
bufp->name = sp->name;
|
||||
|
||||
if (sp->scoms_chain != (asymbol **)NULL)
|
||||
if (sp->scoms_chain != (asymbol **) NULL)
|
||||
|
||||
{
|
||||
/*
|
||||
{
|
||||
/*
|
||||
defined as common but not allocated, this happens
|
||||
only with -r and not -d, write out a common
|
||||
definition
|
||||
*/
|
||||
bufp = *(sp->scoms_chain);
|
||||
}
|
||||
*symbol_table++ = bufp;
|
||||
}
|
||||
bufp = *(sp->scoms_chain);
|
||||
}
|
||||
*symbol_table++ = bufp;
|
||||
}
|
||||
}
|
||||
else if (sp->scoms_chain != (asymbol **)NULL) {
|
||||
else if (sp->scoms_chain != (asymbol **) NULL)
|
||||
{
|
||||
/* This symbol is a common - just output */
|
||||
asymbol *bufp = (*(sp->scoms_chain));
|
||||
*symbol_table++ = bufp;
|
||||
}
|
||||
else if (sp->srefs_chain != (asymbol **)NULL) {
|
||||
else if (sp->srefs_chain != (asymbol **) NULL)
|
||||
{
|
||||
/* This symbol is undefined but has a reference */
|
||||
asymbol *bufp = (*(sp->srefs_chain));
|
||||
*symbol_table++ = bufp;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
/*
|
||||
This symbol has neither defs nor refs, it must have come
|
||||
from the command line, since noone has used it it has no
|
||||
data attatched, so we'll ignore it
|
||||
data attatched, so we'll ignore it
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
return symbol_table;
|
||||
}
|
||||
|
||||
void
|
||||
ldsym_write()
|
||||
ldsym_write ()
|
||||
{
|
||||
if (keepsyms_file != 0
|
||||
&& strip_symbols != STRIP_SOME)
|
||||
@ -572,48 +626,50 @@ ldsym_write()
|
||||
info ("%P `-retain-symbols-file' overrides `-s' and `-S'\n");
|
||||
strip_symbols = STRIP_SOME;
|
||||
}
|
||||
if (strip_symbols != STRIP_ALL) {
|
||||
/* We know the maximum size of the symbol table -
|
||||
if (strip_symbols != STRIP_ALL)
|
||||
{
|
||||
/* We know the maximum size of the symbol table -
|
||||
it's the size of all the global symbols ever seen +
|
||||
the size of all the symbols from all the files +
|
||||
the number of files (for the per file symbols)
|
||||
+1 (for the null at the end)
|
||||
*/
|
||||
extern unsigned int total_files_seen;
|
||||
extern unsigned int total_symbols_seen;
|
||||
extern unsigned int total_files_seen;
|
||||
extern unsigned int total_symbols_seen;
|
||||
|
||||
asymbol ** symbol_table = (asymbol **)
|
||||
ldmalloc ((bfd_size_type)(global_symbol_count +
|
||||
total_files_seen +
|
||||
total_symbols_seen + 1) * sizeof (asymbol *));
|
||||
asymbol ** tablep = write_file_locals(symbol_table);
|
||||
asymbol **symbol_table = (asymbol **)
|
||||
ldmalloc ((bfd_size_type) (global_symbol_count +
|
||||
total_files_seen +
|
||||
total_symbols_seen + 1) * sizeof (asymbol *));
|
||||
asymbol **tablep = write_file_locals (symbol_table);
|
||||
|
||||
tablep = write_file_globals(tablep);
|
||||
tablep = process_keepsyms (symbol_table, tablep - symbol_table);
|
||||
tablep = write_file_globals (tablep);
|
||||
tablep = process_keepsyms (symbol_table, tablep - symbol_table);
|
||||
|
||||
*tablep = (asymbol *)NULL;
|
||||
bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table));
|
||||
}
|
||||
*tablep = (asymbol *) NULL;
|
||||
bfd_set_symtab (output_bfd, symbol_table, (unsigned) (tablep - symbol_table));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
return true if the supplied symbol name is not in the
|
||||
return true if the supplied symbol name is not in the
|
||||
linker symbol table
|
||||
*/
|
||||
boolean
|
||||
DEFUN(ldsym_undefined,(sym),
|
||||
CONST char *sym)
|
||||
boolean
|
||||
DEFUN (ldsym_undefined, (sym),
|
||||
CONST char *sym)
|
||||
{
|
||||
ldsym_type *from_table = ldsym_get_soft(sym);
|
||||
if (from_table != (ldsym_type *)NULL)
|
||||
{
|
||||
if (from_table->sdefs_chain != (asymbol **)NULL) return false;
|
||||
}
|
||||
ldsym_type *from_table = ldsym_get_soft (sym);
|
||||
if (from_table != (ldsym_type *) NULL)
|
||||
{
|
||||
if (from_table->sdefs_chain != (asymbol **) NULL)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
DEFUN_VOID(ldsym_init)
|
||||
DEFUN_VOID (ldsym_init)
|
||||
{
|
||||
obstack_begin(&global_sym_obstack, 20000);
|
||||
obstack_begin (&global_sym_obstack, 20000);
|
||||
}
|
||||
|
Reference in New Issue
Block a user