* ldlang.c (new_afile): Add new argument add_to_list. Don't set

real to true for lang_input_file_is_marker_enum.  Clear the_bfd.
	(lang_add_input_file): Pass true to new_afile for add_to_list.
	(lookup_name): Remove force_load argument.  Changed all callers.
	Pass false to new_afile for add_to_list.  Split loading of symbols
	out into separate function.
	(load_symbols): New function split out of lookup_name.  Don't load
	the symbols if they are already loaded.
	(open_input_bfds): For lang_input_statement_enum call load_symbols
	rather than lookup_name.
	(lang_process): Pass abs_output_section rather than NULL to
	lang_size_sections.
	(lang_startup): Set real field of first_file to true.
This commit is contained in:
Ian Lance Taylor 1994-03-24 20:25:12 +00:00
parent 47e70c5417
commit 193c5f93a1
2 changed files with 116 additions and 111 deletions

View File

@ -1,5 +1,29 @@
Thu Mar 24 15:20:47 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* ldlang.c (new_afile): Add new argument add_to_list. Don't set
real to true for lang_input_file_is_marker_enum. Clear the_bfd.
(lang_add_input_file): Pass true to new_afile for add_to_list.
(lookup_name): Remove force_load argument. Changed all callers.
Pass false to new_afile for add_to_list. Split loading of symbols
out into separate function.
(load_symbols): New function split out of lookup_name. Don't load
the symbols if they are already loaded.
(open_input_bfds): For lang_input_statement_enum call load_symbols
rather than lookup_name.
(lang_process): Pass abs_output_section rather than NULL to
lang_size_sections.
(lang_startup): Set real field of first_file to true.
Wed Mar 23 14:15:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com) Wed Mar 23 14:15:44 1994 Ian Lance Taylor (ian@tweedledumb.cygnus.com)
* ldlang.c (had_relax): Removed.
(relax_again): New static variable.
(lang_size_sections): Change call to bfd_relax_section to
correspond to BFD changes. Set relax_again appropriately.
(lang_process): Remove #if 0 code. When relaxing, keep calling
lang_do_assignments and lang_size_sections until relax_again
becomes false.
* emultemp/gld960.em: Include libiberty.h * emultemp/gld960.em: Include libiberty.h
(gld960_before_parse): Pass NULL as final argument to concat. (gld960_before_parse): Pass NULL as final argument to concat.

View File

