* ldlang.c (walk_wild, walk_wild_file, walk_wild_section,
output_section_callback, gc_section_callback): New functions for generic section walks. (wild, lang_gc_wild): Use walk_wild. (wild_file, lang_gc_wild_file): Deleted. Common logic moved to walk_wild_file. (wild_section, lang_gc_wild_section): Deleted. Common logic moved to walk_fild_section. Unique logic moved into callbacks output_section_callback and gc_section_callback.
This commit is contained in:
parent
d0e9a01c12
commit
4dec4d4e74
12
ld/ChangeLog
12
ld/ChangeLog
@ -1,3 +1,15 @@
|
||||
1999-05-12 Anthony Green <green@cygnus.com>
|
||||
|
||||
* ldlang.c (walk_wild, walk_wild_file, walk_wild_section,
|
||||
output_section_callback, gc_section_callback): New functions for
|
||||
generic section walks.
|
||||
(wild, lang_gc_wild): Use walk_wild.
|
||||
(wild_file, lang_gc_wild_file): Deleted. Common logic moved to
|
||||
walk_wild_file.
|
||||
(wild_section, lang_gc_wild_section): Deleted. Common logic moved
|
||||
to walk_fild_section. Unique logic moved into callbacks
|
||||
output_section_callback and gc_section_callback.
|
||||
|
||||
1999-04-26 Tom Tromey <tromey@cygnus.com>
|
||||
|
||||
* aclocal.m4, configure: Updated for new version of libtool.
|
||||
|
475
ld/ldlang.c
475
ld/ldlang.c
@ -77,16 +77,9 @@ static boolean wildcardp PARAMS ((const char *));
|
||||
static lang_statement_union_type *wild_sort
|
||||
PARAMS ((lang_wild_statement_type *, lang_input_statement_type *,
|
||||
asection *));
|
||||
static void wild_section PARAMS ((lang_wild_statement_type *ptr,
|
||||
const char *section,
|
||||
lang_input_statement_type *file,
|
||||
lang_output_section_statement_type *output));
|
||||
static lang_input_statement_type *lookup_name PARAMS ((const char *name));
|
||||
static void load_symbols PARAMS ((lang_input_statement_type *entry,
|
||||
lang_statement_list_type *));
|
||||
static void wild_file PARAMS ((lang_wild_statement_type *, const char *,
|
||||
lang_input_statement_type *,
|
||||
lang_output_section_statement_type *));
|
||||
static void wild PARAMS ((lang_wild_statement_type *s,
|
||||
const char *section, const char *file,
|
||||
const char *target,
|
||||
@ -142,20 +135,23 @@ static int topower PARAMS ((int));
|
||||
static void lang_set_startof PARAMS ((void));
|
||||
static void reset_memory_regions PARAMS ((void));
|
||||
static void lang_record_phdrs PARAMS ((void));
|
||||
static void lang_gc_wild_section
|
||||
PARAMS ((lang_wild_statement_type *, const char *,
|
||||
lang_input_statement_type *));
|
||||
static void lang_gc_wild_file
|
||||
PARAMS ((lang_wild_statement_type *, const char *,
|
||||
lang_input_statement_type *));
|
||||
static void lang_gc_wild
|
||||
PARAMS ((lang_wild_statement_type *, const char *, const char *));
|
||||
static void lang_gc_sections_1 PARAMS ((lang_statement_union_type *));
|
||||
static void lang_gc_sections PARAMS ((void));
|
||||
static void lang_do_version_exports_section PARAMS ((void));
|
||||
static void lang_check_section_addresses PARAMS ((void));
|
||||
|
||||
|
||||
typedef void (*callback_t) PARAMS ((lang_wild_statement_type *,
|
||||
asection *, lang_input_statement_type *,
|
||||
void *));
|
||||
static void walk_wild_section
|
||||
PARAMS ((lang_wild_statement_type *, const char *,
|
||||
lang_input_statement_type *, callback_t, void *));
|
||||
static void walk_wild_file
|
||||
PARAMS ((lang_wild_statement_type *, const char *,
|
||||
lang_input_statement_type *, callback_t, void *));
|
||||
|
||||
/* EXPORTS */
|
||||
lang_output_section_statement_type *abs_output_section;
|
||||
lang_statement_list_type *stat_ptr = &statement_list;
|
||||
@ -192,6 +188,142 @@ stat_alloc (size)
|
||||
return obstack_alloc (&stat_obstack, size);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
Generic traversal routines for finding matching sections.
|
||||
*/
|
||||
|
||||
static void
|
||||
walk_wild_section (ptr, section, file, callback, data)
|
||||
lang_wild_statement_type *ptr;
|
||||
const char *section;
|
||||
lang_input_statement_type *file;
|
||||
callback_t callback;
|
||||
void *data;
|
||||
{
|
||||
/* Don't process sections from files which were excluded. */
|
||||
if (ptr->exclude_filename != NULL)
|
||||
{
|
||||
boolean match;
|
||||
|
||||
if (wildcardp (ptr->exclude_filename))
|
||||
match = fnmatch (ptr->exclude_filename, file->filename, 0) == 0 ? true : false;
|
||||
else
|
||||
match = strcmp (ptr->exclude_filename, file->filename) == 0 ? true : false;
|
||||
|
||||
if (match)
|
||||
return;
|
||||
}
|
||||
|
||||
if (file->just_syms_flag == false)
|
||||
{
|
||||
register asection *s;
|
||||
boolean wildcard;
|
||||
|
||||
if (section == NULL)
|
||||
wildcard = false;
|
||||
else
|
||||
wildcard = wildcardp (section);
|
||||
|
||||
for (s = file->the_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
boolean match;
|
||||
|
||||
if (section == NULL)
|
||||
match = true;
|
||||
else
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = bfd_get_section_name (file->the_bfd, s);
|
||||
if (wildcard)
|
||||
match = fnmatch (section, name, 0) == 0 ? true : false;
|
||||
else
|
||||
match = strcmp (section, name) == 0 ? true : false;
|
||||
}
|
||||
|
||||
if (match)
|
||||
(*callback) (ptr, s, file, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle a wild statement for a single file F. */
|
||||
|
||||
static void
|
||||
walk_wild_file (s, section, f, callback, data)
|
||||
lang_wild_statement_type *s;
|
||||
const char *section;
|
||||
lang_input_statement_type *f;
|
||||
callback_t callback;
|
||||
void *data;
|
||||
{
|
||||
if (f->the_bfd == NULL
|
||||
|| ! bfd_check_format (f->the_bfd, bfd_archive))
|
||||
walk_wild_section (s, section, f, callback, data);
|
||||
else
|
||||
{
|
||||
bfd *member;
|
||||
|
||||
/* This is an archive file. We must map each member of the
|
||||
archive separately. */
|
||||
member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL);
|
||||
while (member != NULL)
|
||||
{
|
||||
/* When lookup_name is called, it will call the add_symbols
|
||||
entry point for the archive. For each element of the
|
||||
archive which is included, BFD will call ldlang_add_file,
|
||||
which will set the usrdata field of the member to the
|
||||
lang_input_statement. */
|
||||
if (member->usrdata != NULL)
|
||||
{
|
||||
walk_wild_section (s, section,
|
||||
(lang_input_statement_type *) member->usrdata,
|
||||
callback, data);
|
||||
}
|
||||
|
||||
member = bfd_openr_next_archived_file (f->the_bfd, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
walk_wild (s, section, file, callback, data)
|
||||
lang_wild_statement_type *s;
|
||||
const char *section;
|
||||
const char *file;
|
||||
callback_t callback;
|
||||
void *data;
|
||||
{
|
||||
lang_input_statement_type *f;
|
||||
|
||||
if (file == (char *) NULL)
|
||||
{
|
||||
/* Perform the iteration over all files in the list. */
|
||||
for (f = (lang_input_statement_type *) file_chain.head;
|
||||
f != (lang_input_statement_type *) NULL;
|
||||
f = (lang_input_statement_type *) f->next)
|
||||
{
|
||||
walk_wild_file (s, section, f, callback, data);
|
||||
}
|
||||
}
|
||||
else if (wildcardp (file))
|
||||
{
|
||||
for (f = (lang_input_statement_type *) file_chain.head;
|
||||
f != (lang_input_statement_type *) NULL;
|
||||
f = (lang_input_statement_type *) f->next)
|
||||
{
|
||||
if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0)
|
||||
walk_wild_file (s, section, f, callback, data);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform the iteration over a single file. */
|
||||
f = lookup_name (file);
|
||||
walk_wild_file (s, section, f, callback, data);
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------
|
||||
lang_for_each_statement walks the parse tree and calls the provided
|
||||
function for each node
|
||||
@ -1070,104 +1202,53 @@ wild_sort (wild, file, section)
|
||||
NULL, in which case it is a wild card. */
|
||||
|
||||
static void
|
||||
wild_section (ptr, section, file, output)
|
||||
output_section_callback (ptr, section, file, output)
|
||||
lang_wild_statement_type *ptr;
|
||||
const char *section;
|
||||
asection *section;
|
||||
lang_input_statement_type *file;
|
||||
lang_output_section_statement_type *output;
|
||||
void *output;
|
||||
{
|
||||
|
||||
/* Don't process sections from files which were excluded. */
|
||||
if (ptr->exclude_filename != NULL)
|
||||
lang_statement_union_type *before;
|
||||
|
||||
/* If the wild pattern was marked KEEP, the member sections
|
||||
should be as well. */
|
||||
if (ptr->keep_sections)
|
||||
section->flags |= SEC_KEEP;
|
||||
|
||||
before = wild_sort (ptr, file, section);
|
||||
|
||||
/* Here BEFORE points to the lang_input_section which
|
||||
should follow the one we are about to add. If BEFORE
|
||||
is NULL, then the section should just go at the end
|
||||
of the current list. */
|
||||
|
||||
if (before == NULL)
|
||||
wild_doit (&ptr->children, section,
|
||||
(lang_output_section_statement_type *) output,
|
||||
file);
|
||||
else
|
||||
{
|
||||
boolean match;
|
||||
|
||||
if (wildcardp (ptr->exclude_filename))
|
||||
match = fnmatch (ptr->exclude_filename, file->filename, 0) == 0 ? true : false;
|
||||
else
|
||||
match = strcmp (ptr->exclude_filename, file->filename) == 0 ? true : false;
|
||||
|
||||
if (match)
|
||||
return;
|
||||
}
|
||||
|
||||
if (file->just_syms_flag == false)
|
||||
{
|
||||
register asection *s;
|
||||
boolean wildcard;
|
||||
|
||||
if (section == NULL)
|
||||
wildcard = false;
|
||||
else
|
||||
wildcard = wildcardp (section);
|
||||
|
||||
for (s = file->the_bfd->sections; s != NULL; s = s->next)
|
||||
lang_statement_list_type list;
|
||||
lang_statement_union_type **pp;
|
||||
|
||||
lang_list_init (&list);
|
||||
wild_doit (&list, section,
|
||||
(lang_output_section_statement_type *) output,
|
||||
file);
|
||||
|
||||
/* If we are discarding the section, LIST.HEAD will
|
||||
be NULL. */
|
||||
if (list.head != NULL)
|
||||
{
|
||||
boolean match;
|
||||
|
||||
/* Attach all sections named SECTION. If SECTION is NULL,
|
||||
then attach all sections.
|
||||
|
||||
Previously, if SECTION was NULL, this code did not call
|
||||
wild_doit if the SEC_IS_COMMON flag was set for the
|
||||
section. I did not understand that, and I took it out.
|
||||
--ian@cygnus.com. */
|
||||
|
||||
if (section == NULL)
|
||||
match = true;
|
||||
else
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = bfd_get_section_name (file->the_bfd, s);
|
||||
if (wildcard)
|
||||
match = fnmatch (section, name, 0) == 0 ? true : false;
|
||||
else
|
||||
match = strcmp (section, name) == 0 ? true : false;
|
||||
}
|
||||
|
||||
if (match)
|
||||
{
|
||||
lang_statement_union_type *before;
|
||||
|
||||
/* If the wild pattern was marked KEEP, the member sections
|
||||
should be as well. */
|
||||
if (ptr->keep_sections)
|
||||
s->flags |= SEC_KEEP;
|
||||
|
||||
before = wild_sort (ptr, file, s);
|
||||
|
||||
/* Here BEFORE points to the lang_input_section which
|
||||
should follow the one we are about to add. If BEFORE
|
||||
is NULL, then the section should just go at the end
|
||||
of the current list. */
|
||||
|
||||
if (before == NULL)
|
||||
wild_doit (&ptr->children, s, output, file);
|
||||
else
|
||||
{
|
||||
lang_statement_list_type list;
|
||||
lang_statement_union_type **pp;
|
||||
|
||||
lang_list_init (&list);
|
||||
wild_doit (&list, s, output, file);
|
||||
|
||||
/* If we are discarding the section, LIST.HEAD will
|
||||
be NULL. */
|
||||
if (list.head != NULL)
|
||||
{
|
||||
ASSERT (list.head->next == NULL);
|
||||
|
||||
for (pp = &ptr->children.head;
|
||||
*pp != before;
|
||||
pp = &(*pp)->next)
|
||||
ASSERT (*pp != NULL);
|
||||
|
||||
list.head->next = *pp;
|
||||
*pp = list.head;
|
||||
}
|
||||
}
|
||||
}
|
||||
ASSERT (list.head->next == NULL);
|
||||
|
||||
for (pp = &ptr->children.head;
|
||||
*pp != before;
|
||||
pp = &(*pp)->next)
|
||||
ASSERT (*pp != NULL);
|
||||
|
||||
list.head->next = *pp;
|
||||
*pp = list.head;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1320,43 +1401,7 @@ load_symbols (entry, place)
|
||||
entry->loaded = true;
|
||||
}
|
||||
|
||||
/* Handle a wild statement for a single file F. */
|
||||
|
||||
static void
|
||||
wild_file (s, section, f, output)
|
||||
lang_wild_statement_type *s;
|
||||
const char *section;
|
||||
lang_input_statement_type *f;
|
||||
lang_output_section_statement_type *output;
|
||||
{
|
||||
if (f->the_bfd == NULL
|
||||
|| ! bfd_check_format (f->the_bfd, bfd_archive))
|
||||
wild_section (s, section, f, output);
|
||||
else
|
||||
{
|
||||
bfd *member;
|
||||
|
||||
/* This is an archive file. We must map each member of the
|
||||
archive separately. */
|
||||
member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL);
|
||||
while (member != NULL)
|
||||
{
|
||||
/* When lookup_name is called, it will call the add_symbols
|
||||
entry point for the archive. For each element of the
|
||||
archive which is included, BFD will call ldlang_add_file,
|
||||
which will set the usrdata field of the member to the
|
||||
lang_input_statement. */
|
||||
if (member->usrdata != NULL)
|
||||
{
|
||||
wild_section (s, section,
|
||||
(lang_input_statement_type *) member->usrdata,
|
||||
output);
|
||||
}
|
||||
|
||||
member = bfd_openr_next_archived_file (f->the_bfd, member);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Handle a wild statement. SECTION or FILE or both may be NULL,
|
||||
indicating that it is a wildcard. Separate lang_input_section
|
||||
@ -1371,34 +1416,7 @@ wild (s, section, file, target, output)
|
||||
const char *target;
|
||||
lang_output_section_statement_type *output;
|
||||
{
|
||||
lang_input_statement_type *f;
|
||||
|
||||
if (file == (char *) NULL)
|
||||
{
|
||||
/* Perform the iteration over all files in the list */
|
||||
for (f = (lang_input_statement_type *) file_chain.head;
|
||||
f != (lang_input_statement_type *) NULL;
|
||||
f = (lang_input_statement_type *) f->next)
|
||||
{
|
||||
wild_file (s, section, f, output);
|
||||
}
|
||||
}
|
||||
else if (wildcardp (file))
|
||||
{
|
||||
for (f = (lang_input_statement_type *) file_chain.head;
|
||||
f != (lang_input_statement_type *) NULL;
|
||||
f = (lang_input_statement_type *) f->next)
|
||||
{
|
||||
if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0)
|
||||
wild_file (s, section, f, output);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform the iteration over a single file */
|
||||
f = lookup_name (file);
|
||||
wild_file (s, section, f, output);
|
||||
}
|
||||
walk_wild (s, section, file, output_section_callback, (void *) output);
|
||||
|
||||
if (section != (char *) NULL
|
||||
&& strcmp (section, "COMMON") == 0
|
||||
@ -3487,90 +3505,20 @@ reset_memory_regions ()
|
||||
}
|
||||
}
|
||||
|
||||
/* ??? At some point this traversal for GC should share code with the
|
||||
traversal for manipulating the output file. */
|
||||
|
||||
/* Expand a wild statement for a particular FILE, marking its sections KEEP
|
||||
as needed. SECTION may be NULL, in which case it is a wild card. */
|
||||
|
||||
static void
|
||||
lang_gc_wild_section (ptr, section, file)
|
||||
gc_section_callback (ptr, section, file, data)
|
||||
lang_wild_statement_type *ptr;
|
||||
const char *section;
|
||||
asection *section;
|
||||
lang_input_statement_type *file;
|
||||
void *data;
|
||||
{
|
||||
if (file->just_syms_flag == false)
|
||||
{
|
||||
register asection *s;
|
||||
boolean wildcard;
|
||||
|
||||
if (section == NULL)
|
||||
wildcard = false;
|
||||
else
|
||||
wildcard = wildcardp (section);
|
||||
|
||||
for (s = file->the_bfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
boolean match;
|
||||
|
||||
if (section == NULL)
|
||||
match = true;
|
||||
else
|
||||
{
|
||||
const char *name;
|
||||
|
||||
name = bfd_get_section_name (file->the_bfd, s);
|
||||
if (wildcard)
|
||||
match = fnmatch (section, name, 0) == 0 ? true : false;
|
||||
else
|
||||
match = strcmp (section, name) == 0 ? true : false;
|
||||
}
|
||||
|
||||
if (match)
|
||||
{
|
||||
/* If the wild pattern was marked KEEP, the member sections
|
||||
should be as well. */
|
||||
if (ptr->keep_sections)
|
||||
s->flags |= SEC_KEEP;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle a wild statement for a single file F. */
|
||||
|
||||
static void
|
||||
lang_gc_wild_file (s, section, f)
|
||||
lang_wild_statement_type *s;
|
||||
const char *section;
|
||||
lang_input_statement_type *f;
|
||||
{
|
||||
if (f->the_bfd == NULL
|
||||
|| ! bfd_check_format (f->the_bfd, bfd_archive))
|
||||
lang_gc_wild_section (s, section, f);
|
||||
else
|
||||
{
|
||||
bfd *member;
|
||||
|
||||
/* This is an archive file. We must map each member of the
|
||||
archive separately. */
|
||||
member = bfd_openr_next_archived_file (f->the_bfd, (bfd *) NULL);
|
||||
while (member != NULL)
|
||||
{
|
||||
/* When lookup_name is called, it will call the add_symbols
|
||||
entry point for the archive. For each element of the
|
||||
archive which is included, BFD will call ldlang_add_file,
|
||||
which will set the usrdata field of the member to the
|
||||
lang_input_statement. */
|
||||
if (member->usrdata != NULL)
|
||||
{
|
||||
lang_gc_wild_section (s, section,
|
||||
(lang_input_statement_type *) member->usrdata);
|
||||
}
|
||||
|
||||
member = bfd_openr_next_archived_file (f->the_bfd, member);
|
||||
}
|
||||
}
|
||||
/* If the wild pattern was marked KEEP, the member sections
|
||||
should be as well. */
|
||||
if (ptr->keep_sections)
|
||||
section->flags |= SEC_KEEP;
|
||||
}
|
||||
|
||||
/* Handle a wild statement, marking it against GC. SECTION or FILE or both
|
||||
@ -3582,34 +3530,7 @@ lang_gc_wild (s, section, file)
|
||||
const char *section;
|
||||
const char *file;
|
||||
{
|
||||
lang_input_statement_type *f;
|
||||
|
||||
if (file == (char *) NULL)
|
||||
{
|
||||
/* Perform the iteration over all files in the list */
|
||||
for (f = (lang_input_statement_type *) file_chain.head;
|
||||
f != (lang_input_statement_type *) NULL;
|
||||
f = (lang_input_statement_type *) f->next)
|
||||
{
|
||||
lang_gc_wild_file (s, section, f);
|
||||
}
|
||||
}
|
||||
else if (wildcardp (file))
|
||||
{
|
||||
for (f = (lang_input_statement_type *) file_chain.head;
|
||||
f != (lang_input_statement_type *) NULL;
|
||||
f = (lang_input_statement_type *) f->next)
|
||||
{
|
||||
if (fnmatch (file, f->filename, FNM_FILE_NAME) == 0)
|
||||
lang_gc_wild_file (s, section, f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Perform the iteration over a single file */
|
||||
f = lookup_name (file);
|
||||
lang_gc_wild_file (s, section, f);
|
||||
}
|
||||
walk_wild (s, section, file, gc_section_callback, NULL);
|
||||
}
|
||||
|
||||
/* Iterate over sections marking them against GC. */
|
||||
|
Loading…
Reference in New Issue
Block a user