From 97407faf3da58e5e3bd1d042e746d8e328b00ce3 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 6 Jun 2008 06:02:00 +0000 Subject: [PATCH] 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. --- bfd/ChangeLog | 5 +++ bfd/elf32-spu.c | 69 ++++++++++++++++------------------- include/ChangeLog | 4 +++ include/bfdlink.h | 3 ++ ld/ChangeLog | 11 ++++++ ld/emulparams/elf32_spu.sh | 2 +- ld/emultempl/spuelf.em | 1 + ld/ldlang.c | 90 +++++++++++++++++++++++++++++++++------------- 8 files changed, 121 insertions(+), 64 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 470e3a2..b725c3c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,8 @@ +2008-06-06 Alan Modra + + * 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 PR ld/6590 diff --git a/bfd/elf32-spu.c b/bfd/elf32-spu.c index e6e0093..e11e1d7 100644 --- a/bfd/elf32-spu.c +++ b/bfd/elf32-spu.c @@ -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) diff --git a/include/ChangeLog b/include/ChangeLog index 9b0140c..4e399f3 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2008-06-06 Alan Modra + + * bfdlink.h (struct bfd_link_info): Add "path_separator". + 2008-04-10 Andreas Krebbel * dis-asm.h (print_s390_disassembler_options): diff --git a/include/bfdlink.h b/include/bfdlink.h index bcd4b4f..e683310 100644 --- a/include/bfdlink.h +++ b/include/bfdlink.h @@ -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; diff --git a/ld/ChangeLog b/ld/ChangeLog index e724aa9..228d15f 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,14 @@ +2008-06-06 Alan Modra + + * 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 * ld.texinfo (Orphan Sections): Fix texi typo. diff --git a/ld/emulparams/elf32_spu.sh b/ld/emulparams/elf32_spu.sh index 52a3e7b..8248d5d 100644 --- a/ld/emulparams/elf32_spu.sh +++ b/ld/emulparams/elf32_spu.sh @@ -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.*)) }" diff --git a/ld/emultempl/spuelf.em b/ld/emultempl/spuelf.em index a56d78f..3c8b7d3 100644 --- a/ld/emultempl/spuelf.em +++ b/ld/emultempl/spuelf.em @@ -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); diff --git a/ld/ldlang.c b/ld/ldlang.c index c8aac29..8cf486e 100644 --- a/ld/ldlang.c +++ b/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; -- 2.7.4