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

@ -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

@ -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;
} }

@ -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,9 +658,13 @@ 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
{ {
@ -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 */
com->section = symbfd = bfd_asymbol_bfd (com);
((lang_input_statement_type *) if (com->section == &bfd_com_section)
(com->the_bfd->usrdata))->common_section; com->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 */ /* 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
*/ */

@ -189,9 +189,9 @@ main (argc, argv)
parse_args (argc, argv); parse_args (argc, argv);
if (config.relocateable_output && command_line.relax) if (config.relocateable_output && command_line.relax)
{ {
einfo ("%P%F: -relax and -r may not be used together\n"); einfo ("%P%F: -relax and -r may not be used together\n");
} }
lang_final (); lang_final ();
if (trace_files) if (trace_files)
@ -358,131 +358,131 @@ DEFUN (Q_enter_global_ref, (nlist_p, name),
if (sym->udata) if (sym->udata)
return; return;
if (flag_is_constructor (this_symbol_flags)) if (flag_is_constructor (this_symbol_flags))
{
/* Add this constructor to the list we keep */
ldlang_add_constructor (sp);
/* Turn any commons into refs */
if (sp->scoms_chain != (asymbol **) NULL)
{ {
refize (sp, sp->scoms_chain); /* Add this constructor to the list we keep */
sp->scoms_chain = 0; ldlang_add_constructor (sp);
/* Turn any commons into refs */
if (sp->scoms_chain != (asymbol **) NULL)
{
refize (sp, sp->scoms_chain);
sp->scoms_chain = 0;
}
} }
}
else else
{
if (bfd_is_com_section (sym->section))
{ {
/* If we have a definition of this symbol already then if (bfd_is_com_section (sym->section))
{
/* If we have a definition of this symbol already then
this common turns into a reference. Also we only this common turns into a reference. Also we only
ever point to the largest common, so if we ever point to the largest common, so if we
have a common, but it's bigger that the new symbol have a common, but it's bigger that the new symbol
the turn this into a reference too. */ the turn this into a reference too. */
if (sp->sdefs_chain) if (sp->sdefs_chain)
{ {
/* This is a common symbol, but we already have a definition /* This is a common symbol, but we already have a definition
for it, so just link it into the ref chain as if for it, so just link it into the ref chain as if
it were a reference */ it were a reference */
refize (sp, nlist_p); refize (sp, nlist_p);
} }
else if (sp->scoms_chain) else if (sp->scoms_chain)
{ {
/* If we have a previous common, keep only the biggest */ /* If we have a previous common, keep only the biggest */
if ((*(sp->scoms_chain))->value > sym->value) if ((*(sp->scoms_chain))->value > sym->value)
{ {
/* other common is bigger, throw this one away */ /* other common is bigger, throw this one away */
refize (sp, nlist_p); refize (sp, nlist_p);
} }
else if (sp->scoms_chain != nlist_p) else if (sp->scoms_chain != nlist_p)
{ {
/* other common is smaller, throw that away */ /* other common is smaller, throw that away */
refize (sp, sp->scoms_chain); refize (sp, sp->scoms_chain);
sp->scoms_chain = nlist_p; sp->scoms_chain = nlist_p;
} }
} }
else else
{ {
/* This is the first time we've seen a common, so remember it /* This is the first time we've seen a common, so remember it
- if it was undefined before, we know it's defined now. If - if it was undefined before, we know it's defined now. If
the symbol has been marked as really being a constructor, the symbol has been marked as really being a constructor,
then treat this as a ref then treat this as a ref
*/ */
if (sp->flags & SYM_CONSTRUCTOR) if (sp->flags & SYM_CONSTRUCTOR)
{
/* Turn this into a ref */
refize (sp, nlist_p);
}
else
{
/* treat like a common */
if (sp->srefs_chain)
undefined_global_sym_count--;
commons_pending++;
sp->scoms_chain = nlist_p;
}
}
}
else if (sym->section != &bfd_und_section)
{ {
/* Turn this into a ref */ /* This is the definition of a symbol, add to def chain */
if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section)
{
/* 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 *stat1 =
(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);
einfo ("%X%C: first seen here\n",
bfd_asymbol_bfd (sy), sy->section, stat_symbols, sy->value);
}
else
{
sym->udata = (PTR) (sp->sdefs_chain);
sp->sdefs_chain = nlist_p;
}
/* A definition overrides a common symbol */
if (sp->scoms_chain)
{
refize (sp, sp->scoms_chain);
sp->scoms_chain = 0;
commons_pending--;
}
else if (sp->srefs_chain && relaxing == false)
{
/* If previously was undefined, then remember as defined */
undefined_global_sym_count--;
}
}
else
{
if (sp->scoms_chain == (asymbol **) NULL
&& sp->srefs_chain == (asymbol **) NULL
&& sp->sdefs_chain == (asymbol **) NULL)
{
/* And it's the first time we've seen it */
undefined_global_sym_count++;
}
refize (sp, nlist_p); refize (sp, nlist_p);
} }
else
{
/* treat like a common */
if (sp->srefs_chain)
undefined_global_sym_count--;
commons_pending++;
sp->scoms_chain = nlist_p;
}
}
} }
else if (sym->section != &bfd_und_section)
{
/* This is the definition of a symbol, add to def chain */
if (sp->sdefs_chain && (*(sp->sdefs_chain))->section != sym->section)
{
/* 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 *stat1 =
(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);
einfo ("%X%C: first seen here\n",
bfd_asymbol_bfd(sy), sy->section, stat_symbols, sy->value);
}
else
{
sym->udata = (PTR) (sp->sdefs_chain);
sp->sdefs_chain = nlist_p;
}
/* A definition overrides a common symbol */
if (sp->scoms_chain)
{
refize (sp, sp->scoms_chain);
sp->scoms_chain = 0;
commons_pending--;
}
else if (sp->srefs_chain && relaxing == false)
{
/* If previously was undefined, then remember as defined */
undefined_global_sym_count--;
}
}
else
{
if (sp->scoms_chain == (asymbol **) NULL
&& sp->srefs_chain == (asymbol **) NULL
&& sp->sdefs_chain == (asymbol **) NULL)
{
/* And it's the first time we've seen it */
undefined_global_sym_count++;
}
refize (sp, nlist_p);
}
}
ASSERT (sp->sdefs_chain == 0 || sp->scoms_chain == 0); ASSERT (sp->sdefs_chain == 0 || sp->scoms_chain == 0);
ASSERT (sp->scoms_chain == 0 || (*(sp->scoms_chain))->udata == 0); ASSERT (sp->scoms_chain == 0 || (*(sp->scoms_chain))->udata == 0);
@ -496,74 +496,74 @@ Q_enter_file_symbols (entry)
asymbol **q; asymbol **q;
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);
if (trace_files || option_v) if (trace_files || option_v)
{ {
info ("%I\n", entry); info ("%I\n", entry);
} }
total_symbols_seen += entry->symbol_count; total_symbols_seen += entry->symbol_count;
total_files_seen++; total_files_seen++;
if (entry->symbol_count) if (entry->symbol_count)
{
for (q = entry->asymbols; *q; q++)
{ {
asymbol *p = *q; for (q = entry->asymbols; *q; q++)
{
asymbol *p = *q;
if (had_y && p->name) if (had_y && p->name)
{ {
/* 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->section == &bfd_ind_section)
{
add_indirect (q);
}
else if (p->flags & BSF_WARNING)
{
add_warning (p);
}
else if (p->section == &bfd_und_section
|| (p->flags & BSF_GLOBAL)
|| bfd_is_com_section (p->section)
|| (p->flags & BSF_CONSTRUCTOR))
{
asymbol *p = *q;
if (p->flags & BSF_INDIRECT)
{
add_indirect (q);
}
else if (p->flags & BSF_WARNING)
{
add_warning (p);
}
else if (p->section == &bfd_und_section
|| (p->flags & BSF_GLOBAL)
|| bfd_is_com_section (p->section)
|| (p->flags & BSF_CONSTRUCTOR))
{
Q_enter_global_ref (q, p->name);
}
}
} }
}
if (p->flags & BSF_INDIRECT)
{
add_indirect (q);
}
else if (p->flags & BSF_WARNING)
{
add_warning (p);
}
else if (p->section == &bfd_und_section
|| (p->flags & BSF_GLOBAL)
|| bfd_is_com_section (p->section)
|| (p->flags & BSF_CONSTRUCTOR))
{
asymbol *p = *q;
if (p->flags & BSF_INDIRECT)
{
add_indirect (q);
}
else if (p->flags & BSF_WARNING)
{
add_warning (p);
}
else if (p->section == &bfd_und_section
|| (p->flags & BSF_GLOBAL)
|| bfd_is_com_section (p->section)
|| (p->flags & BSF_CONSTRUCTOR))
{
Q_enter_global_ref (q, p->name);
}
}
} }
}
} }
@ -595,7 +595,7 @@ search_library (entry)
#ifdef GNU960 #ifdef GNU960
static static
boolean boolean
gnu960_check_format (abfd, format) gnu960_check_format (abfd, format)
bfd *abfd; bfd *abfd;
bfd_format format; bfd_format format;
@ -680,31 +680,31 @@ 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
{ {
subentry = subentry =
(struct lang_input_statement_struct *) (struct lang_input_statement_struct *)
ldmalloc ((bfd_size_type) (sizeof (struct lang_input_statement_struct))); ldmalloc ((bfd_size_type) (sizeof (struct lang_input_statement_struct)));
subentry->filename = subfile_offset->filename; subentry->filename = subfile_offset->filename;
subentry->local_sym_name = subfile_offset->filename; subentry->local_sym_name = subfile_offset->filename;
subentry->asymbols = 0; subentry->asymbols = 0;
subentry->the_bfd = subfile_offset; subentry->the_bfd = subfile_offset;
subentry->subfiles = 0; subentry->subfiles = 0;
subentry->next = 0; subentry->next = 0;
subentry->superfile = library_entry; subentry->superfile = library_entry;
subentry->is_archive = false; subentry->is_archive = false;
subentry->just_syms_flag = false; subentry->just_syms_flag = false;
subentry->loaded = false; subentry->loaded = false;
subentry->chain = 0; subentry->chain = 0;
} }
return subentry; return subentry;
} }
@ -858,11 +858,11 @@ linear_library (entry)
{ {
if (entry->the_bfd->xvec->flavour != bfd_target_ieee_flavour) if (entry->the_bfd->xvec->flavour != bfd_target_ieee_flavour)
{ {
/* IEEE can use table of contents, so this message is bogus */ /* IEEE can use table of contents, so this message is bogus */
einfo ("%P: library %s has bad table of contents, rerun ranlib\n", einfo ("%P: library %s has bad table of contents, rerun ranlib\n",
entry->the_bfd->filename); entry->the_bfd->filename);
} }
entry->complained = true; entry->complained = true;
} }
@ -878,42 +878,42 @@ 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))
#else #else
if (bfd_check_format (archive, bfd_object)) if (bfd_check_format (archive, bfd_object))
#endif #endif
{ {
register struct lang_input_statement_struct *subentry; register struct lang_input_statement_struct *subentry;
subentry = decode_library_subfile (entry, subentry = decode_library_subfile (entry,
archive); archive);
archive->usrdata = (PTR) subentry; archive->usrdata = (PTR) subentry;
if (!subentry) if (!subentry)
return; return;
if (subentry->loaded == false) if (subentry->loaded == false)
{ {
Q_read_entry_symbols (archive, subentry); Q_read_entry_symbols (archive, subentry);
if (subfile_wanted_p (subentry) == true) if (subfile_wanted_p (subentry) == true)
{ {
Q_enter_file_symbols (subentry); Q_enter_file_symbols (subentry);
if (prev) if (prev)
prev->chain = subentry; prev->chain = subentry;
else else
entry->subfiles = subentry; entry->subfiles = subentry;
prev = subentry; prev = subentry;
more_to_do = true; more_to_do = true;
subentry->loaded = true; subentry->loaded = true;
} }
} }
} }
} }
archive = bfd_openr_next_archived_file (entry->the_bfd, archive); archive = bfd_openr_next_archived_file (entry->the_bfd, archive);
} }
@ -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;
} }

