From: Nick Clifton Date: Fri, 29 Apr 2016 08:24:42 +0000 (+0100) Subject: Enhance support for copying and stripping Solaris and ARM binaries. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=5522f910cb539905d6adfdceab208ddfa5e84557;p=binutils-gdb.git Enhance support for copying and stripping Solaris and ARM binaries. PR 19938 bfd * elf-bfd.h (struct elf_backend_data): Rename elf_backend_set_special_section_info_and_link to elf_backend_copy_special_section_fields. * elfxx-target.h: Likewise. * elf.c (section_match): Ignore the SHF_INFO_LINK flag when comparing section flags. (copy_special_section_fields): New function. (_bfd_elf_copy_private_bfd_data): Copy the EI_ABIVERSION field. Perform two scans over special sections. The first one looks for a direct mapping between the output section and an input section. The second scan looks for a possible match based upon section characteristics. * elf32-arm.c (elf32_arm_copy_special_section_fields): New function. Handle setting the sh_link field of SHT_ARM_EXIDX sections. * elf32-i386.c (elf32_i386_set_special_info_link): Rename to elf32_i386_copy_solaris_special_section_fields. * elf32-sparc.c (elf32_sparc_set_special_section_info_link): Rename to elf32_sparc_copy_solaris_special_section_fields. * elf64-x86-64.c (elf64_x86_64_set_special_info_link): Rename to elf64_x86_64_copy_solaris_special_section_fields. binutils* readelf.c (get_solaris_segment_type): New function. (get_segment_type): Call it. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d70dd881e7c..f60ee034c38 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,28 @@ +2016-04-29 Nick Clifton + + PR 19938 + * elf-bfd.h (struct elf_backend_data): Rename + elf_backend_set_special_section_info_and_link to + elf_backend_copy_special_section_fields. + * elfxx-target.h: Likewise. + * elf.c (section_match): Ignore the SHF_INFO_LINK flag when + comparing section flags. + (copy_special_section_fields): New function. + (_bfd_elf_copy_private_bfd_data): Copy the EI_ABIVERSION field. + Perform two scans over special sections. The first one looks for + a direct mapping between the output section and an input section. + The second scan looks for a possible match based upon section + characteristics. + * elf32-arm.c (elf32_arm_copy_special_section_fields): New + function. Handle setting the sh_link field of SHT_ARM_EXIDX + sections. + * elf32-i386.c (elf32_i386_set_special_info_link): Rename to + elf32_i386_copy_solaris_special_section_fields. + * elf32-sparc.c (elf32_sparc_set_special_section_info_link): + Rename to elf32_sparc_copy_solaris_special_section_fields. + * elf64-x86-64.c (elf64_x86_64_set_special_info_link): Rename to + elf64_x86_64_copy_solaris_special_section_fields. + 2016-04-28 Nick Clifton * po/zh_CN.po: Updated Chinese (simplified) translation. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 6c05b55b641..9067dd9aea1 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1300,13 +1300,15 @@ struct elf_backend_data /* Return the section which RELOC_SEC applies to. */ asection *(*get_reloc_section) (asection *reloc_sec); - /* Called when setting the sh_link and sh_info fields of a section with a - type >= SHT_LOOS. Returns TRUE if these fields were initialised in - OHEADER, FALSE otherwise. IHEADER is the best guess matching section - from the input bfd IBFD. */ - bfd_boolean (*elf_backend_set_special_section_info_and_link) - (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *iheader, - Elf_Internal_Shdr *oheader); + /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which + has a type >= SHT_LOOS. Returns TRUE if the fields were initialised, + FALSE otherwise. Can be called multiple times for a given section, + until it returns TRUE. Most of the times it is called ISECTION will be + set to an input section that might be associated with the output section. + The last time that it is called, ISECTION will be set to NULL. */ + bfd_boolean (*elf_backend_copy_special_section_fields) + (const bfd *ibfd, bfd *obfd, const Elf_Internal_Shdr *isection, + Elf_Internal_Shdr *osection); /* Used to handle bad SHF_LINK_ORDER input. */ bfd_error_handler_type link_order_error_handler; diff --git a/bfd/elf.c b/bfd/elf.c index 69830ce0b3a..4be7d739739 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1218,11 +1218,13 @@ bfd_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, should be the same. */ static bfd_boolean -section_match (Elf_Internal_Shdr * a, Elf_Internal_Shdr * b) +section_match (const Elf_Internal_Shdr * a, + const Elf_Internal_Shdr * b) { return a->sh_type == b->sh_type - && a->sh_flags == b->sh_flags + && (a->sh_flags & ~ SHF_INFO_LINK) + == (b->sh_flags & ~ SHF_INFO_LINK) && a->sh_addralign == b->sh_addralign && a->sh_size == b->sh_size && a->sh_entsize == b->sh_entsize @@ -1236,7 +1238,7 @@ section_match (Elf_Internal_Shdr * a, Elf_Internal_Shdr * b) to be the correct section. */ static unsigned int -find_link (bfd * obfd, Elf_Internal_Shdr * iheader, unsigned int hint) +find_link (const bfd * obfd, const Elf_Internal_Shdr * iheader, const unsigned int hint) { Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd); unsigned int i; @@ -1257,14 +1259,110 @@ find_link (bfd * obfd, Elf_Internal_Shdr * iheader, unsigned int hint) return SHN_UNDEF; } +/* PR 19938: Attempt to set the ELF section header fields of an OS or + Processor specific section, based upon a matching input section. + Returns TRUE upon success, FALSE otherwise. */ + +static bfd_boolean +copy_special_section_fields (const bfd *ibfd, + bfd *obfd, + const Elf_Internal_Shdr *iheader, + Elf_Internal_Shdr *oheader, + const unsigned int secnum) +{ + const struct elf_backend_data *bed = get_elf_backend_data (obfd); + const Elf_Internal_Shdr **iheaders = (const Elf_Internal_Shdr **) elf_elfsections (ibfd); + bfd_boolean changed = FALSE; + unsigned int sh_link; + + if (oheader->sh_type == SHT_NOBITS) + { + /* This is a feature for objcopy --only-keep-debug: + When a section's type is changed to NOBITS, we preserve + the sh_link and sh_info fields so that they can be + matched up with the original. + + Note: Strictly speaking these assignments are wrong. + The sh_link and sh_info fields should point to the + relevent sections in the output BFD, which may not be in + the same location as they were in the input BFD. But + the whole point of this action is to preserve the + original values of the sh_link and sh_info fields, so + that they can be matched up with the section headers in + the original file. So strictly speaking we may be + creating an invalid ELF file, but it is only for a file + that just contains debug info and only for sections + without any contents. */ + if (oheader->sh_link == 0) + oheader->sh_link = iheader->sh_link; + if (oheader->sh_info == 0) + oheader->sh_info = iheader->sh_info; + return TRUE; + } + + /* Allow the target a chance to decide how these fields should be set. */ + if (bed->elf_backend_copy_special_section_fields != NULL + && bed->elf_backend_copy_special_section_fields + (ibfd, obfd, iheader, oheader)) + return TRUE; + + /* We have an iheader which might match oheader, and which has non-zero + sh_info and/or sh_link fields. Attempt to follow those links and find + the section in the output bfd which corresponds to the linked section + in the input bfd. */ + if (iheader->sh_link != SHN_UNDEF) + { + sh_link = find_link (obfd, iheaders[iheader->sh_link], iheader->sh_link); + if (sh_link != SHN_UNDEF) + { + oheader->sh_link = sh_link; + changed = TRUE; + } + else + /* FIXME: Should we install iheader->sh_link + if we could not find a match ? */ + (* _bfd_error_handler) + (_("%B: Failed to find link section for section %d"), obfd, secnum); + } + + if (iheader->sh_info) + { + /* The sh_info field can hold arbitrary information, but if the + SHF_LINK_INFO flag is set then it should be interpreted as a + section index. */ + if (iheader->sh_flags & SHF_INFO_LINK) + { + sh_link = find_link (obfd, iheaders[iheader->sh_info], + iheader->sh_info); + if (sh_link != SHN_UNDEF) + oheader->sh_flags |= SHF_INFO_LINK; + } + else + /* No idea what it means - just copy it. */ + sh_link = iheader->sh_info; + + if (sh_link != SHN_UNDEF) + { + oheader->sh_info = sh_link; + changed = TRUE; + } + else + (* _bfd_error_handler) + (_("%B: Failed to find info section for section %d"), obfd, secnum); + } + + return changed; +} + /* Copy the program header and other data from one object module to another. */ bfd_boolean _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) { - Elf_Internal_Shdr ** iheaders = elf_elfsections (ibfd); - Elf_Internal_Shdr ** oheaders = elf_elfsections (obfd); + const Elf_Internal_Shdr **iheaders = (const Elf_Internal_Shdr **) elf_elfsections (ibfd); + Elf_Internal_Shdr **oheaders = elf_elfsections (obfd); + const struct elf_backend_data *bed; unsigned int i; if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour @@ -1283,39 +1381,84 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) elf_elfheader (obfd)->e_ident[EI_OSABI] = elf_elfheader (ibfd)->e_ident[EI_OSABI]; + /* If set, copy the EI_ABIVERSION field. */ + if (elf_elfheader (ibfd)->e_ident[EI_ABIVERSION]) + elf_elfheader (obfd)->e_ident[EI_ABIVERSION] + = elf_elfheader (ibfd)->e_ident[EI_ABIVERSION]; + /* Copy object attributes. */ _bfd_elf_copy_obj_attributes (ibfd, obfd); if (iheaders == NULL || oheaders == NULL) return TRUE; - /* Possibly copy the sh_info and sh_link fields. */ + bed = get_elf_backend_data (obfd); + + /* Possibly copy other fields in the section header. */ for (i = 1; i < elf_numsections (obfd); i++) { unsigned int j; Elf_Internal_Shdr * oheader = oheaders[i]; + /* Ignore ordinary sections. SHT_NOBITS sections are considered however + because of a special case need for generating separate debug info + files. See below for more details. */ if (oheader == NULL || (oheader->sh_type != SHT_NOBITS - && oheader->sh_type < SHT_LOOS) - || oheader->sh_size == 0 + && oheader->sh_type < SHT_LOOS)) + continue; + + /* Ignore empty sections, and sections whose + fields have already been initialised. */ + if (oheader->sh_size == 0 || (oheader->sh_info != 0 && oheader->sh_link != 0)) continue; /* Scan for the matching section in the input bfd. - FIXME: We could use something better than a linear scan here. + First we try for a direct mapping between the input and output sections. */ + for (j = 1; j < elf_numsections (ibfd); j++) + { + const Elf_Internal_Shdr * iheader = iheaders[j]; + + if (iheader == NULL) + continue; + + if (oheader->bfd_section != NULL + && iheader->bfd_section != NULL + && iheader->bfd_section->output_section != NULL + && iheader->bfd_section->output_section == oheader->bfd_section) + { + /* We have found a connection from the input section to the + output section. Attempt to copy the header fields. If + this fails then do not try any further sections - there + should only be a one-to-one mapping between input and output. */ + if (! copy_special_section_fields (ibfd, obfd, iheader, oheader, i)) + j = elf_numsections (ibfd); + break; + } + } + + if (j < elf_numsections (ibfd)) + continue; + + /* That failed. So try to deduce the corresponding input section. Unfortunately we cannot compare names as the output string table is empty, so instead we check size, address and type. */ for (j = 1; j < elf_numsections (ibfd); j++) { - Elf_Internal_Shdr * iheader = iheaders[j]; + const Elf_Internal_Shdr * iheader = iheaders[j]; + + if (iheader == NULL) + continue; - /* Since --only-keep-debug turns all non-debug sections into + /* Try matching fields in the input section's header. + Since --only-keep-debug turns all non-debug sections into SHT_NOBITS sections, the output SHT_NOBITS type matches any input type. */ if ((oheader->sh_type == SHT_NOBITS || iheader->sh_type == oheader->sh_type) - && iheader->sh_flags == oheader->sh_flags + && (iheader->sh_flags & ~ SHF_INFO_LINK) + == (oheader->sh_flags & ~ SHF_INFO_LINK) && iheader->sh_addralign == oheader->sh_addralign && iheader->sh_entsize == oheader->sh_entsize && iheader->sh_size == oheader->sh_size @@ -1323,99 +1466,18 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd) && (iheader->sh_info != oheader->sh_info || iheader->sh_link != oheader->sh_link)) { - /* PR 19938: Attempt to preserve the sh_link and sh_info fields - of OS and Processor specific sections. We try harder for - these sections, because this is not just about matching - stripped binaries to their originals. */ - if (oheader->sh_type >= SHT_LOOS) - { - const struct elf_backend_data *bed = get_elf_backend_data (obfd); - bfd_boolean changed = FALSE; - unsigned int sh_link; - - /* Allow the target a chance to decide how these fields should - be set. */ - if (bed->elf_backend_set_special_section_info_and_link != NULL - && bed->elf_backend_set_special_section_info_and_link - (ibfd, obfd, iheader, oheader)) - break; - - /* We have iheader which matches oheader, but which has - non-zero sh_info and/or sh_link fields. Attempt to - follow those links and find the section in the output - bfd which corresponds to the linked section in the input - bfd. */ - if (iheader->sh_link != SHN_UNDEF) - { - sh_link = find_link (obfd, - iheaders[iheader->sh_link], - iheader->sh_link); - if (sh_link != SHN_UNDEF) - { - oheader->sh_link = sh_link; - changed = TRUE; - } - else - /* FIXME: Should we install iheader->sh_link - if we could not find a match ? */ - (* _bfd_error_handler) - (_("%B: Failed to find link section for section %d"), - obfd, i); - } - - if (iheader->sh_info) - { - /* The sh_info field can hold arbitrary information, - but if the SHF_LINK_INFO flag is set then it - should be interpreted as a section index. */ - if (iheader->sh_flags & SHF_INFO_LINK) - sh_link = find_link (obfd, - iheaders[iheader->sh_info], - iheader->sh_info); - else - /* No idea what it means - just copy it. */ - sh_link = iheader->sh_info; - - if (sh_link != SHN_UNDEF) - { - oheader->sh_info = sh_link; - changed = TRUE; - } - else - (* _bfd_error_handler) - (_("%B: Failed to find info section for section %d"), - obfd, i); - } - - if (changed) - break; - } - else - { - /* This is an feature for objcopy --only-keep-debug: - When a section's type is changed to NOBITS, we preserve - the sh_link and sh_info fields so that they can be - matched up with the original. - - Note: Strictly speaking these assignments are wrong. - The sh_link and sh_info fields should point to the - relevent sections in the output BFD, which may not be in - the same location as they were in the input BFD. But - the whole point of this action is to preserve the - original values of the sh_link and sh_info fields, so - that they can be matched up with the section headers in - the original file. So strictly speaking we may be - creating an invalid ELF file, but it is only for a file - that just contains debug info and only for sections - without any contents. */ - if (oheader->sh_link == 0) - oheader->sh_link = iheader->sh_link; - if (oheader->sh_info == 0) - oheader->sh_info = iheader->sh_info; - break; - } + if (copy_special_section_fields (ibfd, obfd, iheader, oheader, i)) + break; } } + + if (j == elf_numsections (ibfd) && oheader->sh_type >= SHT_LOOS) + { + /* Final attempt. Call the backend copy function + with a NULL input section. */ + if (bed->elf_backend_copy_special_section_fields != NULL) + bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader); + } } return TRUE; diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 6e27155d5d3..ba89aa6c262 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -14112,11 +14112,15 @@ elf32_arm_adjust_dynamic_symbol (struct bfd_link_info * info, s = bfd_get_linker_section (dynobj, ".dynbss"); BFD_ASSERT (s != NULL); - /* We must generate a R_ARM_COPY reloc to tell the dynamic linker to - copy the initial value out of the dynamic object and into the - runtime process image. We need to remember the offset into the + /* If allowed, we must generate a R_ARM_COPY reloc to tell the dynamic + linker to copy the initial value out of the dynamic object and into + the runtime process image. We need to remember the offset into the .rel(a).bss section we are going to use. */ - if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0) + if (info->nocopyreloc == 0 + && (h->root.u.def.section->flags & SEC_ALLOC) != 0 + /* PR 16177: A copy is only needed if the input section is readonly. */ + && (h->root.u.def.section->flags & SEC_READONLY) == 0 + && h->size != 0) { asection *srel; @@ -17873,6 +17877,100 @@ elf32_arm_count_additional_relocs (asection *sec) return arm_data->additional_reloc_count; } +/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which + has a type >= SHT_LOOS. Returns TRUE if these fields were initialised + FALSE otherwise. ISECTION is the best guess matching section from the + input bfd IBFD, but it might be NULL. */ + +static bfd_boolean +elf32_arm_copy_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED, + bfd *obfd ATTRIBUTE_UNUSED, + const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *osection) +{ + switch (osection->sh_type) + { + case SHT_ARM_EXIDX: + { + Elf_Internal_Shdr **oheaders = elf_elfsections (obfd); + Elf_Internal_Shdr **iheaders = elf_elfsections (ibfd); + unsigned i = 0; + + osection->sh_flags = SHF_ALLOC | SHF_LINK_ORDER; + osection->sh_info = 0; + + /* The sh_link field must be set to the text section associated with + this index section. Unfortunately the ARM EHABI does not specify + exactly how to determine this association. Our caller does try + to match up OSECTION with its corresponding input section however + so that is a good first guess. */ + if (isection != NULL + && osection->bfd_section != NULL + && isection->bfd_section != NULL + && isection->bfd_section->output_section != NULL + && isection->bfd_section->output_section == osection->bfd_section + && iheaders != NULL + && isection->sh_link > 0 + && isection->sh_link < elf_numsections (ibfd) + && iheaders[isection->sh_link]->bfd_section != NULL + && iheaders[isection->sh_link]->bfd_section->output_section != NULL + ) + { + for (i = elf_numsections (obfd); i-- > 0;) + if (oheaders[i]->bfd_section + == iheaders[isection->sh_link]->bfd_section->output_section) + break; + } + + if (i == 0) + { + /* Failing that we have to find a matching section ourselves. If + we had the output section name available we could compare that + with input section names. Unfortunately we don't. So instead + we use a simple heuristic and look for the nearest executable + section before this one. */ + for (i = elf_numsections (obfd); i-- > 0;) + if (oheaders[i] == osection) + break; + if (i == 0) + break; + + while (i-- > 0) + if (oheaders[i]->sh_type == SHT_PROGBITS + && (oheaders[i]->sh_flags & (SHF_ALLOC | SHF_EXECINSTR)) + == (SHF_ALLOC | SHF_EXECINSTR)) + break; + } + + if (i) + { + osection->sh_link = i; + /* If the text section was part of a group + then the index section should be too. */ + if (oheaders[i]->sh_flags & SHF_GROUP) + osection->sh_flags |= SHF_GROUP; + return TRUE; + } + } + break; + + case SHT_ARM_PREEMPTMAP: + osection->sh_flags = SHF_ALLOC; + break; + + case SHT_ARM_ATTRIBUTES: + case SHT_ARM_DEBUGOVERLAY: + case SHT_ARM_OVERLAYSECTION: + default: + break; + } + + return FALSE; +} + +#undef elf_backend_copy_special_section_fields +#define elf_backend_copy_special_section_fields elf32_arm_copy_special_section_fields + #define ELF_ARCH bfd_arch_arm #define ELF_TARGET_ID ARM_ELF_DATA #define ELF_MACHINE_CODE EM_ARM @@ -18035,6 +18133,7 @@ elf32_arm_nacl_plt_sym_val (bfd_vma i, const asection *plt, #undef bfd_elf32_get_synthetic_symtab #undef elf_backend_plt_sym_val #define elf_backend_plt_sym_val elf32_arm_nacl_plt_sym_val +#undef elf_backend_copy_special_section_fields #undef ELF_MINPAGESIZE #undef ELF_COMMONPAGESIZE @@ -18454,7 +18553,6 @@ elf32_arm_symbian_plt_sym_val (bfd_vma i, const asection *plt, return plt->vma + 4 * ARRAY_SIZE (elf32_arm_symbian_plt_entry) * i; } - #undef elf32_bed #define elf32_bed elf32_arm_symbian_bed diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 7948fa99907..4de8a2df8df 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -5905,16 +5905,22 @@ elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info) #undef elf_backend_strtab_flags #define elf_backend_strtab_flags SHF_STRINGS +/* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which + has a type >= SHT_LOOS. Returns TRUE if these fields were initialised + FALSE otherwise. ISECTION is the best guess matching section from the + input bfd IBFD, but it might be NULL. */ + static bfd_boolean -elf32_i386_set_special_info_link (const bfd *ibfd ATTRIBUTE_UNUSED, - bfd *obfd ATTRIBUTE_UNUSED, - const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, - Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED) +elf32_i386_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED, + bfd *obfd ATTRIBUTE_UNUSED, + const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED) { /* PR 19938: FIXME: Need to add code for setting the sh_info - and sh_link fields of Solaris specific section types. + and sh_link fields of Solaris specific section types. */ + return FALSE; - Based upon Oracle Solaris 11.3 Linkers and Libraries Guide, Ch. 13, + /* Based upon Oracle Solaris 11.3 Linkers and Libraries Guide, Ch. 13, Object File Format, Table 13-9 ELF sh_link and sh_info Interpretation: http://docs.oracle.com/cd/E53394_01/html/E54813/chapter6-94076.html#scrolltoc @@ -5974,11 +5980,10 @@ SHT_SUNW_verneed The section header index of The number of version SHT_SUNW_versym The section header index of 0 [0x6fffffff] the associated symbol table. */ - return FALSE; } -#undef elf_backend_set_special_section_info_and_link -#define elf_backend_set_special_section_info_and_link elf32_i386_set_special_info_link +#undef elf_backend_copy_special_section_fields +#define elf_backend_copy_special_section_fields elf32_i386_copy_solaris_special_section_fields #include "elf32-target.h" @@ -6016,7 +6021,7 @@ elf32_iamcu_elf_object_p (bfd *abfd) #define elf_backend_want_plt_sym 0 #undef elf_backend_strtab_flags -#undef elf_backend_set_special_section_info_and_link +#undef elf_backend_copy_special_section_fields #include "elf32-target.h" diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index c045854f89a..495d55a199a 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -265,18 +265,18 @@ elf32_sparc_add_symbol_hook (bfd * abfd, #define elf_backend_strtab_flags SHF_STRINGS static bfd_boolean -elf32_sparc_set_special_info_link (const bfd *ibfd ATTRIBUTE_UNUSED, - bfd *obfd ATTRIBUTE_UNUSED, - const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, - Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED) +elf32_sparc_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED, + bfd *obfd ATTRIBUTE_UNUSED, + const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED) { /* PR 19938: FIXME: Need to add code for setting the sh_info and sh_link fields of Solaris specific section types. */ return FALSE; } -#undef elf_backend_set_special_section_info_and_link -#define elf_backend_set_special_section_info_and_link elf32_sparc_set_special_info_link +#undef elf_backend_copy_special_section_fields +#define elf_backend_copy_special_section_fields elf32_sparc_copy_solaris_special_section_fields #include "elf32-target.h" @@ -341,7 +341,7 @@ elf32_sparc_vxworks_final_write_processing (bfd *abfd, bfd_boolean linker) elf32_sparc_vxworks_final_write_processing #undef elf_backend_static_tls_alignment #undef elf_backend_strtab_flags -#undef elf_backend_set_special_section_info_and_link +#undef elf_backend_copy_special_section_fields #undef elf32_bed #define elf32_bed sparc_elf_vxworks_bed diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 02fcb220b91..8a5ce750914 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -6552,18 +6552,18 @@ static const struct bfd_elf_special_section #define elf_backend_strtab_flags SHF_STRINGS static bfd_boolean -elf64_x86_64_set_special_info_link (const bfd *ibfd ATTRIBUTE_UNUSED, - bfd *obfd ATTRIBUTE_UNUSED, - const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, - Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED) +elf64_x86_64_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED, + bfd *obfd ATTRIBUTE_UNUSED, + const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED, + Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED) { /* PR 19938: FIXME: Need to add code for setting the sh_info and sh_link fields of Solaris specific section types. */ return FALSE; } -#undef elf_backend_set_special_section_info_and_link -#define elf_backend_set_special_section_info_and_link elf64_x86_64_set_special_info_link +#undef elf_backend_copy_special_section_fields +#define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields #include "elf64-target.h" @@ -6597,7 +6597,7 @@ elf64_x86_64_nacl_elf_object_p (bfd *abfd) #undef elf_backend_want_plt_sym #define elf_backend_want_plt_sym 0 #undef elf_backend_strtab_flags -#undef elf_backend_set_special_section_info_and_link +#undef elf_backend_copy_special_section_fields /* NaCl uses substantially different PLT entries for the same effects. */ diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index fde34b7d292..c1bbadce6dd 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -686,8 +686,8 @@ #define elf_backend_get_reloc_section _bfd_elf_get_reloc_section #endif -#ifndef elf_backend_set_special_section_info_and_link -#define elf_backend_set_special_section_info_and_link NULL +#ifndef elf_backend_copy_special_section_fields +#define elf_backend_copy_special_section_fields NULL #endif #ifndef elf_backend_compact_eh_encoding @@ -797,7 +797,7 @@ static struct elf_backend_data elfNN_bed = elf_backend_is_function_type, elf_backend_maybe_function_sym, elf_backend_get_reloc_section, - elf_backend_set_special_section_info_and_link, + elf_backend_copy_special_section_fields, elf_backend_link_order_error_handler, elf_backend_relplt_name, ELF_MACHINE_ALT1, diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 7a19cc7da3f..7eea2c05d9f 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,9 @@ +2016-04-29 Nick Clifton + + PR 19938 + * readelf.c (get_solaris_segment_type): New function. + (get_segment_type): Call it. + 2016-04-28 Nick Clifton * po/zh_CN.po: Updated Chinese (simplified) translation. diff --git a/binutils/readelf.c b/binutils/readelf.c index cf917556c09..b6454d35327 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -3688,6 +3688,23 @@ get_tic6x_segment_type (unsigned long type) return NULL; } +static const char * +get_solaris_segment_type (unsigned long type) +{ + switch (type) + { + case 0x6464e550: return "PT_SUNW_UNWIND"; + case 0x6474e550: return "PT_SUNW_EH_FRAME"; + case 0x6ffffff7: return "PT_LOSUNW"; + case 0x6ffffffa: return "PT_SUNWBSS"; + case 0x6ffffffb: return "PT_SUNWSTACK"; + case 0x6ffffffc: return "PT_SUNWDTRACE"; + case 0x6ffffffd: return "PT_SUNWCAP"; + case 0x6fffffff: return "PT_HISUNW"; + default: return NULL; + } +} + static const char * get_segment_type (unsigned long p_type) { @@ -3758,7 +3775,10 @@ get_segment_type (unsigned long p_type) result = get_ia64_segment_type (p_type); break; default: - result = NULL; + if (elf_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS) + result = get_solaris_segment_type (p_type); + else + result = NULL; break; }