mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-22 11:00:01 +08:00
Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com)
* ldindr.c (add_indirect): Keep more information in the alias symbol chain. * ldlang.c (wild_doit): Don't inherit NEVER_LOAD section attribute from an input section. * ldmain.c (Q_enter_file_symbols): Common section is NEVER_LOAD by default. (Q_enter_file_symbos): Indirect symbols now are known by their section, not a special symbol flag. * ldsym.c (write_file_locals): Indirect symbols aren't local. (write_file_globals): Write the mapping for an indirect symbol. * relax.c (build_it): When forced to write a NEVER_LOAD section, fill it with zeros.
This commit is contained in:
18
ld/ChangeLog
18
ld/ChangeLog
@ -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
|
||||||
|
27
ld/ldindr.c
27
ld/ldindr.c
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
79
ld/ldlang.c
79
ld/ldlang.c
@ -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
|
||||||
*/
|
*/
|
||||||
|
451
ld/ldmain.c
451
ld/ldmain.c
@ -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;
|
||||||
}
|
}
|
||||||
|
552
ld/ldsym.c
552
ld/ldsym.c
@ -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);
|
||||||
}
|
}
|
||||||
|
228
ld/relax.c
228
ld/relax.c
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user