@ -74,7 +74,7 @@ static void lang_for_each_statement_worker
lang_statement_union_type *s)); lang_statement_union_type *s));
static lang_input_statement_type *new_afile static lang_input_statement_type *new_afile
PARAMS ((const char *name, lang_input_file_enum_type file_type, PARAMS ((const char *name, lang_input_file_enum_type file_type,
const char *target)); const char *target, boolean add_to_list));
static void print_flags PARAMS ((int *ignore_flags)); static void print_flags PARAMS ((int *ignore_flags));
static void init_os PARAMS ((lang_output_section_statement_type *s)); static void init_os PARAMS ((lang_output_section_statement_type *s));
static void wild_doit PARAMS ((lang_statement_list_type *ptr, static void wild_doit PARAMS ((lang_statement_list_type *ptr,
@ -87,8 +87,8 @@ static void wild_section PARAMS ((lang_wild_statement_type *ptr,
const char *section, const char *section,
lang_input_statement_type *file, lang_input_statement_type *file,
lang_output_section_statement_type *output)); lang_output_section_statement_type *output));
static lang_input_statement_type *lookup_name PARAMS ((const char *name, static lang_input_statement_type *lookup_name PARAMS ((const char *name));
int force_load)); static void load_symbols PARAMS ((lang_input_statement_type *entry));
static void wild PARAMS ((lang_wild_statement_type *s, static void wild PARAMS ((lang_wild_statement_type *s,
const char *section, const char *file, const char *section, const char *file,
const char *target, const char *target,
@ -300,14 +300,22 @@ new_statement (type, size, list)
*/ */
static lang_input_statement_type * static lang_input_statement_type *
new_afile (name, file_type, target) new_afile (name, file_type, target, add_to_list)
CONST char *name; CONST char *name;
lang_input_file_enum_type file_type; lang_input_file_enum_type file_type;
CONST char *target; CONST char *target;
boolean add_to_list;
{ {
lang_input_statement_type *p;
lang_input_statement_type *p = new_stat (lang_input_statement, if (add_to_list)
stat_ptr); p = new_stat (lang_input_statement, stat_ptr);
else
{
p = ((lang_input_statement_type *)
stat_alloc (sizeof (lang_input_statement_type)));
p->header.next = NULL;
}
lang_has_input_file = true; lang_has_input_file = true;
p->target = target; p->target = target;
@ -338,8 +346,15 @@ new_afile (name, file_type, target)
p->just_syms_flag = false; p->just_syms_flag = false;
p->search_dirs_flag = true; p->search_dirs_flag = true;
break; break;
case lang_input_file_is_search_file_enum:
case lang_input_file_is_marker_enum: case lang_input_file_is_marker_enum:
p->filename = name;
p->is_archive = false;
p->real = false;
p->local_sym_name = name;
p->just_syms_flag = false;
p->search_dirs_flag = true;
break;
case lang_input_file_is_search_file_enum:
p->filename = name; p->filename = name;
p->is_archive = false; p->is_archive = false;
p->real = true; p->real = true;
@ -358,6 +373,7 @@ new_afile (name, file_type, target)
default: default:
FAIL (); FAIL ();
} }
p->the_bfd = (bfd *) NULL;
p->asymbols = (asymbol **) NULL; p->asymbols = (asymbol **) NULL;
p->superfile = (lang_input_statement_type *) NULL; p->superfile = (lang_input_statement_type *) NULL;
p->next_real_file = (lang_statement_union_type *) NULL; p->next_real_file = (lang_statement_union_type *) NULL;
@ -396,7 +412,7 @@ lang_add_input_file (name, file_type, target)
} }
#endif #endif
return new_afile (name, file_type, target); return new_afile (name, file_type, target, true);
} }
/* Build enough state so that the parser can build its tree */ /* Build enough state so that the parser can build its tree */
@ -745,11 +761,9 @@ wild_section (ptr, section, file, output)
not define anything we need at the time, they won't have all their not define anything we need at the time, they won't have all their
symbols read. If we need them later, we'll have to redo it. symbols read. If we need them later, we'll have to redo it.
*/ */
static static lang_input_statement_type *
lang_input_statement_type * lookup_name (name)
lookup_name (name, force_load)
CONST char *name; CONST char *name;
int force_load;
{ {
lang_input_statement_type *search; lang_input_statement_type *search;
@ -766,50 +780,52 @@ lookup_name (name, force_load)
} }
if (search == (lang_input_statement_type *) NULL) if (search == (lang_input_statement_type *) NULL)
{ search = new_afile (name, lang_input_file_is_file_enum, default_target,
/* There isn't an afile entry for this file yet, this must be false);
because the name has only appeared inside a load script and
not on the command line */
search = new_afile (name, lang_input_file_is_file_enum, default_target);
}
/* If we have already added this file, or this file is not real /* If we have already added this file, or this file is not real
(FIXME: can that ever actually happen?) or the name is NULL (FIXME: can that ever actually happen?) or the name is NULL
(FIXME: can that ever actually happen?) don't add this file. */ (FIXME: can that ever actually happen?) don't add this file. */
if ((search->loaded && ! force_load) if (search->loaded
|| ! search->real || ! search->real
|| search->filename == (const char *) NULL) || search->filename == (const char *) NULL)
return search; return search;
/* start-sanitize-mpw */
#ifdef MPW
/* I hate adding code that works, but for reasons I don't know. */
search->the_bfd = NULL;
#endif
/* end-sanitize-mpw */
ldfile_open_file (search); load_symbols (search);
if (bfd_check_format (search->the_bfd, bfd_object)) return search;
}
/* Get the symbols for an input file. */
static void
load_symbols (entry)
lang_input_statement_type *entry;
{
if (entry->loaded)
return;
ldfile_open_file (entry);
if (bfd_check_format (entry->the_bfd, bfd_object))
{ {
ldlang_add_file (search); ldlang_add_file (entry);
if (trace_files || trace_file_tries) if (trace_files || trace_file_tries)
info_msg ("%I\n", search); info_msg ("%I\n", entry);
} }
else if (bfd_check_format (search->the_bfd, bfd_archive)) else if (bfd_check_format (entry->the_bfd, bfd_archive))
{ {
/* There is nothing to do here; the add_symbols routine will /* There is nothing to do here; the add_symbols routine will
call ldlang_add_file (via the add_archive_element callback) call ldlang_add_file (via the add_archive_element callback)
for each element of the archive which is used. */ for each element of the archive which is used. */
} }
else else
einfo ("%F%B: file not recognized: %E\n", search->the_bfd); einfo ("%F%B: file not recognized: %E\n", entry->the_bfd);
if (bfd_link_add_symbols (search->the_bfd, &link_info) == false) if (bfd_link_add_symbols (entry->the_bfd, &link_info) == false)
einfo ("%F%B: could not read symbols: %E\n", search->the_bfd); einfo ("%F%B: could not read symbols: %E\n", entry->the_bfd);
search->loaded = true; entry->loaded = true;
return search;
} }
static void static void
@ -835,7 +851,7 @@ wild (s, section, file, target, output)
else else
{ {
/* Perform the iteration over a single file */ /* Perform the iteration over a single file */
wild_section (s, section, lookup_name (file, 0), output); wild_section (s, section, lookup_name (file), output);
} }
if (section != (char *) NULL if (section != (char *) NULL
&& strcmp (section, "COMMON") == 0 && strcmp (section, "COMMON") == 0
@ -938,14 +954,14 @@ open_input_bfds (statement)
/* Maybe we should load the file's symbols */ /* Maybe we should load the file's symbols */
if (statement->wild_statement.filename) if (statement->wild_statement.filename)
{ {
(void) lookup_name (statement->wild_statement.filename, 1); (void) lookup_name (statement->wild_statement.filename);
} }
break; break;
case lang_input_statement_enum: case lang_input_statement_enum:
if (statement->input_statement.real == true) if (statement->input_statement.real == true)
{ {
statement->input_statement.target = current_target; statement->input_statement.target = current_target;
lookup_name (statement->input_statement.filename, 1); load_symbols (&statement->input_statement);
} }
break; break;
default: default:
@ -1613,11 +1629,12 @@ size_input_section (this_ptr, output_section_statement, fill, dot, relax)
return dot; return dot;
} }
/* Sizing happens in two passes, first pass we allocate worst case /* This variable indicates whether bfd_relax_section should be called
stuff. The second pass (if relaxing), we use what we learnt to again. */
change the size of some relocs from worst case to better
*/ static boolean relax_again;
static boolean had_relax;
/* Set the sizes for all the output sections. */
bfd_vma bfd_vma
lang_size_sections (s, output_section_statement, prev, fill, dot, relax) lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
@ -1800,50 +1817,26 @@ lang_size_sections (s, output_section_statement, prev, fill, dot, relax)
case lang_target_statement_enum: case lang_target_statement_enum:
break; break;
case lang_input_section_enum: case lang_input_section_enum:
if (relax)
{ {
lang_input_section_type *is;
asection *i; asection *i;
is = &(*prev)->input_section; i = (*prev)->input_section.section;
i = is->section; if (! relax)
i->_cooked_size = i->_raw_size;
/* FIXME: The interface to bfd_relax_section should be changed else
to not require the generic symbols to be read. Changing
this would require changing both b_out_relax_section and
bfd_coff_relax16_section. */
if (is->ifile->asymbols == (asymbol **) NULL)
{ {
unsigned int symsize; boolean again;
symsize = get_symtab_upper_bound (i->owner);
is->ifile->asymbols = (asymbol **) xmalloc (symsize);
is->ifile->symbol_count =
bfd_canonicalize_symtab (i->owner, is->ifile->asymbols);
/* The generic linker code in BFD requires that these
symbols be stored in the outsymbols and symcount
fields. When the bfd_relax_section is interface is
fixed this should also be fixed. */
i->owner->outsymbols = is->ifile->asymbols;
i->owner->symcount = is->ifile->symbol_count;
}
bfd_set_error (bfd_error_no_error);
if (bfd_relax_section (i->owner, i, &link_info, is->ifile->asymbols))
had_relax = true;
else if (bfd_get_error () != bfd_error_no_error)
einfo ("%P%F: can't relax section: %E");
}
else {
(*prev)->input_section.section->_cooked_size =
(*prev)->input_section.section->_raw_size ;
if (! bfd_relax_section (i->owner, i, &link_info, &again))
einfo ("%P%F: can't relax section: %E\n");
if (again)
relax_again = true;
} }
dot = size_input_section (prev, dot = size_input_section (prev,
output_section_statement, output_section_statement,
output_section_statement->fill, output_section_statement->fill,
dot, relax); dot, relax);
}
break; break;
case lang_input_statement_enum: case lang_input_statement_enum:
break; break;
@ -2529,40 +2522,25 @@ lang_process ()
ldemul_before_allocation (); ldemul_before_allocation ();
#if 0
had_relax = true;
while (had_relax)
{
had_relax = false;
lang_size_sections (statement_list.head,
(lang_output_section_statement_type *) NULL,
&(statement_list.head), 0, (bfd_vma) 0, true);
/* FIXME. Until the code in relax is fixed so that it only reads in
stuff once, we cant iterate since there is no way for the linker to
know what has been patched and what hasn't */
break;
}
#endif
/* Now run around and relax if we can */ /* Now run around and relax if we can */
if (command_line.relax) if (command_line.relax)
{ {
/* First time round is a trial run to get the 'worst case' /* First time round is a trial run to get the 'worst case'
addresses of the objects if there was no relaxing. */ addresses of the objects if there was no relaxing. */
lang_size_sections (statement_list.head, lang_size_sections (statement_list.head,
(lang_output_section_statement_type *) NULL, abs_output_section,
&(statement_list.head), 0, (bfd_vma) 0, false); &(statement_list.head), 0, (bfd_vma) 0, false);
reset_memory_regions (); reset_memory_regions ();
/* Do all the assignments, now that we know the final resting /* Keep relaxing until bfd_relax_section gives up. */
places of all the symbols. */ do
{
relax_again = false;
/* Do all the assignments with our current guesses as to
section sizes. */
lang_do_assignments (statement_list.head, lang_do_assignments (statement_list.head,
abs_output_section, abs_output_section,
(fill_type) 0, (bfd_vma) 0); (fill_type) 0, (bfd_vma) 0);
@ -2570,9 +2548,11 @@ lang_process ()
/* Perform another relax pass - this time we know where the /* Perform another relax pass - this time we know where the
globals are, so can make better guess. */ globals are, so can make better guess. */
lang_size_sections (statement_list.head, lang_size_sections (statement_list.head,
(lang_output_section_statement_type *) NULL, abs_output_section,
&(statement_list.head), 0, (bfd_vma) 0, true); &(statement_list.head), 0, (bfd_vma) 0, true);
} }
while (relax_again);
}
else else
{ {
/* Size up the sections. */ /* Size up the sections. */
@ -2749,6 +2729,7 @@ lang_startup (name)
} }
first_file->filename = name; first_file->filename = name;
first_file->local_sym_name = name; first_file->local_sym_name = name;
first_file->real = true;
startup_file = name; startup_file = name;
} }