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:
Steve Chamberlain 1993-03-30 17:49:00 +00:00
parent 21c7770362
commit 29f33467f2
6 changed files with 779 additions and 638 deletions

View file

@ -1,3 +1,21 @@
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.
Tue Mar 23 13:24:10 1993 Jeffrey Osier (jeffrey@fowanton.cygnus.com)
* ld.texinfo: changes for q1
Tue Mar 23 00:13:29 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
* Makefile.in: add dvi target, define & use TEXI2DVI, add installcheck

View file

@ -1,6 +1,29 @@
/* ldindr.c
Handle indirect symbols.
Copyright (C) 1991 Free Software Foundation, Inc.
Written by Steve Chamberlain steve@cygnus.com
This file is part of GLD, the Gnu Linker.
GLD is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GLD is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GLD; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
An indirect symbol is where a global symbol in one file say's that
all refs like it should be turned into refs of the symbol pointed
at by the value of the indirect symbol.
@ -93,8 +116,8 @@ asymbol **ptr)
{
refize(new, new->scoms_chain);
}
lgs->sdefs_chain = (asymbol **)new;
lgs->sdefs_chain = (asymbol **)new;
lgs->srefs_chain = ptr;
}

View file

@ -61,7 +61,6 @@ static lang_statement_list_type lang_output_section_statement;
static CONST char *current_target;
static CONST char *output_target;
static size_t longest_section_name = 8;
static asection common_section;
static section_userdata_type common_section_userdata;
static lang_statement_list_type statement_list;
@ -612,11 +611,17 @@ DEFUN (wild_doit, (ptr, section, output, file),
new->section = section;
new->ifile = file;
section->output_section = output->bfd_section;
section->output_section->flags |= section->flags;
/* Be selective about what the output section inherits from the
input section */
section->output_section->flags |= section->flags & ~SEC_NEVER_LOAD;
if (!output->loadable)
{
/* Turn of load flag */
/* Turn off load flag */
output->bfd_section->flags &= ~SEC_LOAD;
output->bfd_section->flags |= SEC_NEVER_LOAD;
}
if (section->alignment_power > output->bfd_section->alignment_power)
{
@ -653,10 +658,14 @@ DEFUN (wild_section, (ptr, section, file, output),
{
/* Do the creation to all sections in the file */
for (s = file->the_bfd->sections; s != (asection *) NULL; s = s->next)
{
/* except for bss */
if ((s->flags & SEC_IS_COMMON) == 0)
{
wild_doit (&ptr->children, s, output, file);
}
}
}
else
{
/* Do the creation to the named section only */
@ -729,6 +738,8 @@ DEFUN (wild, (s, section, file, target, output),
{
wild_section (s, section, f, output);
}
/* Once more for the script file */
wild_section(s, section, script_file, output);
}
else
{
@ -947,13 +958,20 @@ DEFUN_VOID (lang_create_output_section_statements)
static void
DEFUN_VOID (lang_init_script_file)
{
script_file = lang_add_input_file ("script file",
script_file = lang_add_input_file ("command line",
lang_input_file_is_fake_enum,
(char *) NULL);
script_file->the_bfd = bfd_create ("script file", output_bfd);
script_file->the_bfd = bfd_create ("command line", output_bfd);
script_file->symbol_count = 0;
script_file->the_bfd->sections = output_bfd->sections;
abs_output_section = lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
script_file->the_bfd->sections = 0;
/* The user data of a bfd points to the input statement attatched */
script_file->the_bfd->usrdata = (void *)script_file;
script_file->common_section =
bfd_make_section(script_file->the_bfd,"COMMON");
abs_output_section =
lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
abs_output_section->bfd_section = &bfd_abs_section;
@ -1876,16 +1894,18 @@ DEFUN_VOID (lang_relocate_globals)
}
if (it != (asymbol *) NULL)
{
asymbol **prev = 0;
asymbol **ptr = lgs->srefs_chain;;
if (lgs->flags & SYM_WARNING)
{
produce_warnings (lgs, it);
}
while (ptr != (asymbol **) NULL)
while (ptr != (asymbol **) NULL
&& ptr != prev)
{
asymbol *ref = *ptr;
prev = ptr;
*ptr = it;
ptr = (asymbol **) (ref->udata);
}
@ -1954,9 +1974,6 @@ DEFUN_VOID (lang_check)
file != (lang_statement_union_type *) NULL;
file = file->input_statement.next)
{
unsigned long ldfile_new_output_machine = 0;
enum bfd_architecture ldfile_new_output_architecture = bfd_arch_unknown;
input_bfd = file->input_statement.the_bfd;
input_machine = bfd_get_mach (input_bfd);
@ -2051,15 +2068,35 @@ DEFUN_VOID (lang_common)
}
if (config.sort_common == false || align == power)
{
bfd *symbfd;
/* Change from a common symbol into a definition of
a symbol */
lgs->sdefs_chain = lgs->scoms_chain;
lgs->scoms_chain = (asymbol **) NULL;
commons_pending--;
/* Point to the correct common section */
symbfd = bfd_asymbol_bfd (com);
if (com->section == &bfd_com_section)
com->section =
((lang_input_statement_type *)
(com->the_bfd->usrdata))->common_section;
((lang_input_statement_type *) symbfd->usrdata)
->common_section;
else
{
CONST char *name;
asection *newsec;
name = bfd_get_section_name (symbfd,
com->section);
newsec = bfd_get_section_by_name (symbfd,
name);
/* BFD backend must provide this section. */
if (newsec == (asection *) NULL)
einfo ("%P%F: No output section %s", name);
com->section = newsec;
}
/* Fix the size of the common section */
com->section->_raw_size =
@ -2077,13 +2114,13 @@ DEFUN_VOID (lang_common)
com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON;
com->value = com->section->_raw_size;
if (write_map)
if (write_map && config.map_file)
{
fprintf (config.map_file, "Allocating common %s: %x at %x %s\n",
lgs->name,
(unsigned) size,
(unsigned) com->value,
com->the_bfd->filename);
bfd_asymbol_bfd(com)->filename);
}
com->section->_raw_size += size;
@ -2274,6 +2311,7 @@ static int topower(x)
if (i >= x) return l;
i<<=1;
}
return 0;
}
void
DEFUN (lang_enter_output_section_statement,
@ -2313,7 +2351,7 @@ DEFUN (lang_enter_output_section_statement,
os->loadable = 0;
else
os->loadable = 1;
os->block_value = block_value;
os->block_value = block_value ? block_value : 1;
stat_ptr = &os->children;
os->subsection_alignment = topower(
@ -2364,12 +2402,10 @@ DEFUN (create_symbol, (name, flags, section),
/* Add this definition to script file */
asymbol *def = (asymbol *) bfd_make_empty_symbol (script_file->the_bfd);
def->name = buystring (name);
def->udata = 0;
def->flags = flags;
def->section = section;
*def_ptr = def;
Q_enter_global_ref (def_ptr, name);
return def;
@ -2401,9 +2437,6 @@ DEFUN_VOID (lang_process)
current_target = default_target;
lang_for_each_statement (open_input_bfds);
common_section.userdata = (PTR) & common_section_userdata;
/* Run through the contours of the script and attatch input sections
to the correct output sections
*/

View file

@ -437,18 +437,18 @@ DEFUN (Q_enter_global_ref, (nlist_p, name),
/* Multiple definition */
asymbol *sy = *(sp->sdefs_chain);
lang_input_statement_type *stat =
(lang_input_statement_type *) bfd_asymbol_bfd(sy)->usrdata;
(lang_input_statement_type *) bfd_asymbol_bfd (sy)->usrdata;
lang_input_statement_type *stat1 =
(lang_input_statement_type *) bfd_asymbol_bfd(sym)->usrdata;
(lang_input_statement_type *) bfd_asymbol_bfd (sym)->usrdata;
asymbol **stat1_symbols = stat1 ? stat1->asymbols : 0;
asymbol **stat_symbols = stat ? stat->asymbols : 0;
multiple_def_count++;
einfo ("%X%C: multiple definition of `%T'\n",
bfd_asymbol_bfd(sym), sym->section, stat1_symbols, sym->value, sym);
bfd_asymbol_bfd (sym), sym->section, stat1_symbols, sym->value, sym);
einfo ("%X%C: first seen here\n",
bfd_asymbol_bfd(sy), sy->section, stat_symbols, sy->value);
bfd_asymbol_bfd (sy), sy->section, stat_symbols, sy->value);
}
else
{
@ -497,7 +497,7 @@ Q_enter_file_symbols (entry)
entry->common_section =
bfd_make_section_old_way (entry->the_bfd, "COMMON");
entry->common_section->flags = SEC_NEVER_LOAD;
ldlang_add_file (entry);
@ -518,16 +518,16 @@ Q_enter_file_symbols (entry)
{
/* look up the symbol anyway to see if the trace bit was
set */
ldsym_type *s = ldsym_get(p->name);
ldsym_type *s = ldsym_get (p->name);
if (s->flags & SYM_Y)
{
einfo("%B: %s %T\n", entry->the_bfd,
einfo ("%B: %s %T\n", entry->the_bfd,
p->section == &bfd_und_section ? "reference to" : "definition of ",
p);
}
}
if (p->flags & BSF_INDIRECT)
if (p->section == &bfd_ind_section)
{
add_indirect (q);
}
@ -680,11 +680,11 @@ decode_library_subfile (library_entry, subfile_offset)
lang_input_statement_struct for this library subfile. If so,
just return it. Otherwise, allocate some space and build a new one. */
if ( subfile_offset->usrdata
&& ((struct lang_input_statement_struct *)subfile_offset->usrdata)->
loaded == true )
if (subfile_offset->usrdata
&& ((struct lang_input_statement_struct *) subfile_offset->usrdata)->
loaded == true)
{
subentry = (struct lang_input_statement_struct *)subfile_offset->usrdata;
subentry = (struct lang_input_statement_struct *) subfile_offset->usrdata;
}
else
{
@ -878,7 +878,7 @@ linear_library (entry)
once */
if (!archive->usrdata ||
! ((lang_input_statement_type *)(archive->usrdata))->loaded)
!((lang_input_statement_type *) (archive->usrdata))->loaded)
{
#ifdef GNU960
if (gnu960_check_format (archive, bfd_object))
@ -921,7 +921,7 @@ linear_library (entry)
}
}
/* ENTRY is an entry for a file inside an archive
/* ENTRY is an entry for a file inside an archive
Its symbols have been read into core, but not entered into the
linker ymbol table
Return nonzero if we ought to load this file */
@ -941,7 +941,7 @@ subfile_wanted_p (entry)
if (p->flags & BSF_INDIRECT)
{
/** add_indirect(q);*/
/** add_indirect(q);*/
}
if (bfd_is_com_section (p->section)
@ -1000,8 +1000,7 @@ subfile_wanted_p (entry)
(asymbol **) ((*(sp->srefs_chain))->udata);
(*(sp->scoms_chain))->udata = (PTR) NULL;
(*(sp->scoms_chain))->section =
&bfd_com_section;
(*(sp->scoms_chain))->section = p->section;
(*(sp->scoms_chain))->flags = 0;
/* Remember the size of this item */
sp->scoms_chain[0]->value = p->value;
@ -1012,12 +1011,12 @@ subfile_wanted_p (entry)
asymbol *com = *(sp->scoms_chain);
if (((lang_input_statement_type *)
(bfd_asymbol_bfd(com)->usrdata))->common_section ==
(bfd_asymbol_bfd (com)->usrdata))->common_section ==
(asection *) NULL)
{
((lang_input_statement_type *)
(bfd_asymbol_bfd(com)->usrdata))->common_section =
bfd_make_section_old_way (bfd_asymbol_bfd(com), "COMMON");
(bfd_asymbol_bfd (com)->usrdata))->common_section =
bfd_make_section_old_way (bfd_asymbol_bfd (com), "COMMON");
}
}
}
@ -1040,10 +1039,10 @@ subfile_wanted_p (entry)
}
void
add_ysym(text)
char *text;
add_ysym (text)
char *text;
{
ldsym_type *lookup = ldsym_get(text);
ldsym_type *lookup = ldsym_get (text);
lookup->flags |= SYM_Y;
had_y = 1;
}

View file

@ -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;
@ -82,7 +82,7 @@ unsigned int global_symbol_count;
/* IMPORTS */
extern boolean option_longmap ;
extern boolean option_longmap;
/* LOCALS */
#define TABSIZE 1009
@ -91,11 +91,11 @@ static ldsym_type *global_symbol_hash_table[TABSIZE];
/* Compute the hash code for symbol name KEY. */
static
#ifdef __GNUC__
__inline
__inline
#endif
int
DEFUN(hash_string,(key),
DEFUN (hash_string, (key),
CONST char *key)
{
register CONST char *cp;
@ -103,7 +103,8 @@ DEFUN(hash_string,(key),
register int l = 0;
cp = key;
k = 0;
while (*cp && l < symbol_truncate) {
while (*cp && l < symbol_truncate)
{
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
l++;
}
@ -112,19 +113,21 @@ DEFUN(hash_string,(key),
static
#ifdef __GNUC__
__inline
__inline
#endif
ldsym_type *
DEFUN(search,(key,hashval) ,
ldsym_type *
DEFUN (search, (key, hashval),
CONST char *key AND
int hashval)
{
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) {
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 (ldsym_type *) (bp->sdefs_chain);
}
return bp;
}
@ -135,7 +138,7 @@ 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),
DEFUN (ldsym_get, (key),
CONST char *key)
{
register int hashval;
@ -146,18 +149,19 @@ DEFUN(ldsym_get,(key),
hashval = hash_string (key) % TABSIZE;
/* Search the bucket. */
bp = search(key, hashval);
if(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,7 +180,7 @@ DEFUN(ldsym_get,(key),
/* Like `ldsym_get' but return 0 if the symbol is not already known. */
ldsym_type *
DEFUN(ldsym_get_soft,(key),
DEFUN (ldsym_get_soft, (key),
CONST char *key)
{
register int hashval;
@ -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,30 +292,31 @@ 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) {
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);
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);
fprintf (config.map_file, " %s\n", f->filename);
if (f->just_syms_flag)
{
fprintf (config.map_file, " symbols only\n");
@ -319,22 +324,24 @@ DEFUN(print_file_stuff,(f),
else
{
asection *s;
if (true || option_longmap) {
if (true || option_longmap)
{
for (s = f->the_bfd->sections;
s != (asection *)NULL;
s = s->next) {
print_address(s->output_offset);
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),
(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),
(unsigned) bfd_get_section_size_before_reloc (s),
s->alignment_power, s->name);
}
}
@ -342,13 +349,14 @@ DEFUN(print_file_stuff,(f),
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));
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, "hex \n");
}
}
fprintf (config.map_file, "\n");
@ -359,87 +367,96 @@ 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));
if (sp->flags & SYM_INDIRECT)
{
fprintf (config.map_file, "indirect %s to %s\n",
sp->name, (((ldsym_type *) (sp->sdefs_chain))->name));
}
else {
else
{
if (sp->sdefs_chain)
{
asymbol *defsym = *(sp->sdefs_chain);
asection *defsec = bfd_get_section(defsym);
print_address(defsym->value);
asection *defsec = bfd_get_section (defsym);
print_address (defsym->value);
if (defsec)
{
fprintf(config.map_file, " %-10s",
bfd_section_name(output_bfd,
fprintf (config.map_file, " %-10s",
bfd_section_name (output_bfd,
defsec));
print_space();
print_address(defsym->value+defsec->vma);
print_space ();
print_address (defsym->value + defsec->vma);
}
else
{
fprintf(config.map_file, " .......");
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->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 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
{
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) {
!= (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) {
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);
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 */
@ -463,22 +480,29 @@ asymbol **output_buffer;
if (p->section == 0)
p->section = &bfd_abs_section;
if (flag_is_global(p->flags) )
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)) {
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))
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) {
if (strip_symbols == STRIP_NONE)
{
*output_buffer++ = p;
}
}
@ -487,24 +511,30 @@ asymbol **output_buffer;
{
/* These must be global. */
}
else if (flag_is_ordinary_local(p->flags))
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) {
else if (p->flags == BSF_WARNING)
{
}
else
{
*output_buffer++ = p;
}
}
else if (p->flags & BSF_CTOR)
{
/* Throw it away */
}
else
{
FAIL();
FAIL ();
}
}
}
@ -516,20 +546,41 @@ 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)
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)
{
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;
if (sp->scoms_chain != (asymbol **)NULL)
if (sp->scoms_chain != (asymbol **) NULL)
{
/*
@ -542,17 +593,20 @@ asymbol **symbol_table;
*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
@ -564,7 +618,7 @@ asymbol **symbol_table;
}
void
ldsym_write()
ldsym_write ()
{
if (keepsyms_file != 0
&& strip_symbols != STRIP_SOME)
@ -572,7 +626,8 @@ ldsym_write()
info ("%P `-retain-symbols-file' overrides `-s' and `-S'\n");
strip_symbols = STRIP_SOME;
}
if (strip_symbols != STRIP_ALL) {
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 +
@ -582,17 +637,17 @@ ldsym_write()
extern unsigned int total_files_seen;
extern unsigned int total_symbols_seen;
asymbol ** symbol_table = (asymbol **)
ldmalloc ((bfd_size_type)(global_symbol_count +
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 **tablep = write_file_locals (symbol_table);
tablep = write_file_globals(tablep);
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));
}
}
@ -601,19 +656,20 @@ return true if the supplied symbol name is not in the
linker symbol table
*/
boolean
DEFUN(ldsym_undefined,(sym),
DEFUN (ldsym_undefined, (sym),
CONST char *sym)
{
ldsym_type *from_table = ldsym_get_soft(sym);
if (from_table != (ldsym_type *)NULL)
ldsym_type *from_table = ldsym_get_soft (sym);
if (from_table != (ldsym_type *) NULL)
{
if (from_table->sdefs_chain != (asymbol **)NULL) return false;
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);
}

View file

@ -39,25 +39,26 @@ Tie together all the interseting blocks
#include "ldgram.h"
#include "relax.h"
static void
DEFUN(build_it,(statement),
lang_statement_union_type *statement)
DEFUN (build_it, (statement),
lang_statement_union_type * statement)
{
switch (statement->header.type) {
switch (statement->header.type)
{
#if 0
{
bfd_byte play_area[SHORT_SIZE];
unsigned int i;
bfd_putshort(output_bfd, statement->fill_statement.fill, play_area);
bfd_putshort (output_bfd, statement->fill_statement.fill, play_area);
/* Write out all entire shorts */
for (i = 0;
i < statement->fill_statement.size - SHORT_SIZE + 1;
i+= SHORT_SIZE)
i += SHORT_SIZE)
{
bfd_set_section_contents(output_bfd,
bfd_set_section_contents (output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset +i,
statement->data_statement.output_offset + i,
SHORT_SIZE);
}
@ -65,15 +66,15 @@ DEFUN(build_it,(statement),
/* Now write any remaining byte */
if (i < statement->fill_statement.size)
{
bfd_set_section_contents(output_bfd,
bfd_set_section_contents (output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset +i,
statement->data_statement.output_offset + i,
1);
}
abort();
abort ();
}
break;
#endif
@ -84,23 +85,24 @@ DEFUN(build_it,(statement),
bfd_vma value = statement->data_statement.value;
bfd_byte play_area[LONG_SIZE];
unsigned int size = 0;
asection * output_section = statement->data_statement.output_section;
switch (statement->data_statement.type) {
asection *output_section = statement->data_statement.output_section;
switch (statement->data_statement.type)
{
case LONG:
bfd_put_32(output_section->owner, value, play_area);
bfd_put_32 (output_section->owner, value, play_area);
size = LONG_SIZE;
break;
case SHORT:
bfd_put_16(output_section->owner, value, play_area);
bfd_put_16 (output_section->owner, value, play_area);
size = SHORT_SIZE;
break;
case BYTE:
bfd_put_8(output_section->owner, value, play_area);
bfd_put_8 (output_section->owner, value, play_area);
size = BYTE_SIZE;
break;
}
bfd_set_section_contents(output_section->owner,
bfd_set_section_contents (output_section->owner,
statement->data_statement.output_section,
play_area,
statement->data_statement.output_vma,
@ -121,11 +123,22 @@ DEFUN(build_it,(statement),
asection *output_section = i->output_section;
bfd_seclet_type *seclet = bfd_new_seclet(output_section->owner,output_section);
bfd_seclet_type *seclet = bfd_new_seclet (output_section->owner, output_section);
if (i->flags & SEC_NEVER_LOAD)
{
/* We've got a never load section inside one which is going
to be output, we'll change it into a fill seclet */
seclet->type = bfd_fill_seclet;
seclet->u.fill.value = 0;
}
else
{
seclet->type = bfd_indirect_seclet;
seclet->u.indirect.section = i;
seclet->u.indirect.symbols = statement->input_section.ifile->asymbols;
seclet->u.indirect.symbols
= statement->input_section.ifile->asymbols;
}
seclet->size = i->_cooked_size;
seclet->offset = i->output_offset;
seclet->next = 0;
@ -140,7 +153,7 @@ DEFUN(build_it,(statement),
attached */
bfd_seclet_type *seclet =
bfd_new_seclet(statement->padding_statement.output_section->owner,
bfd_new_seclet (statement->padding_statement.output_section->owner,
statement->padding_statement.output_section);
seclet->type = bfd_fill_seclet;
@ -166,18 +179,18 @@ DEFUN(build_it,(statement),
void
DEFUN(write_relax,(output_bfd, data, relocateable),
bfd *output_bfd AND
DEFUN (write_relax, (output_bfd, data, relocateable),
bfd * output_bfd AND
PTR data AND
boolean relocateable)
{
/* Tie up all the statements to generate an output bfd structure which
/* Tie up all the statements to generate an output bfd structure which
bfd can mull over */
lang_for_each_statement(build_it);
lang_for_each_statement (build_it);
bfd_seclet_link(output_bfd, data, relocateable);
bfd_seclet_link (output_bfd, data, relocateable);
}
@ -190,8 +203,8 @@ DEFUN(write_relax,(output_bfd, data, relocateable),
symbols in it, and shift around the data too.
*/
boolean
DEFUN(relax_section,(this_ptr),
lang_statement_union_type **this_ptr)
DEFUN (relax_section, (this_ptr),
lang_statement_union_type ** this_ptr)
{
extern lang_input_statement_type *script_file;
lang_input_section_type *is = &((*this_ptr)->input_section);
@ -199,10 +212,9 @@ DEFUN(relax_section,(this_ptr),
if (!(i->owner->flags & BFD_IS_RELAXABLE))
{
if (i->owner != script_file->the_bfd)
einfo("%B: not assembled with -linkrelax\n", i->owner);
einfo ("%B: not assembled with -linkrelax\n", i->owner);
}
return bfd_relax_section(i->owner, i, is->ifile->asymbols);
return bfd_relax_section (i->owner, i, is->ifile->asymbols);
}