@ -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,43 +91,46 @@ 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;
register int k; register int k;
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; {
l++; k = (((k << 1) + (k >> 14)) ^ (*cp++)) & 0x3fff;
} l++;
}
return k; return k;
} }
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) { {
/* Use the symbol we're aliased to instead */ if (bp->flags & SYM_INDIRECT)
return (ldsym_type *)(bp->sdefs_chain); {
/* Use the symbol we're aliased to instead */
return (ldsym_type *) (bp->sdefs_chain);
}
return bp;
} }
return bp;
}
return 0; return 0;
} }
@ -135,8 +138,8 @@ 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;
register ldsym_type *bp; register ldsym_type *bp;
@ -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,8 +180,8 @@ 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;
/* Determine which bucket. */ /* Determine which bucket. */
@ -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,69 +292,73 @@ 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; {
/* If this is a definition, asymbol *p = *q;
/* 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");
}
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; fprintf (config.map_file, " symbols only\n");
s != (asection *)NULL; }
s = s->next) { else
fprintf(config.map_file, "%s ", s->name); {
print_address(s->output_offset); asection *s;
fprintf(config.map_file, "(%x)", (unsigned)bfd_get_section_size_after_reloc(s)); if (true || option_longmap)
} {
fprintf(config.map_file, "hex \n"); 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"); fprintf (config.map_file, "\n");
} }
@ -359,155 +367,177 @@ 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 {
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) { else
fprintf(config.map_file, " %s ",sp->name); {
} if (sp->sdefs_chain)
else { {
fprintf(config.map_file, "undefined "); asymbol *defsym = *(sp->sdefs_chain);
fprintf(config.map_file, "%s ",sp->name); 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) { 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; {
for (s = entry->the_bfd->sections; asection *s;
s != (asection *)NULL; for (s = entry->the_bfd->sections;
s = s->next) { s != (asection *) NULL;
if (s->output_section == create_object_symbols->bfd_section) { s = s->next)
/* Add symbol to this section */ {
asymbol * newsym = if (s->output_section == create_object_symbols->bfd_section)
(asymbol *)bfd_make_empty_symbol(entry->the_bfd); {
newsym->name = entry->local_sym_name; /* Add symbol to this section */
/* The symbol belongs to the output file's text 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*/ /* The value is the start of this section in the output file*/
newsym->value = 0; newsym->value = 0;
/* FIXME: Usurping BSF_KEEP_G flag, since it's defined as /* FIXME: Usurping BSF_KEEP_G flag, since it's defined as
"used by the linker" and I can't find any other code that "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 uses it. Should be a cleaner way of doing this (like an
"application flags" field in the symbol structure?). */ "application flags" field in the symbol structure?). */
newsym->flags = BSF_LOCAL | BSF_KEEP_G; newsym->flags = BSF_LOCAL | BSF_KEEP_G;
newsym->section = s; newsym->section = s;
*output_buffer++ = newsym; *output_buffer++ = newsym;
break; break;
} }
} }
} }
for (i = 0; i < entry->symbol_count; i++) for (i = 0; i < entry->symbol_count; i++)
{ {
asymbol *p = entry->asymbols[i]; asymbol *p = entry->asymbols[i];
/* FIXME, temporary hack, since not all of ld knows about the new abs section convention */ /* FIXME, temporary hack, since not all of ld knows about the new abs section convention */
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 */ {
*(output_buffer++) = p; /* And this is one of them */
p->flags |= BSF_KEEP; *(output_buffer++) = p;
} p->flags |= BSF_KEEP;
} }
else { }
if (flag_is_debugger(p->flags)) else
{ {
/* Only keep the debugger symbols if no stripping required */ if (p->section == &bfd_ind_section)
if (strip_symbols == STRIP_NONE) { {
*output_buffer++ = p; /* 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 ** 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) == 0 && sp->sdefs_chain != (asymbol **)NULL) { 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)); 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)
{ {
/* /*
defined as common but not allocated, this happens defined as common but not allocated, this happens
only with -r and not -d, write out a common only with -r and not -d, write out a common
definition definition
*/ */
bufp = *(sp->scoms_chain); bufp = *(sp->scoms_chain);
} }
*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
data attatched, so we'll ignore it data attatched, so we'll ignore it
*/ */
} }
} }
return symbol_table; return 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,28 +626,29 @@ 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 +
the number of files (for the per file symbols) the number of files (for the per file symbols)
+1 (for the null at the end) +1 (for the null at the end)
*/ */
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);
} }

