aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-09-09 15:03:54 +0000
committerNick Clifton <nickc@redhat.com>2009-09-09 15:03:54 +0000
commitcfcac11dc826f830a5ca9a7265ad5e2ecd14e92f (patch)
tree61359fd7d4d1adacb8558d014145b96165b70922
parentad86f1fb4da4f0b049bfd5f9fb05dcd52124ad33 (diff)
downloadgdb-cfcac11dc826f830a5ca9a7265ad5e2ecd14e92f.zip
gdb-cfcac11dc826f830a5ca9a7265ad5e2ecd14e92f.tar.gz
gdb-cfcac11dc826f830a5ca9a7265ad5e2ecd14e92f.tar.bz2
PR 10478:
* elf.c (bfd_section_from_shdr): Do not reject sparc binaries with section headers containing sh_link values of SHN_BEFORE or SHN_AFTER. * elfcode.h (elf_object_p): Likewise. readelf.c (get_elf_section_flags): Add support for SHF_EXCLUDE and SHF_ORDERED. (process_section_headers): Warn about out of range sh_link values. When displaying detailed section header information annote the SHN_BEFORE and SHN_AFTER values.
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/elf.c20
-rw-r--r--bfd/elfcode.h18
-rw-r--r--binutils/ChangeLog9
-rw-r--r--binutils/readelf.c105
5 files changed, 130 insertions, 31 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 39ee6fd..82a663b 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+2009-09-09 Nick Clifton <nickc@redhat.com>
+
+ PR 10478:
+ * elf.c (bfd_section_from_shdr): Do not reject sparc binaries with
+ section headers containing sh_link values of SHN_BEFORE or
+ SHN_AFTER.
+ * elfcode.h (elf_object_p): Likewise.
+
2009-09-09 Tristan Gingold <gingold@adacore.com>
Handle DYLD_INFO introduced by Darwin10.
@@ -12,7 +20,6 @@
(bfd_mach_o_load_command_name): AddB FD_MACH_O_LC_DYLD_INFO.
(bfd_mach_o_print_dyld_info): New function.
-
2009-09-09 M R Swami Reddy <MR.Swami.Reddy@nsc.com>
* elf32-cr16.c (elf32_cr16_relocate_section): Add code to discard the
diff --git a/bfd/elf.c b/bfd/elf.c
index 13f6904..ed974c0 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1514,10 +1514,24 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
case SHT_DYNAMIC: /* Dynamic linking information. */
if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
return FALSE;
- if (hdr->sh_link > elf_numsections (abfd)
- || elf_elfsections (abfd)[hdr->sh_link] == NULL)
+ if (hdr->sh_link > elf_numsections (abfd))
+ {
+ /* PR 10478: Accept sparc binaries with a sh_link
+ field set to SHN_BEFORE or SHN_AFTER. */
+ switch (bfd_get_arch (abfd))
+ {
+ case bfd_arch_sparc:
+ if (hdr->sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
+ || hdr->sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
+ break;
+ /* Otherwise fall through. */
+ default:
+ return FALSE;
+ }
+ }
+ else if (elf_elfsections (abfd)[hdr->sh_link] == NULL)
return FALSE;
- if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
+ else if (elf_elfsections (abfd)[hdr->sh_link]->sh_type != SHT_STRTAB)
{
Elf_Internal_Shdr *dynsymhdr;
diff --git a/bfd/elfcode.h b/bfd/elfcode.h
index 10aa131..889d25a 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -760,7 +760,23 @@ elf_object_p (bfd *abfd)
/* Sanity check sh_link and sh_info. */
if (i_shdrp[shindex].sh_link >= num_sec)
- goto got_wrong_format_error;
+ {
+ /* PR 10478: Accept sparc binaries with a sh_link
+ field set to SHN_BEFORE or SHN_AFTER. */
+ switch (ebd->elf_machine_code)
+ {
+ case EM_OLD_SPARCV9:
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
+ case EM_SPARC:
+ if (i_shdrp[shindex].sh_link == (SHN_LORESERVE & 0xffff) /* SHN_BEFORE */
+ || i_shdrp[shindex].sh_link == ((SHN_LORESERVE + 1) & 0xffff) /* SHN_AFTER */)
+ break;
+ /* Otherwise fall through. */
+ default:
+ goto got_wrong_format_error;
+ }
+ }
if (((i_shdrp[shindex].sh_flags & SHF_INFO_LINK)
|| i_shdrp[shindex].sh_type == SHT_RELA
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 1722fe7..022cda5 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,12 @@
+2009-09-09 Nick Clifton <nickc@redhat.com>
+
+ PR 10478:
+ readelf.c (get_elf_section_flags): Add support for SHF_EXCLUDE and
+ SHF_ORDERED.
+ (process_section_headers): Warn about out of range sh_link
+ values. When displaying detailed section header information
+ annote the SHN_BEFORE and SHN_AFTER values.
+
2009-09-08 Alan Modra <amodra@bigpond.net.au>
* dwarf.c (byte_get_little_endian): Handle size of 3.
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 590c70d..872ec09 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3873,26 +3873,29 @@ get_elf_section_flags (bfd_vma sh_flags)
}
flags [] =
{
- { "WRITE", 5 },
- { "ALLOC", 5 },
- { "EXEC", 4 },
- { "MERGE", 5 },
- { "STRINGS", 7 },
- { "INFO LINK", 9 },
- { "LINK ORDER", 10 },
- { "OS NONCONF", 10 },
- { "GROUP", 5 },
- { "TLS", 3 },
- /* IA-64 specific. */
- { "SHORT", 5 },
- { "NORECOV", 7 },
- /* IA-64 OpenVMS specific. */
- { "VMS_GLOBAL", 10 },
- { "VMS_OVERLAID", 12 },
- { "VMS_SHARED", 10 },
- { "VMS_VECTOR", 10 },
- { "VMS_ALLOC_64BIT", 15 },
- { "VMS_PROTECTED", 13}
+ /* 0 */ { STRING_COMMA_LEN ("WRITE") },
+ /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
+ /* 2 */ { STRING_COMMA_LEN ("EXEC") },
+ /* 3 */ { STRING_COMMA_LEN ("MERGE") },
+ /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
+ /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
+ /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
+ /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
+ /* 8 */ { STRING_COMMA_LEN ("GROUP") },
+ /* 9 */ { STRING_COMMA_LEN ("TLS") },
+ /* IA-64 specific. */
+ /* 10 */ { STRING_COMMA_LEN ("SHORT") },
+ /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
+ /* IA-64 OpenVMS specific. */
+ /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
+ /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
+ /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
+ /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
+ /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
+ /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
+ /* SPARC specific. */
+ /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
+ /* 19 */ { STRING_COMMA_LEN ("ORDERED") }
};
if (do_section_details)
@@ -3926,8 +3929,9 @@ get_elf_section_flags (bfd_vma sh_flags)
default:
index = -1;
- if (elf_header.e_machine == EM_IA_64)
+ switch (elf_header.e_machine)
{
+ case EM_IA_64:
if (flag == SHF_IA_64_SHORT)
index = 10;
else if (flag == SHF_IA_64_NORECOV)
@@ -3945,8 +3949,20 @@ get_elf_section_flags (bfd_vma sh_flags)
default: break;
}
#endif
+ break;
+
+ case EM_OLD_SPARCV9:
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
+ case EM_SPARC:
+ if (flag == SHF_EXCLUDE)
+ index = 18;
+ else if (flag == SHF_ORDERED)
+ index = 19;
+ break;
+ default:
+ break;
}
- break;
}
if (index != -1)
@@ -4327,6 +4343,8 @@ process_section_headers (FILE * file)
if (is_32bit_elf)
{
+ const char * link_too_big = NULL;
+
print_vma (section->sh_addr, LONG_HEX);
printf ( " %6.6lx %6.6lx %2.2lx",
@@ -4339,10 +4357,45 @@ process_section_headers (FILE * file)
else
printf (" %3s ", get_elf_section_flags (section->sh_flags));
- printf ("%2u %3u %2lu\n",
- section->sh_link,
- section->sh_info,
- (unsigned long) section->sh_addralign);
+ if (section->sh_link >= elf_header.e_shnum)
+ {
+ link_too_big = "";
+ /* The sh_link value is out of range. Normally this indicates
+ an error but it can have special values in SPARC binaries. */
+ switch (elf_header.e_machine)
+ {
+ case EM_OLD_SPARCV9:
+ case EM_SPARC32PLUS:
+ case EM_SPARCV9:
+ case EM_SPARC:
+ if (section->sh_link == (SHN_BEFORE & 0xffff))
+ link_too_big = "BEFORE";
+ else if (section->sh_link == (SHN_AFTER & 0xffff))
+ link_too_big = "AFTER";
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (do_section_details)
+ {
+ if (link_too_big != NULL && * link_too_big)
+ printf ("<%s> ", link_too_big);
+ else
+ printf ("%2u ", section->sh_link);
+ printf ("%3u %2lu\n", section->sh_info,
+ (unsigned long) section->sh_addralign);
+ }
+ else
+ printf ("%2u %3u %2lu\n",
+ section->sh_link,
+ section->sh_info,
+ (unsigned long) section->sh_addralign);
+
+ if (link_too_big && ! * link_too_big)
+ warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
+ i, section->sh_link);
}
else if (do_wide)
{