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) 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 * Makefile.in: add dvi target, define & use TEXI2DVI, add installcheck

View File

@ -1,6 +1,29 @@
/* ldindr.c /* ldindr.c
Handle indirect symbols. 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 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 all refs like it should be turned into refs of the symbol pointed
at by the value of the indirect symbol. at by the value of the indirect symbol.
@ -93,8 +116,8 @@ asymbol **ptr)
{ {
refize(new, new->scoms_chain); 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 *current_target;
static CONST char *output_target; static CONST char *output_target;
static size_t longest_section_name = 8; static size_t longest_section_name = 8;
static asection common_section;
static section_userdata_type common_section_userdata; static section_userdata_type common_section_userdata;
static lang_statement_list_type statement_list; static lang_statement_list_type statement_list;
@ -612,11 +611,17 @@ DEFUN (wild_doit, (ptr, section, output, file),
new->section = section; new->section = section;
new->ifile = file; new->ifile = file;
section->output_section = output->bfd_section; 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) if (!output->loadable)
{ {
/* Turn of load flag */ /* Turn off load flag */
output->bfd_section->flags &= ~SEC_LOAD; output->bfd_section->flags &= ~SEC_LOAD;
output->bfd_section->flags |= SEC_NEVER_LOAD;
} }
if (section->alignment_power > output->bfd_section->alignment_power) 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 */ /* Do the creation to all sections in the file */
for (s = file->the_bfd->sections; s != (asection *) NULL; s = s->next) 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); wild_doit (&ptr->children, s, output, file);
} }
} }
}
else else
{ {
/* Do the creation to the named section only */ /* 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); wild_section (s, section, f, output);
} }
/* Once more for the script file */
wild_section(s, section, script_file, output);
} }
else else
{ {
@ -947,13 +958,20 @@ DEFUN_VOID (lang_create_output_section_statements)
static void static void
DEFUN_VOID (lang_init_script_file) 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, lang_input_file_is_fake_enum,
(char *) NULL); (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->symbol_count = 0;
script_file->the_bfd->sections = output_bfd->sections; script_file->the_bfd->sections = 0;
abs_output_section = lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME);
/* 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; abs_output_section->bfd_section = &bfd_abs_section;
@ -1876,16 +1894,18 @@ DEFUN_VOID (lang_relocate_globals)
} }
if (it != (asymbol *) NULL) if (it != (asymbol *) NULL)
{ {
asymbol **prev = 0;
asymbol **ptr = lgs->srefs_chain;; asymbol **ptr = lgs->srefs_chain;;
if (lgs->flags & SYM_WARNING) if (lgs->flags & SYM_WARNING)
{ {
produce_warnings (lgs, it); produce_warnings (lgs, it);
} }
while (ptr != (asymbol **) NULL) while (ptr != (asymbol **) NULL
&& ptr != prev)
{ {
asymbol *ref = *ptr; asymbol *ref = *ptr;
prev = ptr;
*ptr = it; *ptr = it;
ptr = (asymbol **) (ref->udata); ptr = (asymbol **) (ref->udata);
} }
@ -1954,9 +1974,6 @@ DEFUN_VOID (lang_check)
file != (lang_statement_union_type *) NULL; file != (lang_statement_union_type *) NULL;
file = file->input_statement.next) 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_bfd = file->input_statement.the_bfd;
input_machine = bfd_get_mach (input_bfd); input_machine = bfd_get_mach (input_bfd);
@ -2051,15 +2068,35 @@ DEFUN_VOID (lang_common)
} }
if (config.sort_common == false || align == power) if (config.sort_common == false || align == power)
{ {
bfd *symbfd;
/* Change from a common symbol into a definition of /* Change from a common symbol into a definition of
a symbol */ a symbol */
lgs->sdefs_chain = lgs->scoms_chain; lgs->sdefs_chain = lgs->scoms_chain;
lgs->scoms_chain = (asymbol **) NULL; lgs->scoms_chain = (asymbol **) NULL;
commons_pending--; commons_pending--;
/* Point to the correct common section */ /* Point to the correct common section */
symbfd = bfd_asymbol_bfd (com);
if (com->section == &bfd_com_section)
com->section = com->section =
((lang_input_statement_type *) ((lang_input_statement_type *) symbfd->usrdata)
(com->the_bfd->usrdata))->common_section; ->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 */ /* Fix the size of the common section */
com->section->_raw_size = com->section->_raw_size =
@ -2077,13 +2114,13 @@ DEFUN_VOID (lang_common)
com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON; com->flags = BSF_EXPORT | BSF_GLOBAL | BSF_OLD_COMMON;
com->value = com->section->_raw_size; 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", fprintf (config.map_file, "Allocating common %s: %x at %x %s\n",
lgs->name, lgs->name,
(unsigned) size, (unsigned) size,
(unsigned) com->value, (unsigned) com->value,
com->the_bfd->filename); bfd_asymbol_bfd(com)->filename);
} }
com->section->_raw_size += size; com->section->_raw_size += size;
@ -2274,6 +2311,7 @@ static int topower(x)
if (i >= x) return l; if (i >= x) return l;
i<<=1; i<<=1;
} }
return 0;
} }
void void
DEFUN (lang_enter_output_section_statement, DEFUN (lang_enter_output_section_statement,
@ -2313,7 +2351,7 @@ DEFUN (lang_enter_output_section_statement,
os->loadable = 0; os->loadable = 0;
else else
os->loadable = 1; os->loadable = 1;
os->block_value = block_value; os->block_value = block_value ? block_value : 1;
stat_ptr = &os->children; stat_ptr = &os->children;
os->subsection_alignment = topower( os->subsection_alignment = topower(
@ -2364,12 +2402,10 @@ DEFUN (create_symbol, (name, flags, section),
/* Add this definition to script file */ /* Add this definition to script file */
asymbol *def = (asymbol *) bfd_make_empty_symbol (script_file->the_bfd); asymbol *def = (asymbol *) bfd_make_empty_symbol (script_file->the_bfd);
def->name = buystring (name); def->name = buystring (name);
def->udata = 0; def->udata = 0;
def->flags = flags; def->flags = flags;
def->section = section; def->section = section;
*def_ptr = def; *def_ptr = def;
Q_enter_global_ref (def_ptr, name); Q_enter_global_ref (def_ptr, name);
return def; return def;
@ -2401,9 +2437,6 @@ DEFUN_VOID (lang_process)
current_target = default_target; current_target = default_target;
lang_for_each_statement (open_input_bfds); 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 /* Run through the contours of the script and attatch input sections
to the correct output sections to the correct output sections
*/ */

View File

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

View File

@ -63,7 +63,7 @@ extern strip_symbols_type strip_symbols;
extern discard_locals_type discard_locals; extern discard_locals_type discard_locals;
/* Head and tail of global symbol table chronological list */ /* 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; ldsym_type **symbol_tail_ptr = &symbol_head;
CONST char *keepsyms_file; CONST char *keepsyms_file;
int kept_syms; int kept_syms;
@ -82,7 +82,7 @@ unsigned int global_symbol_count;
/* IMPORTS */ /* IMPORTS */
extern boolean option_longmap ; extern boolean option_longmap;
/* LOCALS */ /* LOCALS */
#define TABSIZE 1009 #define TABSIZE 1009
@ -91,11 +91,11 @@ static ldsym_type *global_symbol_hash_table[TABSIZE];
/* Compute the hash code for symbol name KEY. */ /* Compute the hash code for symbol name KEY. */
static static
#ifdef __GNUC__ #ifdef __GNUC__
__inline __inline
#endif #endif
int int
DEFUN(hash_string,(key), DEFUN (hash_string, (key),
CONST char *key) CONST char *key)
{ {
register CONST char *cp; register CONST char *cp;
@ -103,7 +103,8 @@ DEFUN(hash_string,(key),
register int l = 0; register int l = 0;
cp = key; cp = key;
k = 0; k = 0;
while (*cp && l < symbol_truncate) { while (*cp && l < symbol_truncate)
{
k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff; k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
l++; l++;
} }
@ -112,19 +113,21 @@ DEFUN(hash_string,(key),
static static
#ifdef __GNUC__ #ifdef __GNUC__
__inline __inline
#endif #endif
ldsym_type * ldsym_type *
DEFUN(search,(key,hashval) , DEFUN (search, (key, hashval),
CONST char *key AND CONST char *key AND
int hashval) int hashval)
{ {
ldsym_type *bp; ldsym_type *bp;
for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link) for (bp = global_symbol_hash_table[hashval]; bp; bp = bp->link)
if (! strncmp (key, bp->name, symbol_truncate)) { if (!strncmp (key, bp->name, symbol_truncate))
if (bp->flags & SYM_INDIRECT) { {
if (bp->flags & SYM_INDIRECT)
{
/* Use the symbol we're aliased to instead */ /* Use the symbol we're aliased to instead */
return (ldsym_type *)(bp->sdefs_chain); return (ldsym_type *) (bp->sdefs_chain);
} }
return bp; return bp;
} }
@ -135,7 +138,7 @@ DEFUN(search,(key,hashval) ,
/* Get the symbol table entry for the global symbol named KEY. /* Get the symbol table entry for the global symbol named KEY.
Create one if there is none. */ Create one if there is none. */
ldsym_type * ldsym_type *
DEFUN(ldsym_get,(key), DEFUN (ldsym_get, (key),
CONST char *key) CONST char *key)
{ {
register int hashval; register int hashval;
@ -146,18 +149,19 @@ DEFUN(ldsym_get,(key),
hashval = hash_string (key) % TABSIZE; hashval = hash_string (key) % TABSIZE;
/* Search the bucket. */ /* Search the bucket. */
bp = search(key, hashval); bp = search (key, hashval);
if(bp) { if (bp)
{
return bp; return bp;
} }
/* Nothing was found; create a new symbol table entry. */ /* Nothing was found; create a new symbol table entry. */
bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type)(sizeof (ldsym_type))); bp = (ldsym_type *) obstack_alloc (&global_sym_obstack, (bfd_size_type) (sizeof (ldsym_type)));
bp->srefs_chain = (asymbol **)NULL; bp->srefs_chain = (asymbol **) NULL;
bp->sdefs_chain = (asymbol **)NULL; bp->sdefs_chain = (asymbol **) NULL;
bp->scoms_chain = (asymbol **)NULL; bp->scoms_chain = (asymbol **) NULL;
bp->name = obstack_copy(&global_sym_obstack, key, strlen(key)+1); bp->name = obstack_copy (&global_sym_obstack, key, strlen (key) + 1);
bp->flags = 0; bp->flags = 0;
/* Add the entry to the bucket. */ /* 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. */ /* Like `ldsym_get' but return 0 if the symbol is not already known. */
ldsym_type * ldsym_type *
DEFUN(ldsym_get_soft,(key), DEFUN (ldsym_get_soft, (key),
CONST char *key) CONST char *key)
{ {
register int hashval; register int hashval;
@ -185,12 +189,12 @@ DEFUN(ldsym_get_soft,(key),
hashval = hash_string (key) % TABSIZE; hashval = hash_string (key) % TABSIZE;
/* Search the bucket. */ /* Search the bucket. */
return search(key, hashval); return search (key, hashval);
} }
static asymbol ** static asymbol **
process_keepsyms (table, size) process_keepsyms (table, size)
asymbol ** table; asymbol **table;
int size; int size;
{ {
struct obstack obstack; struct obstack obstack;
@ -279,7 +283,7 @@ process_keepsyms (table, size)
|| s->flags & BSF_KEEP_G) || s->flags & BSF_KEEP_G)
KEEP (sym); KEEP (sym);
} }
egress: egress:
obstack_free (&obstack, start_of_obstack); obstack_free (&obstack, start_of_obstack);
if (ks_file) if (ks_file)
fclose (ks_file); fclose (ks_file);
@ -288,30 +292,31 @@ process_keepsyms (table, size)
static void static void
list_file_locals (entry) list_file_locals (entry)
lang_input_statement_type *entry; lang_input_statement_type *entry;
{ {
asymbol **q; asymbol **q;
fprintf (config.map_file, "\nLocal symbols of "); fprintf (config.map_file, "\nLocal symbols of ");
minfo("%I", entry); minfo ("%I", entry);
fprintf (config.map_file, ":\n\n"); fprintf (config.map_file, ":\n\n");
if (entry->asymbols) { if (entry->asymbols)
{
for (q = entry->asymbols; *q; q++) for (q = entry->asymbols; *q; q++)
{ {
asymbol *p = *q; asymbol *p = *q;
/* If this is a definition, /* If this is a definition,
update it if necessary by this file's start address. */ update it if necessary by this file's start address. */
if (p->flags & BSF_LOCAL) if (p->flags & BSF_LOCAL)
info(" %V %s\n",p->value, p->name); info (" %V %s\n", p->value, p->name);
} }
} }
} }
static void static void
DEFUN(print_file_stuff,(f), DEFUN (print_file_stuff, (f),
lang_input_statement_type *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) if (f->just_syms_flag)
{ {
fprintf (config.map_file, " symbols only\n"); fprintf (config.map_file, " symbols only\n");
@ -319,22 +324,24 @@ DEFUN(print_file_stuff,(f),
else else
{ {
asection *s; asection *s;
if (true || option_longmap) { if (true || option_longmap)
{
for (s = f->the_bfd->sections; for (s = f->the_bfd->sections;
s != (asection *)NULL; s != (asection *) NULL;
s = s->next) { s = s->next)
print_address(s->output_offset); {
print_address (s->output_offset);
if (s->reloc_done) if (s->reloc_done)
{ {
fprintf (config.map_file, " %08x 2**%2ud %s\n", 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); s->alignment_power, s->name);
} }
else else
{ {
fprintf (config.map_file, " %08x 2**%2ud %s\n", 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); s->alignment_power, s->name);
} }
} }
@ -342,13 +349,14 @@ DEFUN(print_file_stuff,(f),
else else
{ {
for (s = f->the_bfd->sections; for (s = f->the_bfd->sections;
s != (asection *)NULL; s != (asection *) NULL;
s = s->next) { s = s->next)
fprintf(config.map_file, "%s ", s->name); {
print_address(s->output_offset); fprintf (config.map_file, "%s ", s->name);
fprintf(config.map_file, "(%x)", (unsigned)bfd_get_section_size_after_reloc(s)); 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"); fprintf (config.map_file, "\n");
@ -359,87 +367,96 @@ ldsym_print_symbol_table ()
{ {
fprintf (config.map_file, "**FILES**\n\n"); 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, "**GLOBAL SYMBOLS**\n\n");
fprintf(config.map_file, "offset section offset symbol\n"); fprintf (config.map_file, "offset section offset symbol\n");
{ {
register ldsym_type *sp; register ldsym_type *sp;
for (sp = symbol_head; sp; sp = sp->next) for (sp = symbol_head; sp; sp = sp->next)
{ {
if (sp->flags & SYM_INDIRECT) { if (sp->flags & SYM_INDIRECT)
fprintf(config.map_file,"indirect %s to %s\n", {
sp->name, (((ldsym_type *)(sp->sdefs_chain))->name)); fprintf (config.map_file, "indirect %s to %s\n",
sp->name, (((ldsym_type *) (sp->sdefs_chain))->name));
} }
else { else
{
if (sp->sdefs_chain) if (sp->sdefs_chain)
{ {
asymbol *defsym = *(sp->sdefs_chain); asymbol *defsym = *(sp->sdefs_chain);
asection *defsec = bfd_get_section(defsym); asection *defsec = bfd_get_section (defsym);
print_address(defsym->value); print_address (defsym->value);
if (defsec) if (defsec)
{ {
fprintf(config.map_file, " %-10s", fprintf (config.map_file, " %-10s",
bfd_section_name(output_bfd, bfd_section_name (output_bfd,
defsec)); defsec));
print_space(); print_space ();
print_address(defsym->value+defsec->vma); print_address (defsym->value + defsec->vma);
} }
else else
{ {
fprintf(config.map_file, " ......."); fprintf (config.map_file, " .......");
} }
} }
if (sp->scoms_chain) { if (sp->scoms_chain)
fprintf(config.map_file, "common "); {
print_address((*(sp->scoms_chain))->value); fprintf (config.map_file, "common ");
fprintf(config.map_file, " %s ",sp->name); print_address ((*(sp->scoms_chain))->value);
fprintf (config.map_file, " %s ", sp->name);
} }
else if (sp->sdefs_chain) { else if (sp->sdefs_chain)
fprintf(config.map_file, " %s ",sp->name); {
fprintf (config.map_file, " %s ", sp->name);
} }
else { else
fprintf(config.map_file, "undefined "); {
fprintf(config.map_file, "%s ",sp->name); fprintf (config.map_file, "undefined ");
fprintf (config.map_file, "%s ", sp->name);
} }
} }
print_nl(); print_nl ();
} }
} }
if (option_longmap) { if (option_longmap)
lang_for_each_file(list_file_locals); {
lang_for_each_file (list_file_locals);
} }
} }
extern lang_output_section_statement_type *create_object_symbols; extern lang_output_section_statement_type *create_object_symbols;
extern char lprefix; extern char lprefix;
static asymbol ** static asymbol **
write_file_locals(output_buffer) write_file_locals (output_buffer)
asymbol **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 */ /* Run trough the symbols and work out what to do with them */
unsigned int i; unsigned int i;
/* Add one for the filename symbol if needed */ /* Add one for the filename symbol if needed */
if (create_object_symbols if (create_object_symbols
!= (lang_output_section_statement_type *)NULL) { != (lang_output_section_statement_type *) NULL)
{
asection *s; asection *s;
for (s = entry->the_bfd->sections; for (s = entry->the_bfd->sections;
s != (asection *)NULL; s != (asection *) NULL;
s = s->next) { s = s->next)
if (s->output_section == create_object_symbols->bfd_section) { {
if (s->output_section == create_object_symbols->bfd_section)
{
/* Add symbol to this section */ /* Add symbol to this section */
asymbol * newsym = asymbol *newsym =
(asymbol *)bfd_make_empty_symbol(entry->the_bfd); (asymbol *) bfd_make_empty_symbol (entry->the_bfd);
newsym->name = entry->local_sym_name; newsym->name = entry->local_sym_name;
/* The symbol belongs to the output file's text section */ /* The symbol belongs to the output file's text section */
@ -463,22 +480,29 @@ asymbol **output_buffer;
if (p->section == 0) if (p->section == 0)
p->section = &bfd_abs_section; p->section = &bfd_abs_section;
if (flag_is_global(p->flags) ) if (flag_is_global (p->flags))
{ {
/* We are only interested in outputting /* We are only interested in outputting
globals at this stage in special circumstances */ globals at this stage in special circumstances */
if (bfd_asymbol_bfd(p) == entry->the_bfd if (bfd_asymbol_bfd (p) == entry->the_bfd
&& flag_is_not_at_end(p->flags)) { && flag_is_not_at_end (p->flags))
{
/* And this is one of them */ /* And this is one of them */
*(output_buffer++) = p; *(output_buffer++) = p;
p->flags |= BSF_KEEP; p->flags |= BSF_KEEP;
} }
} }
else { else
if (flag_is_debugger(p->flags)) {
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 */ /* Only keep the debugger symbols if no stripping required */
if (strip_symbols == STRIP_NONE) { if (strip_symbols == STRIP_NONE)
{
*output_buffer++ = p; *output_buffer++ = p;
} }
} }
@ -487,24 +511,30 @@ asymbol **output_buffer;
{ {
/* These must be global. */ /* 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) if (discard_locals == DISCARD_ALL)
{ } {
}
else if (discard_locals == DISCARD_L && else if (discard_locals == DISCARD_L &&
(p->name[0] == lprefix)) (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 */ /* Throw it away */
} }
else else
{ {
FAIL(); FAIL ();
} }
} }
} }
@ -516,20 +546,41 @@ asymbol **output_buffer;
static asymbol ** static asymbol **
write_file_globals(symbol_table) write_file_globals (symbol_table)
asymbol **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)); asymbol *bufp = (*(sp->sdefs_chain));
if ((bufp->flags & BSF_KEEP) ==0) { if ((bufp->flags & BSF_KEEP) == 0)
ASSERT(bufp != (asymbol *)NULL); {
ASSERT (bufp != (asymbol *) NULL);
bufp->name = sp->name; 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; *symbol_table++ = bufp;
} }
} }
else if (sp->scoms_chain != (asymbol **)NULL) { else if (sp->scoms_chain != (asymbol **) NULL)
{
/* This symbol is a common - just output */ /* This symbol is a common - just output */
asymbol *bufp = (*(sp->scoms_chain)); asymbol *bufp = (*(sp->scoms_chain));
*symbol_table++ = bufp; *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 */ /* This symbol is undefined but has a reference */
asymbol *bufp = (*(sp->srefs_chain)); asymbol *bufp = (*(sp->srefs_chain));
*symbol_table++ = bufp; *symbol_table++ = bufp;
} }
else { else
{
/* /*
This symbol has neither defs nor refs, it must have come This symbol has neither defs nor refs, it must have come
from the command line, since noone has used it it has no from the command line, since noone has used it it has no
@ -564,7 +618,7 @@ asymbol **symbol_table;
} }
void void
ldsym_write() ldsym_write ()
{ {
if (keepsyms_file != 0 if (keepsyms_file != 0
&& strip_symbols != STRIP_SOME) && strip_symbols != STRIP_SOME)
@ -572,7 +626,8 @@ ldsym_write()
info ("%P `-retain-symbols-file' overrides `-s' and `-S'\n"); info ("%P `-retain-symbols-file' overrides `-s' and `-S'\n");
strip_symbols = STRIP_SOME; strip_symbols = STRIP_SOME;
} }
if (strip_symbols != STRIP_ALL) { if (strip_symbols != STRIP_ALL)
{
/* We know the maximum size of the symbol table - /* We know the maximum size of the symbol table -
it's the size of all the global symbols ever seen + it's the size of all the global symbols ever seen +
the size of all the symbols from all the files + 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_files_seen;
extern unsigned int total_symbols_seen; extern unsigned int total_symbols_seen;
asymbol ** symbol_table = (asymbol **) asymbol **symbol_table = (asymbol **)
ldmalloc ((bfd_size_type)(global_symbol_count + ldmalloc ((bfd_size_type) (global_symbol_count +
total_files_seen + total_files_seen +
total_symbols_seen + 1) * sizeof (asymbol *)); 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 = process_keepsyms (symbol_table, tablep - symbol_table);
*tablep = (asymbol *)NULL; *tablep = (asymbol *) NULL;
bfd_set_symtab(output_bfd, symbol_table, (unsigned)( tablep - symbol_table)); 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 linker symbol table
*/ */
boolean boolean
DEFUN(ldsym_undefined,(sym), DEFUN (ldsym_undefined, (sym),
CONST char *sym) CONST char *sym)
{ {
ldsym_type *from_table = ldsym_get_soft(sym); ldsym_type *from_table = ldsym_get_soft (sym);
if (from_table != (ldsym_type *)NULL) 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; return true;
} }
void 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 "ldgram.h"
#include "relax.h" #include "relax.h"
static void static void
DEFUN(build_it,(statement), DEFUN (build_it, (statement),
lang_statement_union_type *statement) lang_statement_union_type * statement)
{ {
switch (statement->header.type) { switch (statement->header.type)
{
#if 0 #if 0
{ {
bfd_byte play_area[SHORT_SIZE]; bfd_byte play_area[SHORT_SIZE];
unsigned int i; 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 */ /* Write out all entire shorts */
for (i = 0; for (i = 0;
i < statement->fill_statement.size - SHORT_SIZE + 1; 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, statement->fill_statement.output_section,
play_area, play_area,
statement->data_statement.output_offset +i, statement->data_statement.output_offset + i,
SHORT_SIZE); SHORT_SIZE);
} }
@ -65,15 +66,15 @@ DEFUN(build_it,(statement),
/* Now write any remaining byte */ /* Now write any remaining byte */
if (i < statement->fill_statement.size) if (i < statement->fill_statement.size)
{ {
bfd_set_section_contents(output_bfd, bfd_set_section_contents (output_bfd,
statement->fill_statement.output_section, statement->fill_statement.output_section,
play_area, play_area,
statement->data_statement.output_offset +i, statement->data_statement.output_offset + i,
1); 1);
} }
abort(); abort ();
} }
break; break;
#endif #endif
@ -84,23 +85,24 @@ DEFUN(build_it,(statement),
bfd_vma value = statement->data_statement.value; bfd_vma value = statement->data_statement.value;
bfd_byte play_area[LONG_SIZE]; bfd_byte play_area[LONG_SIZE];
unsigned int size = 0; unsigned int size = 0;
asection * output_section = statement->data_statement.output_section; asection *output_section = statement->data_statement.output_section;
switch (statement->data_statement.type) { switch (statement->data_statement.type)
{
case LONG: case LONG:
bfd_put_32(output_section->owner, value, play_area); bfd_put_32 (output_section->owner, value, play_area);
size = LONG_SIZE; size = LONG_SIZE;
break; break;
case SHORT: case SHORT:
bfd_put_16(output_section->owner, value, play_area); bfd_put_16 (output_section->owner, value, play_area);
size = SHORT_SIZE; size = SHORT_SIZE;
break; break;
case BYTE: case BYTE:
bfd_put_8(output_section->owner, value, play_area); bfd_put_8 (output_section->owner, value, play_area);
size = BYTE_SIZE; size = BYTE_SIZE;
break; break;
} }
bfd_set_section_contents(output_section->owner, bfd_set_section_contents (output_section->owner,
statement->data_statement.output_section, statement->data_statement.output_section,
play_area, play_area,
statement->data_statement.output_vma, statement->data_statement.output_vma,
@ -121,11 +123,22 @@ DEFUN(build_it,(statement),
asection *output_section = i->output_section; 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->type = bfd_indirect_seclet;
seclet->u.indirect.section = i; 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->size = i->_cooked_size;
seclet->offset = i->output_offset; seclet->offset = i->output_offset;
seclet->next = 0; seclet->next = 0;
@ -140,7 +153,7 @@ DEFUN(build_it,(statement),
attached */ attached */
bfd_seclet_type *seclet = 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); statement->padding_statement.output_section);
seclet->type = bfd_fill_seclet; seclet->type = bfd_fill_seclet;
@ -166,18 +179,18 @@ DEFUN(build_it,(statement),
void void
DEFUN(write_relax,(output_bfd, data, relocateable), DEFUN (write_relax, (output_bfd, data, relocateable),
bfd *output_bfd AND bfd * output_bfd AND
PTR data AND PTR data AND
boolean relocateable) 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 */ 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. symbols in it, and shift around the data too.
*/ */
boolean boolean
DEFUN(relax_section,(this_ptr), DEFUN (relax_section, (this_ptr),
lang_statement_union_type **this_ptr) lang_statement_union_type ** this_ptr)
{ {
extern lang_input_statement_type *script_file; extern lang_input_statement_type *script_file;
lang_input_section_type *is = &((*this_ptr)->input_section); 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->flags & BFD_IS_RELAXABLE))
{ {
if (i->owner != script_file->the_bfd) 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);
} }