@ -39,126 +39,139 @@ 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);
} }
/* 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
case lang_data_statement_enum: case lang_data_statement_enum:
{ {
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: {
bfd_put_32(output_section->owner, value, play_area); case LONG:
size = LONG_SIZE; bfd_put_32 (output_section->owner, value, play_area);
break; size = LONG_SIZE;
case SHORT: break;
bfd_put_16(output_section->owner, value, play_area); case SHORT:
size = SHORT_SIZE; bfd_put_16 (output_section->owner, value, play_area);
break; size = SHORT_SIZE;
case BYTE: break;
bfd_put_8(output_section->owner, value, play_area); case BYTE:
size = BYTE_SIZE; bfd_put_8 (output_section->owner, value, play_area);
break; size = BYTE_SIZE;
} 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,
size); size);
} }
break; break;
case lang_input_section_enum: case lang_input_section_enum:
{ {
/* Create a new seclet in the output section with this /* Create a new seclet in the output section with this
attached */ attached */
if (statement->input_section.ifile->just_syms_flag == false) if (statement->input_section.ifile->just_syms_flag == false)
{ {
asection *i = statement->input_section.section; asection *i = statement->input_section.section;
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);
seclet->type = bfd_indirect_seclet; if (i->flags & SEC_NEVER_LOAD)
seclet->u.indirect.section = i; {
seclet->u.indirect.symbols = statement->input_section.ifile->asymbols; /* We've got a never load section inside one which is going
seclet->size = i->_cooked_size; to be output, we'll change it into a fill seclet */
seclet->offset = i->output_offset; seclet->type = bfd_fill_seclet;
seclet->next = 0; 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->size = i->_cooked_size;
seclet->offset = i->output_offset;
seclet->next = 0;
}
} }
break; break;
case lang_padding_statement_enum: case lang_padding_statement_enum:
/* Make a new seclet with the right filler */ /* Make a new seclet with the right filler */
{ {
/* Create a new seclet in the output section with this /* Create a new seclet in the output section with this
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;
seclet->size = statement->padding_statement.size; seclet->size = statement->padding_statement.size;
seclet->offset = statement->padding_statement.output_offset; seclet->offset = statement->padding_statement.output_offset;
seclet->u.fill.value = statement->padding_statement.fill; seclet->u.fill.value = statement->padding_statement.fill;
seclet->next = 0; seclet->next = 0;
} }
break; break;
break; break;
default: default:
/* All the other ones fall through */ /* All the other ones fall through */
; ;
} }
@ -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,19 +203,18 @@ 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);
asection *i = is->section; asection *i = is->section;
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);
} }