aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2016-04-29 09:24:42 +0100
committerNick Clifton <nickc@redhat.com>2016-04-29 09:24:42 +0100
commit5522f910cb539905d6adfdceab208ddfa5e84557 (patch)
tree0e266a54bdd71c153b10e11319699d78350b6c33
parent2deb93c7a7708ed164e4b10afb9d6a885d4615c6 (diff)
downloadgdb-5522f910cb539905d6adfdceab208ddfa5e84557.zip
gdb-5522f910cb539905d6adfdceab208ddfa5e84557.tar.gz
gdb-5522f910cb539905d6adfdceab208ddfa5e84557.tar.bz2
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.
-rw-r--r--bfd/ChangeLog25
-rw-r--r--bfd/elf-bfd.h16
-rw-r--r--bfd/elf.c268
-rw-r--r--bfd/elf32-arm.c108
-rw-r--r--bfd/elf32-i386.c25
-rw-r--r--bfd/elf32-sparc.c14
-rw-r--r--bfd/elf64-x86-64.c14
-rw-r--r--bfd/elfxx-target.h6
-rw-r--r--binutils/ChangeLog6
-rw-r--r--binutils/readelf.c22
10 files changed, 361 insertions, 143 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index d70dd88..f60ee03 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,28 @@
+2016-04-29 Nick Clifton <nickc@redhat.com>
+
+ 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 <nickc@redhat.com>
* po/zh_CN.po: Updated Chinese (simplified) translation.
diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index 6c05b55..9067dd9 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 69830ce..4be7d73 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 6e27155..ba89aa6 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 7948fa9..4de8a2d 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 c045854..495d55a 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 02fcb22..8a5ce75 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 fde34b7..c1bbadc 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 7a19cc7..7eea2c0 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,9 @@
+2016-04-29 Nick Clifton <nickc@redhat.com>
+
+ PR 19938
+ * readelf.c (get_solaris_segment_type): New function.
+ (get_segment_type): Call it.
+
2016-04-28 Nick Clifton <nickc@redhat.com>
* po/zh_CN.po: Updated Chinese (simplified) translation.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index cf91755..b6454d3 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3689,6 +3689,23 @@ get_tic6x_segment_type (unsigned long type)
}
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)
{
static char buff[32];
@@ -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;
}