diff options
-rw-r--r-- | binutils/ChangeLog | 6 | ||||
-rw-r--r-- | binutils/objcopy.c | 46 |
2 files changed, 37 insertions, 15 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog index b711b7e..08ea5c3 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2006-09-14 Alan Modra <amodra@bigpond.net.au> + + PR 3182 + * objcopy.c (copy_object): Load symbols earlier. + (setup_section): Mark group signature symbols with BSF_KEEP. + 2006-09-09 Nick Clifton <nickc@redhat.com> PR binutils/3110 diff --git a/binutils/objcopy.c b/binutils/objcopy.c index 2e2ccef..1510ac4 100644 --- a/binutils/objcopy.c +++ b/binutils/objcopy.c @@ -1325,6 +1325,21 @@ copy_object (bfd *ibfd, bfd *obfd) isympp = NULL; osympp = NULL; + symsize = bfd_get_symtab_upper_bound (ibfd); + if (symsize < 0) + { + bfd_nonfatal (bfd_get_archive_filename (ibfd)); + return FALSE; + } + + osympp = isympp = xmalloc (symsize); + symcount = bfd_canonicalize_symtab (ibfd, isympp); + if (symcount < 0) + { + bfd_nonfatal (bfd_get_filename (ibfd)); + return FALSE; + } + /* BFD mandates that all output sections be created and sizes set before any output is done. Thus, we traverse all sections multiple times. */ bfd_map_over_sections (ibfd, setup_section, obfd); @@ -1544,21 +1559,6 @@ copy_object (bfd *ibfd, bfd *obfd) /* Symbol filtering must happen after the output sections have been created, but before their contents are set. */ dhandle = NULL; - symsize = bfd_get_symtab_upper_bound (ibfd); - if (symsize < 0) - { - bfd_nonfatal (bfd_get_archive_filename (ibfd)); - return FALSE; - } - - osympp = isympp = xmalloc (symsize); - symcount = bfd_canonicalize_symtab (ibfd, isympp); - if (symcount < 0) - { - bfd_nonfatal (bfd_get_filename (ibfd)); - return FALSE; - } - if (convert_debugging) dhandle = read_debugging_info (ibfd, isympp, symcount); @@ -2214,6 +2214,22 @@ setup_section (bfd *ibfd, sec_ptr isection, void *obfdarg) err = _("private data"); goto loser; } + else if ((isection->flags & SEC_GROUP) != 0 + && bfd_get_flavour (ibfd) == bfd_target_elf_flavour) + { + Elf_Internal_Shdr *ghdr; + + ghdr = &elf_section_data (isection)->this_hdr; + if (ghdr->sh_link < elf_numsections (ibfd)) + { + const struct elf_backend_data *bed = get_elf_backend_data (ibfd); + Elf_Internal_Shdr *symhdr = elf_elfsections (ibfd) [ghdr->sh_link]; + + if (symhdr->sh_type == SHT_SYMTAB + && ghdr->sh_info < symhdr->sh_size / bed->s->sizeof_sym) + isympp[ghdr->sh_info]->flags |= BSF_KEEP; + } + } /* All went well. */ return; |