aboutsummaryrefslogtreecommitdiff
path: root/binutils/readelf.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2019-07-23 17:54:42 +0930
committerAlan Modra <amodra@gmail.com>2019-07-23 18:22:02 +0930
commitdf3a023bd614133fe69afb02cd0e8f3e590a36a9 (patch)
tree396b62a6d24352b88221af7749348cdfbcd5a9a3 /binutils/readelf.c
parent06f44071ccbeca33fff70b928b71d95a15982740 (diff)
downloadgdb-df3a023bd614133fe69afb02cd0e8f3e590a36a9.zip
gdb-df3a023bd614133fe69afb02cd0e8f3e590a36a9.tar.gz
gdb-df3a023bd614133fe69afb02cd0e8f3e590a36a9.tar.bz2
SHF_GNU_MBIND requires ELFOSABI_GNU
When SHF_GNU_MBIND was added in the SHF_LOOS to SHF_HIOS range, it should have required ELFOSABI_GNU since these flags are already in use by other OSes. HPUX SHF_HP_TLS in fact has the same value. That means no place in binutils should test SHF_GNU_MBIND without first checking OSABI, and SHF_GNU_MBIND should not be set without also setting OSABI. At least, that's the ideal, but the patch accepts SHF_GNU_MBIND on ELFOSABI_NONE object files since gas didn't always set OSABI. However, to reinforce the fact that SHF_GNU_MBIND isn't proper without a non-zero OSABI, readelf will display the flag as LOOS+0 if OSABI isn't set. The clash with SHF_HP_TLS means that hppa64-linux either has that flag on .tbss sections or supports GNU_MBIND, not both. (hppa64-linux users, if there are any, may have noticed that GNU ld since 2017 mysteriously aligned their .tbss sections to a 4k boundary. That was one consequence of SHF_HP_TLS being blindly interpreted as SHF_GNU_MBIND.) Since it seems that binutils, gdb, gcc, glibc, and the linux kernel don't care about SHF_HP_TLS I took that flag out of .tbss for hppa64-linux. bfd/ * elf-bfd.h (enum elf_gnu_osabi): Add elf_gnu_osabi_mbind. * elf.c (_bfd_elf_make_section_from_shdr): Set elf_gnu_osabi_mbind. (get_program_header_size): Formatting. Only test SH_GNU_MBIND when elf_gnu_osabi_mbind is set. (_bfd_elf_map_sections_to_segments): Likewise. (_bfd_elf_init_private_section_data): Likewise. (_bfd_elf_final_write_processing): Update comment. * elf64-hppa.c (elf64_hppa_special_sections): Move .tbss entry. (elf_backend_special_sections): Define without .tbss for linux. binutils/ * readelf.c (get_parisc_segment_type): Split off hpux entries.. (get_ia64_segment_type): ..and these.. (get_hpux_segment_type): ..to here. (get_segment_type): Condition GNU_MBIND on osabi. Use get_hpux_segment_type. (get_symbol_binding): Do not print UNIQUE for ELFOSABI_NONE. (get_symbol_type): Do not print IFUNC for ELFOSABI_NONE. gas/ * config/obj-elf.c (obj_elf_change_section): Don't emit a fatal error for non-SHF_ALLOC SHF_GNU_MBIND here. (obj_elf_parse_section_letters): Return SHF_GNU_MBIND in new gnu_attr param. (obj_elf_section): Adjust obj_elf_parse_section_letters call. Formatting. Set SHF_GNU_MBIND and elf_osabi from gnu_attr. Emit normal error for non-SHF_ALLOC SHF_GNU_MBIND and wrong osabi. (obj_elf_type): Set elf_osabi for ifunc. * testsuite/gas/elf/section12a.d: xfail msp430 and hpux. * testsuite/gas/elf/section12b.d: Likewise. * testsuite/gas/elf/section13.d: Likewise. * testsuite/gas/elf/section13.l: Adjust expected error. ld/ * emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Condition SHF_GNU_MBIND on osabi. Set output elf_gnu_osabi_mbind.
Diffstat (limited to 'binutils/readelf.c')
-rw-r--r--binutils/readelf.c99
1 files changed, 56 insertions, 43 deletions
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 5e8fe82..1ba4bcb 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3879,22 +3879,6 @@ get_parisc_segment_type (unsigned long type)
{
switch (type)
{
- case PT_HP_TLS: return "HP_TLS";
- case PT_HP_CORE_NONE: return "HP_CORE_NONE";
- case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
- case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
- case PT_HP_CORE_COMM: return "HP_CORE_COMM";
- case PT_HP_CORE_PROC: return "HP_CORE_PROC";
- case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
- case PT_HP_CORE_STACK: return "HP_CORE_STACK";
- case PT_HP_CORE_SHM: return "HP_CORE_SHM";
- case PT_HP_CORE_MMF: return "HP_CORE_MMF";
- case PT_HP_PARALLEL: return "HP_PARALLEL";
- case PT_HP_FASTBIND: return "HP_FASTBIND";
- case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
- case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
- case PT_HP_STACK: return "HP_STACK";
- case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
case PT_PARISC_UNWIND: return "PARISC_UNWIND";
case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
@@ -3909,10 +3893,6 @@ get_ia64_segment_type (unsigned long type)
{
case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
case PT_IA_64_UNWIND: return "IA_64_UNWIND";
- case PT_HP_TLS: return "HP_TLS";
- case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
- case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
- case PT_IA_64_HP_STACK: return "HP_STACK";
default: return NULL;
}
}
@@ -3928,6 +3908,44 @@ get_tic6x_segment_type (unsigned long type)
}
static const char *
+get_hpux_segment_type (unsigned long type, unsigned e_machine)
+{
+ if (e_machine == EM_PARISC)
+ switch (type)
+ {
+ case PT_HP_TLS: return "HP_TLS";
+ case PT_HP_CORE_NONE: return "HP_CORE_NONE";
+ case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
+ case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
+ case PT_HP_CORE_COMM: return "HP_CORE_COMM";
+ case PT_HP_CORE_PROC: return "HP_CORE_PROC";
+ case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
+ case PT_HP_CORE_STACK: return "HP_CORE_STACK";
+ case PT_HP_CORE_SHM: return "HP_CORE_SHM";
+ case PT_HP_CORE_MMF: return "HP_CORE_MMF";
+ case PT_HP_PARALLEL: return "HP_PARALLEL";
+ case PT_HP_FASTBIND: return "HP_FASTBIND";
+ case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
+ case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
+ case PT_HP_STACK: return "HP_STACK";
+ case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
+ default: return NULL;
+ }
+
+ if (e_machine == EM_IA_64)
+ switch (type)
+ {
+ case PT_HP_TLS: return "HP_TLS";
+ case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
+ case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
+ case PT_IA_64_HP_STACK: return "HP_STACK";
+ default: return NULL;
+ }
+
+ return NULL;
+}
+
+static const char *
get_solaris_segment_type (unsigned long type)
{
switch (type)
@@ -3965,12 +3983,7 @@ get_segment_type (Filedata * filedata, unsigned long p_type)
case PT_GNU_PROPERTY: return "GNU_PROPERTY";
default:
- if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
- {
- sprintf (buff, "GNU_MBIND+%#lx",
- p_type - PT_GNU_MBIND_LO);
- }
- else if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
+ if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
{
const char * result;
@@ -4011,24 +4024,28 @@ get_segment_type (Filedata * filedata, unsigned long p_type)
}
else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
{
- const char * result;
+ const char * result = NULL;
- switch (filedata->file_header.e_machine)
+ switch (filedata->file_header.e_ident[EI_OSABI])
{
- case EM_PARISC:
- result = get_parisc_segment_type (p_type);
+ case ELFOSABI_GNU:
+ case ELFOSABI_FREEBSD:
+ if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
+ {
+ sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
+ result = buff;
+ }
break;
- case EM_IA_64:
- result = get_ia64_segment_type (p_type);
+ case ELFOSABI_HPUX:
+ result = get_hpux_segment_type (p_type,
+ filedata->file_header.e_machine);
+ break;
+ case ELFOSABI_SOLARIS:
+ result = get_solaris_segment_type (p_type);
break;
default:
- if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
- result = get_solaris_segment_type (p_type);
- else
- result = NULL;
break;
}
-
if (result != NULL)
return result;
@@ -11052,9 +11069,7 @@ get_symbol_binding (Filedata * filedata, unsigned int binding)
else if (binding >= STB_LOOS && binding <= STB_HIOS)
{
if (binding == STB_GNU_UNIQUE
- && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
- /* GNU is still using the default value 0. */
- || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
+ && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
return "UNIQUE";
snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
}
@@ -11106,9 +11121,7 @@ get_symbol_type (Filedata * filedata, unsigned int type)
if (type == STT_GNU_IFUNC
&& (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
- || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD
- /* GNU is still using the default value 0. */
- || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE))
+ || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
return "IFUNC";
snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);