Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com)

* ldindr.c (add_indirect): Keep more information in the alias
	symbol chain.
	* ldlang.c (wild_doit):  Don't inherit NEVER_LOAD section
	attribute from an input section.
	* ldmain.c (Q_enter_file_symbols): Common section is NEVER_LOAD by
	default. (Q_enter_file_symbos): Indirect symbols now are known by
	their section, not a special symbol flag.
	* ldsym.c (write_file_locals): Indirect symbols aren't local.
	(write_file_globals): Write the mapping for an indirect symbol.
	* relax.c (build_it): When forced to write a NEVER_LOAD section,
	fill it with zeros.
This commit is contained in:
Steve Chamberlain 1993-03-30 17:49:00 +00:00
parent 21c7770362
commit 29f33467f2
6 changed files with 779 additions and 638 deletions

View File

@ -1,3 +1,21 @@
Tue Mar 30 09:40:25 1993 Steve Chamberlain (sac@thepub.cygnus.com)
* ldindr.c (add_indirect): Keep more information in the alias
symbol chain.
* ldlang.c (wild_doit): Don't inherit NEVER_LOAD section
attribute from an input section.
* ldmain.c (Q_enter_file_symbols): Common section is NEVER_LOAD by
default. (Q_enter_file_symbos): Indirect symbols now are known by
their section, not a special symbol flag.
* ldsym.c (write_file_locals): Indirect symbols aren't local.
(write_file_globals): Write the mapping for an indirect symbol.
* relax.c (build_it): When forced to write a NEVER_LOAD section,
fill it with zeros.
Tue Mar 23 13:24:10 1993 Jeffrey Osier (jeffrey@fowanton.cygnus.com)
* ld.texinfo: changes for q1
Tue Mar 23 00:13:29 1993 david d `zoo' zuhn (zoo at cirdan.cygnus.com)
* Makefile.in: add dvi target, define & use TEXI2DVI, add installcheck

View File

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

View File

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

View File

@ -188,10 +188,10 @@ main (argc, argv)
lang_has_input_file = false;
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");
}
}
lang_final ();
if (trace_files)
@ -347,9 +347,9 @@ DEFUN (Q_enter_global_ref, (nlist_p, name),
sp = ldsym_get (name);
/* If this symbol already has udata, it means that something strange
/* If this symbol already has udata, it means that something strange
has happened.
The strange thing is that we've had an undefined symbol resolved by
an alias, but the thing the alias defined wasn't in the file. So
the symbol got a udata entry, but the file wasn't loaded. Then
@ -358,131 +358,131 @@ DEFUN (Q_enter_global_ref, (nlist_p, name),
if (sym->udata)
return;
return;
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);
sp->scoms_chain = 0;
/* 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);
sp->scoms_chain = 0;
}
}
}
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
ever point to the largest common, so if we
have a common, but it's bigger that the new symbol
the turn this into a reference too. */
if (sp->sdefs_chain)
{
/* This is a common symbol, but we already have a definition
if (sp->sdefs_chain)
{
/* This is a common symbol, but we already have a definition
for it, so just link it into the ref chain as if
it were a reference */
refize (sp, nlist_p);
}
else if (sp->scoms_chain)
{
/* If we have a previous common, keep only the biggest */
if ((*(sp->scoms_chain))->value > sym->value)
{
/* other common is bigger, throw this one away */
refize (sp, nlist_p);
}
else if (sp->scoms_chain != nlist_p)
{
/* other common is smaller, throw that away */
refize (sp, sp->scoms_chain);
sp->scoms_chain = nlist_p;
}
}
else
{
/* This is the first time we've seen a common, so remember it
refize (sp, nlist_p);
}
else if (sp->scoms_chain)
{
/* If we have a previous common, keep only the biggest */
if ((*(sp->scoms_chain))->value > sym->value)
{
/* other common is bigger, throw this one away */
refize (sp, nlist_p);
}
else if (sp->scoms_chain != nlist_p)
{
/* other common is smaller, throw that away */
refize (sp, sp->scoms_chain);
sp->scoms_chain = nlist_p;
}
}
else
{
/* 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
the symbol has been marked as really being a constructor,
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);
}
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->scoms_chain == 0 || (*(sp->scoms_chain))->udata == 0);
@ -496,74 +496,74 @@ Q_enter_file_symbols (entry)
asymbol **q;
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);
if (trace_files || option_v)
{
info ("%I\n", entry);
}
{
info ("%I\n", entry);
}
total_symbols_seen += entry->symbol_count;
total_files_seen++;
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)
{
/* look up the symbol anyway to see if the trace bit was
if (had_y && p->name)
{
/* look up the symbol anyway to see if the trace bit was
set */
ldsym_type *s = ldsym_get(p->name);
if (s->flags & SYM_Y)
{
einfo("%B: %s %T\n", entry->the_bfd,
p->section == &bfd_und_section ? "reference to" : "definition of ",
p);
ldsym_type *s = ldsym_get (p->name);
if (s->flags & SYM_Y)
{
einfo ("%B: %s %T\n", entry->the_bfd,
p->section == &bfd_und_section ? "reference to" : "definition of ",
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
static
boolean
boolean
gnu960_check_format (abfd, format)
bfd *abfd;
bfd_format format;
@ -680,31 +680,31 @@ decode_library_subfile (library_entry, subfile_offset)
lang_input_statement_struct for this library subfile. If so,
just return it. Otherwise, allocate some space and build a new one. */
if ( subfile_offset->usrdata
&& ((struct lang_input_statement_struct *)subfile_offset->usrdata)->
loaded == true )
{
subentry = (struct lang_input_statement_struct *)subfile_offset->usrdata;
}
else
{
subentry =
(struct lang_input_statement_struct *)
ldmalloc ((bfd_size_type) (sizeof (struct lang_input_statement_struct)));
if (subfile_offset->usrdata
&& ((struct lang_input_statement_struct *) subfile_offset->usrdata)->
loaded == true)
{
subentry = (struct lang_input_statement_struct *) subfile_offset->usrdata;
}
else
{
subentry =
(struct lang_input_statement_struct *)
ldmalloc ((bfd_size_type) (sizeof (struct lang_input_statement_struct)));
subentry->filename = subfile_offset->filename;
subentry->local_sym_name = subfile_offset->filename;
subentry->asymbols = 0;
subentry->the_bfd = subfile_offset;
subentry->subfiles = 0;
subentry->next = 0;
subentry->superfile = library_entry;
subentry->is_archive = false;
subentry->filename = subfile_offset->filename;
subentry->local_sym_name = subfile_offset->filename;
subentry->asymbols = 0;
subentry->the_bfd = subfile_offset;
subentry->subfiles = 0;
subentry->next = 0;
subentry->superfile = library_entry;
subentry->is_archive = false;
subentry->just_syms_flag = false;
subentry->loaded = false;
subentry->chain = 0;
}
subentry->just_syms_flag = false;
subentry->loaded = false;
subentry->chain = 0;
}
return subentry;
}
@ -856,13 +856,13 @@ linear_library (entry)
if (entry->complained == false)
{
if (entry->the_bfd->xvec->flavour != bfd_target_ieee_flavour)
{
/* IEEE can use table of contents, so this message is bogus */
einfo ("%P: library %s has bad table of contents, rerun ranlib\n",
entry->the_bfd->filename);
}
if (entry->the_bfd->xvec->flavour != bfd_target_ieee_flavour)
{
/* IEEE can use table of contents, so this message is bogus */
einfo ("%P: library %s has bad table of contents, rerun ranlib\n",
entry->the_bfd->filename);
}
entry->complained = true;
}
@ -878,42 +878,42 @@ linear_library (entry)
once */
if (!archive->usrdata ||
! ((lang_input_statement_type *)(archive->usrdata))->loaded)
{
!((lang_input_statement_type *) (archive->usrdata))->loaded)
{
#ifdef GNU960
if (gnu960_check_format (archive, bfd_object))
if (gnu960_check_format (archive, bfd_object))
#else
if (bfd_check_format (archive, bfd_object))
if (bfd_check_format (archive, bfd_object))
#endif
{
register struct lang_input_statement_struct *subentry;
{
register struct lang_input_statement_struct *subentry;
subentry = decode_library_subfile (entry,
archive);
subentry = decode_library_subfile (entry,
archive);
archive->usrdata = (PTR) subentry;
if (!subentry)
return;
if (subentry->loaded == false)
{
Q_read_entry_symbols (archive, subentry);
archive->usrdata = (PTR) subentry;
if (!subentry)
return;
if (subentry->loaded == false)
{
Q_read_entry_symbols (archive, subentry);
if (subfile_wanted_p (subentry) == true)
{
Q_enter_file_symbols (subentry);
if (subfile_wanted_p (subentry) == true)
{
Q_enter_file_symbols (subentry);
if (prev)
prev->chain = subentry;
else
entry->subfiles = subentry;
prev = subentry;
if (prev)
prev->chain = subentry;
else
entry->subfiles = subentry;
prev = subentry;
more_to_do = true;
subentry->loaded = true;
}
}
}
}
more_to_do = true;
subentry->loaded = true;
}
}
}
}
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
linker ymbol table
Return nonzero if we ought to load this file */
@ -941,7 +941,7 @@ subfile_wanted_p (entry)
if (p->flags & BSF_INDIRECT)
{
/** add_indirect(q);*/
/** add_indirect(q);*/
}
if (bfd_is_com_section (p->section)
@ -1000,8 +1000,7 @@ subfile_wanted_p (entry)
(asymbol **) ((*(sp->srefs_chain))->udata);
(*(sp->scoms_chain))->udata = (PTR) NULL;
(*(sp->scoms_chain))->section =
&bfd_com_section;
(*(sp->scoms_chain))->section = p->section;
(*(sp->scoms_chain))->flags = 0;
/* Remember the size of this item */
sp->scoms_chain[0]->value = p->value;
@ -1012,12 +1011,12 @@ subfile_wanted_p (entry)
asymbol *com = *(sp->scoms_chain);
if (((lang_input_statement_type *)
(bfd_asymbol_bfd(com)->usrdata))->common_section ==
(bfd_asymbol_bfd (com)->usrdata))->common_section ==
(asection *) NULL)
{
((lang_input_statement_type *)
(bfd_asymbol_bfd(com)->usrdata))->common_section =
bfd_make_section_old_way (bfd_asymbol_bfd(com), "COMMON");
(bfd_asymbol_bfd (com)->usrdata))->common_section =
bfd_make_section_old_way (bfd_asymbol_bfd (com), "COMMON");
}
}
}
@ -1040,10 +1039,10 @@ subfile_wanted_p (entry)
}
void
add_ysym(text)
char *text;
add_ysym (text)
char *text;
{
ldsym_type *lookup = ldsym_get(text);
ldsym_type *lookup = ldsym_get (text);
lookup->flags |= SYM_Y;
had_y = 1;
}

View File

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

View File

@ -16,12 +16,12 @@ You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/*
/*
new age linking
Tie together all the interseting blocks
Tie together all the interseting blocks
*/
@ -39,150 +39,163 @@ Tie together all the interseting blocks
#include "ldgram.h"
#include "relax.h"
static void
DEFUN(build_it,(statement),
lang_statement_union_type *statement)
DEFUN (build_it, (statement),
lang_statement_union_type * statement)
{
switch (statement->header.type) {
switch (statement->header.type)
{
#if 0
{
{
bfd_byte play_area[SHORT_SIZE];
unsigned int i;
bfd_putshort(output_bfd, statement->fill_statement.fill, play_area);
/* Write out all entire shorts */
for (i = 0;
i < statement->fill_statement.size - SHORT_SIZE + 1;
i+= SHORT_SIZE)
{
bfd_set_section_contents(output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset +i,
SHORT_SIZE);
bfd_byte play_area[SHORT_SIZE];
unsigned int i;
bfd_putshort (output_bfd, statement->fill_statement.fill, play_area);
/* Write out all entire shorts */
for (i = 0;
i < statement->fill_statement.size - SHORT_SIZE + 1;
i += SHORT_SIZE)
{
bfd_set_section_contents (output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset + i,
SHORT_SIZE);
}
}
/* Now write any remaining byte */
if (i < statement->fill_statement.size)
{
bfd_set_section_contents(output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset +i,
1);
/* Now write any remaining byte */
if (i < statement->fill_statement.size)
{
bfd_set_section_contents (output_bfd,
statement->fill_statement.output_section,
play_area,
statement->data_statement.output_offset + i,
1);
}
}
abort();
}
break;
abort ();
}
break;
#endif
case lang_data_statement_enum:
case lang_data_statement_enum:
{
{
bfd_vma value = statement->data_statement.value;
bfd_byte play_area[LONG_SIZE];
unsigned int size = 0;
asection * output_section = statement->data_statement.output_section;
switch (statement->data_statement.type) {
case LONG:
bfd_put_32(output_section->owner, value, play_area);
size = LONG_SIZE;
break;
case SHORT:
bfd_put_16(output_section->owner, value, play_area);
size = SHORT_SIZE;
break;
case BYTE:
bfd_put_8(output_section->owner, value, play_area);
size = BYTE_SIZE;
break;
}
bfd_set_section_contents(output_section->owner,
statement->data_statement.output_section,
play_area,
statement->data_statement.output_vma,
size);
bfd_vma value = statement->data_statement.value;
bfd_byte play_area[LONG_SIZE];
unsigned int size = 0;
asection *output_section = statement->data_statement.output_section;
switch (statement->data_statement.type)
{
case LONG:
bfd_put_32 (output_section->owner, value, play_area);
size = LONG_SIZE;
break;
case SHORT:
bfd_put_16 (output_section->owner, value, play_area);
size = SHORT_SIZE;
break;
case BYTE:
bfd_put_8 (output_section->owner, value, play_area);
size = BYTE_SIZE;
break;
}
}
bfd_set_section_contents (output_section->owner,
statement->data_statement.output_section,
play_area,
statement->data_statement.output_vma,
size);
break;
case lang_input_section_enum:
{
/* Create a new seclet in the output section with this
}
break;
case lang_input_section_enum:
{
/* Create a new seclet in the output section with this
attached */
if (statement->input_section.ifile->just_syms_flag == false)
{
asection *i = statement->input_section.section;
if (statement->input_section.ifile->just_syms_flag == false)
{
asection *i = statement->input_section.section;
asection *output_section = i->output_section;
bfd_seclet_type *seclet = bfd_new_seclet(output_section->owner,output_section);
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;
case lang_padding_statement_enum:
/* Make a new seclet with the right filler */
{
/* Create a new seclet in the output section with this
asection *output_section = i->output_section;
bfd_seclet_type *seclet = bfd_new_seclet (output_section->owner, output_section);
if (i->flags & SEC_NEVER_LOAD)
{
/* We've got a never load section inside one which is going
to be output, we'll change it into a fill seclet */
seclet->type = bfd_fill_seclet;
seclet->u.fill.value = 0;
}
else
{
seclet->type = bfd_indirect_seclet;
seclet->u.indirect.section = i;
seclet->u.indirect.symbols
= statement->input_section.ifile->asymbols;
}
seclet->size = i->_cooked_size;
seclet->offset = i->output_offset;
seclet->next = 0;
}
}
break;
case lang_padding_statement_enum:
/* Make a new seclet with the right filler */
{
/* Create a new seclet in the output section with this
attached */
bfd_seclet_type *seclet =
bfd_new_seclet(statement->padding_statement.output_section->owner,
statement->padding_statement.output_section);
seclet->type = bfd_fill_seclet;
seclet->size = statement->padding_statement.size;
seclet->offset = statement->padding_statement.output_offset;
seclet->u.fill.value = statement->padding_statement.fill;
seclet->next = 0;
}
break;
bfd_seclet_type *seclet =
bfd_new_seclet (statement->padding_statement.output_section->owner,
statement->padding_statement.output_section);
seclet->type = bfd_fill_seclet;
seclet->size = statement->padding_statement.size;
seclet->offset = statement->padding_statement.output_offset;
seclet->u.fill.value = statement->padding_statement.fill;
seclet->next = 0;
}
break;
break;
default:
/* All the other ones fall through */
;
break;
default:
/* All the other ones fall through */
;
}
}
}
void
DEFUN(write_relax,(output_bfd, data, relocateable),
bfd *output_bfd AND
PTR data AND
boolean relocateable)
void
DEFUN (write_relax, (output_bfd, data, relocateable),
bfd * output_bfd AND
PTR data AND
boolean relocateable)
{
/* Tie up all the statements to generate an output bfd structure which
/* Tie up all the statements to generate an output bfd structure which
bfd can mull over */
lang_for_each_statement(build_it);
lang_for_each_statement (build_it);
bfd_seclet_link(output_bfd, data, relocateable);
bfd_seclet_link (output_bfd, data, relocateable);
}
/* See if we can change the size of this section by shrinking the
@ -190,19 +203,18 @@ DEFUN(write_relax,(output_bfd, data, relocateable),
symbols in it, and shift around the data too.
*/
boolean
DEFUN(relax_section,(this_ptr),
lang_statement_union_type **this_ptr)
DEFUN (relax_section, (this_ptr),
lang_statement_union_type ** this_ptr)
{
extern lang_input_statement_type *script_file;
lang_input_section_type *is = &((*this_ptr)->input_section);
asection *i = is->section;
if (!(i->owner->flags & BFD_IS_RELAXABLE))
{
if (i->owner != script_file->the_bfd)
einfo("%B: not assembled with -linkrelax\n", i->owner);
}
if (!(i->owner->flags & BFD_IS_RELAXABLE))
{
if (i->owner != script_file->the_bfd)
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);
}