diff options
author | Alan Modra <amodra@gmail.com> | 2019-07-23 17:54:42 +0930 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2019-07-23 18:22:02 +0930 |
commit | df3a023bd614133fe69afb02cd0e8f3e590a36a9 (patch) | |
tree | 396b62a6d24352b88221af7749348cdfbcd5a9a3 /binutils/readelf.c | |
parent | 06f44071ccbeca33fff70b928b71d95a15982740 (diff) | |
download | gdb-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.c | 99 |
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); |