include/
* bfdlink.h (struct bfd_link_info): Add "path_separator". bfd/ * elf32-spu.c (spu_elf_auto_overlay): Relax requirement that file names be unique. Specify archive:path in overlay script. ld/ * ldlang.c (name_match): New function. (unique_section_p, walk_wild_consider_section): Use it here. (walk_wild_section_general): And here. (archive_path): New function. (walk_wild): Match archive:path filespecs. (open_input_bfds): Don't load archive:path files. * emultempl/spuelf.em (choose_target): Set path_separator. * emulparams/elf32_spu.sh: Add ._ea.* sections to ._ea output.
This commit is contained in:
parent
a2b87ed119
commit
97407faf3d
@ -1,3 +1,8 @@
|
||||
2008-06-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* elf32-spu.c (spu_elf_auto_overlay): Relax requirement that
|
||||
file names be unique. Specify archive:path in overlay script.
|
||||
|
||||
2008-06-05 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
PR ld/6590
|
||||
|
@ -3544,37 +3544,20 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
|
||||
for (i = 1; i < bfd_count; ++i)
|
||||
if (strcmp (bfd_arr[i - 1]->filename, bfd_arr[i]->filename) == 0)
|
||||
{
|
||||
if (bfd_arr[i - 1]->my_archive && bfd_arr[i]->my_archive)
|
||||
if (bfd_arr[i - 1]->my_archive == bfd_arr[i]->my_archive)
|
||||
{
|
||||
if (bfd_arr[i - 1]->my_archive == bfd_arr[i]->my_archive)
|
||||
if (bfd_arr[i - 1]->my_archive && bfd_arr[i]->my_archive)
|
||||
info->callbacks->einfo (_("%s duplicated in %s\n"),
|
||||
bfd_arr[i - 1]->filename,
|
||||
bfd_arr[i - 1]->my_archive->filename);
|
||||
else
|
||||
info->callbacks->einfo (_("%s in both %s and %s\n"),
|
||||
bfd_arr[i - 1]->filename,
|
||||
bfd_arr[i - 1]->my_archive->filename,
|
||||
bfd_arr[i]->filename,
|
||||
bfd_arr[i]->my_archive->filename);
|
||||
else
|
||||
info->callbacks->einfo (_("%s duplicated\n"),
|
||||
bfd_arr[i]->filename);
|
||||
ok = FALSE;
|
||||
}
|
||||
else if (bfd_arr[i - 1]->my_archive)
|
||||
info->callbacks->einfo (_("%s in %s and as an object\n"),
|
||||
bfd_arr[i - 1]->filename,
|
||||
bfd_arr[i - 1]->my_archive->filename);
|
||||
else if (bfd_arr[i]->my_archive)
|
||||
info->callbacks->einfo (_("%s in %s and as an object\n"),
|
||||
bfd_arr[i]->filename,
|
||||
bfd_arr[i]->my_archive->filename);
|
||||
else
|
||||
info->callbacks->einfo (_("%s duplicated\n"),
|
||||
bfd_arr[i]->filename);
|
||||
ok = FALSE;
|
||||
}
|
||||
if (!ok)
|
||||
{
|
||||
/* FIXME: modify plain object files from foo.o to ./foo.o
|
||||
and emit EXCLUDE_FILE to handle the duplicates in
|
||||
archives. There is a pathological case we can't handle:
|
||||
We may have duplicate file names within a single archive. */
|
||||
info->callbacks->einfo (_("sorry, no support for duplicate "
|
||||
"object files in auto-overlay script\n"));
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
@ -3750,9 +3733,11 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
|
||||
{
|
||||
asection *sec = ovly_sections[2 * j];
|
||||
|
||||
if (fprintf (script, " [%c]%s (%s)\n",
|
||||
sec->owner->filename[0],
|
||||
sec->owner->filename + 1,
|
||||
if (fprintf (script, " %s%c%s (%s)\n",
|
||||
(sec->owner->my_archive != NULL
|
||||
? sec->owner->my_archive->filename : ""),
|
||||
info->path_separator,
|
||||
sec->owner->filename,
|
||||
sec->name) <= 0)
|
||||
goto file_err;
|
||||
if (sec->segment_mark)
|
||||
@ -3762,9 +3747,11 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
|
||||
{
|
||||
struct function_info *call_fun = call->fun;
|
||||
sec = call_fun->sec;
|
||||
if (fprintf (script, " [%c]%s (%s)\n",
|
||||
sec->owner->filename[0],
|
||||
sec->owner->filename + 1,
|
||||
if (fprintf (script, " %s%c%s (%s)\n",
|
||||
(sec->owner->my_archive != NULL
|
||||
? sec->owner->my_archive->filename : ""),
|
||||
info->path_separator,
|
||||
sec->owner->filename,
|
||||
sec->name) <= 0)
|
||||
goto file_err;
|
||||
for (call = call_fun->call_list; call; call = call->next)
|
||||
@ -3777,10 +3764,13 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
|
||||
for (j = base; j < i; j++)
|
||||
{
|
||||
asection *sec = ovly_sections[2 * j + 1];
|
||||
if (sec != NULL && fprintf (script, " [%c]%s (%s)\n",
|
||||
sec->owner->filename[0],
|
||||
sec->owner->filename + 1,
|
||||
sec->name) <= 0)
|
||||
if (sec != NULL
|
||||
&& fprintf (script, " %s%c%s (%s)\n",
|
||||
(sec->owner->my_archive != NULL
|
||||
? sec->owner->my_archive->filename : ""),
|
||||
info->path_separator,
|
||||
sec->owner->filename,
|
||||
sec->name) <= 0)
|
||||
goto file_err;
|
||||
|
||||
sec = ovly_sections[2 * j];
|
||||
@ -3791,10 +3781,13 @@ spu_elf_auto_overlay (struct bfd_link_info *info,
|
||||
{
|
||||
struct function_info *call_fun = call->fun;
|
||||
sec = call_fun->rodata;
|
||||
if (sec != NULL && fprintf (script, " [%c]%s (%s)\n",
|
||||
sec->owner->filename[0],
|
||||
sec->owner->filename + 1,
|
||||
sec->name) <= 0)
|
||||
if (sec != NULL
|
||||
&& fprintf (script, " %s%c%s (%s)\n",
|
||||
(sec->owner->my_archive != NULL
|
||||
? sec->owner->my_archive->filename : ""),
|
||||
info->path_separator,
|
||||
sec->owner->filename,
|
||||
sec->name) <= 0)
|
||||
goto file_err;
|
||||
for (call = call_fun->call_list; call; call = call->next)
|
||||
if (call->is_pasted)
|
||||
|
@ -1,3 +1,7 @@
|
||||
2008-06-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* bfdlink.h (struct bfd_link_info): Add "path_separator".
|
||||
|
||||
2008-04-10 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||
|
||||
* dis-asm.h (print_s390_disassembler_options):
|
||||
|
@ -372,6 +372,9 @@ struct bfd_link_info
|
||||
wrap_hash. Used by PowerPC Linux for 'dot' symbols. */
|
||||
char wrap_char;
|
||||
|
||||
/* Separator between archive and filename in linker script filespecs. */
|
||||
char path_separator;
|
||||
|
||||
/* Function callbacks. */
|
||||
const struct bfd_link_callbacks *callbacks;
|
||||
|
||||
|
11
ld/ChangeLog
11
ld/ChangeLog
@ -1,3 +1,14 @@
|
||||
2008-06-06 Alan Modra <amodra@bigpond.net.au>
|
||||
|
||||
* ldlang.c (name_match): New function.
|
||||
(unique_section_p, walk_wild_consider_section): Use it here.
|
||||
(walk_wild_section_general): And here.
|
||||
(archive_path): New function.
|
||||
(walk_wild): Match archive:path filespecs.
|
||||
(open_input_bfds): Don't load archive:path files.
|
||||
* emultempl/spuelf.em (choose_target): Set path_separator.
|
||||
* emulparams/elf32_spu.sh: Add ._ea.* sections to ._ea output.
|
||||
|
||||
2008-06-04 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* ld.texinfo (Orphan Sections): Fix texi typo.
|
||||
|
@ -18,4 +18,4 @@ MAXPAGESIZE=0x80
|
||||
DATA_ADDR="ALIGN(${MAXPAGESIZE})"
|
||||
OTHER_BSS_SECTIONS=".toe ALIGN(128) : { *(.toe) } = 0"
|
||||
OTHER_SECTIONS=".note.spu_name 0 : { KEEP(*(.note.spu_name)) }
|
||||
._ea 0 : { KEEP(*(._ea)) }"
|
||||
._ea 0 : { KEEP(*(._ea)) KEEP(*(._ea.*)) }"
|
||||
|
@ -350,6 +350,7 @@ gld${EMULATION_NAME}_finish (void)
|
||||
static char *
|
||||
gld${EMULATION_NAME}_choose_target (int argc, char *argv[])
|
||||
{
|
||||
link_info.path_separator = ':';
|
||||
my_argc = argc;
|
||||
my_argv = argv;
|
||||
return ldemul_default_target (argc, argv);
|
||||
|
90
ld/ldlang.c
90
ld/ldlang.c
@ -134,6 +134,38 @@ stat_alloc (size_t size)
|
||||
return obstack_alloc (&stat_obstack, size);
|
||||
}
|
||||
|
||||
static int
|
||||
name_match (const char *pattern, const char *name)
|
||||
{
|
||||
if (wildcardp (pattern))
|
||||
return fnmatch (pattern, name, 0);
|
||||
return strcmp (pattern, name);
|
||||
}
|
||||
|
||||
/* If PATTERN is of the form archive:file, return a pointer to the
|
||||
separator. If not, return NULL. */
|
||||
|
||||
static char *
|
||||
archive_path (const char *pattern)
|
||||
{
|
||||
char *p = NULL;
|
||||
|
||||
if (link_info.path_separator == 0)
|
||||
return p;
|
||||
|
||||
p = strchr (pattern, link_info.path_separator);
|
||||
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
|
||||
if (p == NULL || link_info.path_separator != ':')
|
||||
return p;
|
||||
|
||||
/* Assume a match on the second char is part of drive specifier,
|
||||
as in "c:\silly.dos". */
|
||||
if (p == pattern + 1)
|
||||
p = strchr (p + 1, link_info.path_separator);
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
unique_section_p (const asection *sec)
|
||||
{
|
||||
@ -147,12 +179,8 @@ unique_section_p (const asection *sec)
|
||||
|
||||
secnam = sec->name;
|
||||
for (unam = unique_section_list; unam; unam = unam->next)
|
||||
if (wildcardp (unam->name)
|
||||
? fnmatch (unam->name, secnam, 0) == 0
|
||||
: strcmp (unam->name, secnam) == 0)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
if (name_match (unam->name, secnam) == 0)
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
@ -175,17 +203,12 @@ walk_wild_consider_section (lang_wild_statement_type *ptr,
|
||||
bfd_boolean skip = FALSE;
|
||||
struct name_list *list_tmp;
|
||||
|
||||
/* Don't process sections from files which were
|
||||
excluded. */
|
||||
/* Don't process sections from files which were excluded. */
|
||||
for (list_tmp = sec->spec.exclude_name_list;
|
||||
list_tmp;
|
||||
list_tmp = list_tmp->next)
|
||||
{
|
||||
bfd_boolean is_wildcard = wildcardp (list_tmp->name);
|
||||
if (is_wildcard)
|
||||
skip = fnmatch (list_tmp->name, file->filename, 0) == 0;
|
||||
else
|
||||
skip = strcmp (list_tmp->name, file->filename) == 0;
|
||||
skip = name_match (list_tmp->name, file->filename) == 0;
|
||||
|
||||
/* If this file is part of an archive, and the archive is
|
||||
excluded, exclude this file. */
|
||||
@ -193,13 +216,8 @@ walk_wild_consider_section (lang_wild_statement_type *ptr,
|
||||
&& file->the_bfd->my_archive != NULL
|
||||
&& file->the_bfd->my_archive->filename != NULL)
|
||||
{
|
||||
if (is_wildcard)
|
||||
skip = fnmatch (list_tmp->name,
|
||||
file->the_bfd->my_archive->filename,
|
||||
0) == 0;
|
||||
else
|
||||
skip = strcmp (list_tmp->name,
|
||||
file->the_bfd->my_archive->filename) == 0;
|
||||
skip = name_match (list_tmp->name,
|
||||
file->the_bfd->my_archive->filename) == 0;
|
||||
}
|
||||
|
||||
if (skip)
|
||||
@ -236,10 +254,7 @@ walk_wild_section_general (lang_wild_statement_type *ptr,
|
||||
{
|
||||
const char *sname = bfd_get_section_name (file->the_bfd, s);
|
||||
|
||||
if (wildcardp (sec->spec.name))
|
||||
skip = fnmatch (sec->spec.name, sname, 0) != 0;
|
||||
else
|
||||
skip = strcmp (sec->spec.name, sname) != 0;
|
||||
skip = name_match (sec->spec.name, sname) != 0;
|
||||
}
|
||||
|
||||
if (!skip)
|
||||
@ -780,6 +795,7 @@ static void
|
||||
walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
|
||||
{
|
||||
const char *file_spec = s->filename;
|
||||
char *p;
|
||||
|
||||
if (file_spec == NULL)
|
||||
{
|
||||
@ -789,6 +805,29 @@ walk_wild (lang_wild_statement_type *s, callback_t callback, void *data)
|
||||
walk_wild_file (s, f, callback, data);
|
||||
}
|
||||
}
|
||||
else if ((p = archive_path (file_spec)) != NULL)
|
||||
{
|
||||
LANG_FOR_EACH_INPUT_STATEMENT (f)
|
||||
{
|
||||
if ((*(p + 1) == 0
|
||||
|| name_match (p + 1, f->filename) == 0)
|
||||
&& ((p != file_spec)
|
||||
== (f->the_bfd != NULL && f->the_bfd->my_archive != NULL)))
|
||||
{
|
||||
bfd_boolean skip = FALSE;
|
||||
|
||||
if (p != file_spec)
|
||||
{
|
||||
const char *aname = f->the_bfd->my_archive->filename;
|
||||
*p = 0;
|
||||
skip = name_match (file_spec, aname) != 0;
|
||||
*p = link_info.path_separator;
|
||||
}
|
||||
if (!skip)
|
||||
walk_wild_file (s, f, callback, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (wildcardp (file_spec))
|
||||
{
|
||||
LANG_FOR_EACH_INPUT_STATEMENT (f)
|
||||
@ -2931,7 +2970,8 @@ open_input_bfds (lang_statement_union_type *s, bfd_boolean force)
|
||||
case lang_wild_statement_enum:
|
||||
/* Maybe we should load the file's symbols. */
|
||||
if (s->wild_statement.filename
|
||||
&& ! wildcardp (s->wild_statement.filename))
|
||||
&& !wildcardp (s->wild_statement.filename)
|
||||
&& !archive_path (s->wild_statement.filename))
|
||||
lookup_name (s->wild_statement.filename);
|
||||
open_input_bfds (s->wild_statement.children.head, force);
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user