mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-01-21 15:33:33 +08:00
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.
This commit is contained in:
parent
06f44071cc
commit
df3a023bd6
@ -1,3 +1,15 @@
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* elf-bfd.h (enum elf_gnu_osabi): Rename from elf_gnu_symbols.
|
||||
|
@ -1809,11 +1809,12 @@ struct output_elf_obj_tdata
|
||||
bfd_boolean flags_init;
|
||||
};
|
||||
|
||||
/* Indicate if the bfd contains symbols that have the STT_GNU_IFUNC
|
||||
symbol type or STB_GNU_UNIQUE binding. Used to set the osabi
|
||||
field in the ELF header structure. */
|
||||
/* Indicate if the bfd contains SHF_GNU_MBIND sections or symbols that
|
||||
have the STT_GNU_IFUNC symbol type or STB_GNU_UNIQUE binding. Used
|
||||
to set the osabi field in the ELF header structure. */
|
||||
enum elf_gnu_osabi
|
||||
{
|
||||
elf_gnu_osabi_mbind = 1 << 0,
|
||||
elf_gnu_osabi_ifunc = 1 << 1,
|
||||
elf_gnu_osabi_unique = 1 << 2,
|
||||
};
|
||||
|
78
bfd/elf.c
78
bfd/elf.c
@ -1067,6 +1067,19 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
|
||||
if ((hdr->sh_flags & SHF_EXCLUDE) != 0)
|
||||
flags |= SEC_EXCLUDE;
|
||||
|
||||
switch (elf_elfheader (abfd)->e_ident[EI_OSABI])
|
||||
{
|
||||
/* FIXME: We should not recognize SHF_GNU_MBIND for ELFOSABI_NONE,
|
||||
but binutils as of 2019-07-23 did not set the EI_OSABI header
|
||||
byte. */
|
||||
case ELFOSABI_NONE:
|
||||
case ELFOSABI_GNU:
|
||||
case ELFOSABI_FREEBSD:
|
||||
if ((hdr->sh_flags & SHF_GNU_MBIND) != 0)
|
||||
elf_tdata (abfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((flags & SEC_ALLOC) == 0)
|
||||
{
|
||||
/* The debugging sections appear to be recognized only by name,
|
||||
@ -4425,31 +4438,32 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
|
||||
|
||||
bed = get_elf_backend_data (abfd);
|
||||
|
||||
if ((abfd->flags & D_PAGED) != 0)
|
||||
{
|
||||
/* Add a PT_GNU_MBIND segment for each mbind section. */
|
||||
unsigned int page_align_power = bfd_log2 (bed->commonpagesize);
|
||||
for (s = abfd->sections; s != NULL; s = s->next)
|
||||
if (elf_section_flags (s) & SHF_GNU_MBIND)
|
||||
{
|
||||
if (elf_section_data (s)->this_hdr.sh_info
|
||||
> PT_GNU_MBIND_NUM)
|
||||
{
|
||||
_bfd_error_handler
|
||||
/* xgettext:c-format */
|
||||
(_("%pB: GNU_MBIN section `%pA' has invalid sh_info field: %d"),
|
||||
abfd, s, elf_section_data (s)->this_hdr.sh_info);
|
||||
continue;
|
||||
}
|
||||
/* Align mbind section to page size. */
|
||||
if (s->alignment_power < page_align_power)
|
||||
s->alignment_power = page_align_power;
|
||||
segs ++;
|
||||
}
|
||||
}
|
||||
if ((abfd->flags & D_PAGED) != 0
|
||||
&& (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
|
||||
{
|
||||
/* Add a PT_GNU_MBIND segment for each mbind section. */
|
||||
unsigned int page_align_power = bfd_log2 (bed->commonpagesize);
|
||||
for (s = abfd->sections; s != NULL; s = s->next)
|
||||
if (elf_section_flags (s) & SHF_GNU_MBIND)
|
||||
{
|
||||
if (elf_section_data (s)->this_hdr.sh_info > PT_GNU_MBIND_NUM)
|
||||
{
|
||||
_bfd_error_handler
|
||||
/* xgettext:c-format */
|
||||
(_("%pB: GNU_MBIND section `%pA' has invalid "
|
||||
"sh_info field: %d"),
|
||||
abfd, s, elf_section_data (s)->this_hdr.sh_info);
|
||||
continue;
|
||||
}
|
||||
/* Align mbind section to page size. */
|
||||
if (s->alignment_power < page_align_power)
|
||||
s->alignment_power = page_align_power;
|
||||
segs ++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Let the backend count up any program headers it might need. */
|
||||
if (bed->elf_backend_additional_program_headers)
|
||||
/* Let the backend count up any program headers it might need. */
|
||||
if (bed->elf_backend_additional_program_headers)
|
||||
{
|
||||
int a;
|
||||
|
||||
@ -5045,11 +5059,12 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
|
||||
pm = &m->next;
|
||||
}
|
||||
|
||||
if (first_mbind && (abfd->flags & D_PAGED) != 0)
|
||||
if (first_mbind
|
||||
&& (abfd->flags & D_PAGED) != 0
|
||||
&& (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
|
||||
for (s = first_mbind; s != NULL; s = s->next)
|
||||
if ((elf_section_flags (s) & SHF_GNU_MBIND) != 0
|
||||
&& (elf_section_data (s)->this_hdr.sh_info
|
||||
<= PT_GNU_MBIND_NUM))
|
||||
&& elf_section_data (s)->this_hdr.sh_info <= PT_GNU_MBIND_NUM)
|
||||
{
|
||||
/* Mandated PF_R. */
|
||||
unsigned long p_flags = PF_R;
|
||||
@ -7665,7 +7680,8 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
|
||||
& (SHF_MASKOS | SHF_MASKPROC));
|
||||
|
||||
/* Copy sh_info from input for mbind section. */
|
||||
if (elf_section_flags (isec) & SHF_GNU_MBIND)
|
||||
if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
|
||||
&& elf_section_flags (isec) & SHF_GNU_MBIND)
|
||||
elf_section_data (osec)->this_hdr.sh_info
|
||||
= elf_section_data (isec)->this_hdr.sh_info;
|
||||
|
||||
@ -12118,9 +12134,9 @@ _bfd_elf_final_write_processing (bfd *abfd,
|
||||
if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE)
|
||||
i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
|
||||
|
||||
/* To make things simpler for the loader on Linux systems we set the
|
||||
osabi field to ELFOSABI_GNU if the binary contains symbols of
|
||||
the STT_GNU_IFUNC type or STB_GNU_UNIQUE binding. */
|
||||
/* Set the osabi field to ELFOSABI_GNU if the binary contains
|
||||
SHF_GNU_MBIND sections or symbols of STT_GNU_IFUNC type or
|
||||
STB_GNU_UNIQUE binding. */
|
||||
if (i_ehdrp->e_ident[EI_OSABI] == ELFOSABI_NONE
|
||||
&& elf_tdata (abfd)->has_gnu_osabi)
|
||||
i_ehdrp->e_ident[EI_OSABI] = ELFOSABI_GNU;
|
||||
|
@ -3954,13 +3954,13 @@ elf64_hppa_relocate_section (bfd *output_bfd,
|
||||
|
||||
static const struct bfd_elf_special_section elf64_hppa_special_sections[] =
|
||||
{
|
||||
{ STRING_COMMA_LEN (".tbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
|
||||
{ STRING_COMMA_LEN (".fini"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
|
||||
{ STRING_COMMA_LEN (".init"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
|
||||
{ STRING_COMMA_LEN (".plt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
|
||||
{ STRING_COMMA_LEN (".dlt"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
|
||||
{ STRING_COMMA_LEN (".sdata"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
|
||||
{ STRING_COMMA_LEN (".sbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
|
||||
{ STRING_COMMA_LEN (".tbss"), 0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
|
||||
{ NULL, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@ -4088,5 +4088,7 @@ const struct elf_size_info hppa64_elf_size_info =
|
||||
#define ELF_OSABI ELFOSABI_GNU
|
||||
#undef elf64_bed
|
||||
#define elf64_bed elf64_hppa_linux_bed
|
||||
#undef elf_backend_special_sections
|
||||
#define elf_backend_special_sections (elf64_hppa_special_sections + 1)
|
||||
|
||||
#include "elf64-target.h"
|
||||
|
@ -1,3 +1,13 @@
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/binutils-all/objcopy.exp (elf64): Correct object
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
@ -3927,6 +3907,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)
|
||||
{
|
||||
@ -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);
|
||||
|
@ -1,3 +1,18 @@
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/gas/elf/section12a.d: Don't skip for rx.
|
||||
|
@ -706,9 +706,6 @@ obj_elf_change_section (const char *name,
|
||||
attr |= ssect->attr;
|
||||
}
|
||||
|
||||
if ((attr & (SHF_ALLOC | SHF_GNU_MBIND)) == SHF_GNU_MBIND)
|
||||
as_fatal (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
|
||||
|
||||
/* Convert ELF type and flags to BFD flags. */
|
||||
flags = (SEC_RELOC
|
||||
| ((attr & SHF_WRITE) ? 0 : SEC_READONLY)
|
||||
@ -785,7 +782,8 @@ obj_elf_change_section (const char *name,
|
||||
}
|
||||
|
||||
static bfd_vma
|
||||
obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *is_clone)
|
||||
obj_elf_parse_section_letters (char *str, size_t len,
|
||||
bfd_boolean *is_clone, bfd_vma *gnu_attr)
|
||||
{
|
||||
bfd_vma attr = 0;
|
||||
*is_clone = FALSE;
|
||||
@ -819,7 +817,7 @@ obj_elf_parse_section_letters (char *str, size_t len, bfd_boolean *is_clone)
|
||||
attr |= SHF_TLS;
|
||||
break;
|
||||
case 'd':
|
||||
attr |= SHF_GNU_MBIND;
|
||||
*gnu_attr |= SHF_GNU_MBIND;
|
||||
break;
|
||||
case '?':
|
||||
*is_clone = TRUE;
|
||||
@ -1011,6 +1009,7 @@ obj_elf_section (int push)
|
||||
char *beg;
|
||||
int type, dummy;
|
||||
bfd_vma attr;
|
||||
bfd_vma gnu_attr;
|
||||
int entsize;
|
||||
int linkonce;
|
||||
subsegT new_subsection = -1;
|
||||
@ -1041,6 +1040,7 @@ obj_elf_section (int push)
|
||||
return;
|
||||
type = SHT_NULL;
|
||||
attr = 0;
|
||||
gnu_attr = 0;
|
||||
group_name = NULL;
|
||||
entsize = 0;
|
||||
linkonce = 0;
|
||||
@ -1077,7 +1077,8 @@ obj_elf_section (int push)
|
||||
ignore_rest_of_line ();
|
||||
return;
|
||||
}
|
||||
attr |= obj_elf_parse_section_letters (beg, strlen (beg), &is_clone);
|
||||
attr |= obj_elf_parse_section_letters (beg, strlen (beg),
|
||||
&is_clone, &gnu_attr);
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
if (*input_line_pointer == ',')
|
||||
@ -1103,14 +1104,14 @@ obj_elf_section (int push)
|
||||
++input_line_pointer;
|
||||
|
||||
if (ISDIGIT (* input_line_pointer))
|
||||
{
|
||||
type = strtoul (input_line_pointer, & input_line_pointer, 0);
|
||||
}
|
||||
type = strtoul (input_line_pointer, &input_line_pointer, 0);
|
||||
else
|
||||
{
|
||||
c = get_symbol_name (& beg);
|
||||
(void) restore_line_pointer (c);
|
||||
type = obj_elf_section_type (beg, input_line_pointer - beg, TRUE);
|
||||
type = obj_elf_section_type (beg,
|
||||
input_line_pointer - beg,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1177,7 +1178,7 @@ obj_elf_section (int push)
|
||||
}
|
||||
}
|
||||
|
||||
if ((attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
|
||||
if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
|
||||
{
|
||||
++input_line_pointer;
|
||||
SKIP_WHITESPACE ();
|
||||
@ -1211,7 +1212,8 @@ obj_elf_section (int push)
|
||||
c = get_symbol_name (& beg);
|
||||
(void) restore_line_pointer (c);
|
||||
|
||||
attr |= obj_elf_section_word (beg, input_line_pointer - beg, & type);
|
||||
attr |= obj_elf_section_word (beg, input_line_pointer - beg,
|
||||
&type);
|
||||
|
||||
SKIP_WHITESPACE ();
|
||||
}
|
||||
@ -1226,6 +1228,23 @@ done:
|
||||
obj_elf_change_section (name, type, info, attr, entsize, group_name,
|
||||
linkonce, push);
|
||||
|
||||
if ((gnu_attr & SHF_GNU_MBIND) != 0)
|
||||
{
|
||||
struct elf_backend_data *bed;
|
||||
|
||||
if ((attr & SHF_ALLOC) == 0)
|
||||
as_bad (_("SHF_ALLOC isn't set for GNU_MBIND section: %s"), name);
|
||||
|
||||
bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
|
||||
if (bed->elf_osabi == ELFOSABI_NONE)
|
||||
bed->elf_osabi = ELFOSABI_GNU;
|
||||
else if (bed->elf_osabi != ELFOSABI_GNU
|
||||
&& bed->elf_osabi != ELFOSABI_FREEBSD)
|
||||
as_bad (_("GNU_MBIND section is supported only by GNU "
|
||||
"and FreeBSD targets"));
|
||||
}
|
||||
elf_section_flags (now_seg) |= gnu_attr;
|
||||
|
||||
if (push && new_subsection != -1)
|
||||
subseg_set (now_seg, new_subsection);
|
||||
}
|
||||
@ -2032,15 +2051,15 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
|
||||
|| strcmp (type_name, "10") == 0
|
||||
|| strcmp (type_name, "STT_GNU_IFUNC") == 0)
|
||||
{
|
||||
const struct elf_backend_data *bed;
|
||||
struct elf_backend_data *bed;
|
||||
|
||||
bed = get_elf_backend_data (stdoutput);
|
||||
if (!(bed->elf_osabi == ELFOSABI_GNU
|
||||
|| bed->elf_osabi == ELFOSABI_FREEBSD
|
||||
/* GNU is still using the default value 0. */
|
||||
|| bed->elf_osabi == ELFOSABI_NONE))
|
||||
as_bad (_("symbol type \"%s\" is supported only by GNU and FreeBSD targets"),
|
||||
type_name);
|
||||
bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
|
||||
if (bed->elf_osabi == ELFOSABI_NONE)
|
||||
bed->elf_osabi = ELFOSABI_GNU;
|
||||
else if (bed->elf_osabi != ELFOSABI_GNU
|
||||
&& bed->elf_osabi != ELFOSABI_FREEBSD)
|
||||
as_bad (_("symbol type \"%s\" is supported only by GNU "
|
||||
"and FreeBSD targets"), type_name);
|
||||
type = BSF_FUNCTION | BSF_GNU_INDIRECT_FUNCTION;
|
||||
}
|
||||
else if (strcmp (type_name, "gnu_unique_object") == 0)
|
||||
@ -2048,14 +2067,12 @@ obj_elf_type (int ignore ATTRIBUTE_UNUSED)
|
||||
struct elf_backend_data *bed;
|
||||
|
||||
bed = (struct elf_backend_data *) get_elf_backend_data (stdoutput);
|
||||
if (!(bed->elf_osabi == ELFOSABI_GNU
|
||||
/* GNU is still using the default value 0. */
|
||||
|| bed->elf_osabi == ELFOSABI_NONE))
|
||||
if (bed->elf_osabi == ELFOSABI_NONE)
|
||||
bed->elf_osabi = ELFOSABI_GNU;
|
||||
else if (bed->elf_osabi != ELFOSABI_GNU)
|
||||
as_bad (_("symbol type \"%s\" is supported only by GNU targets"),
|
||||
type_name);
|
||||
type = BSF_OBJECT | BSF_GNU_UNIQUE;
|
||||
/* PR 10549: Always set OSABI field to GNU for objects containing unique symbols. */
|
||||
bed->elf_osabi = ELFOSABI_GNU;
|
||||
}
|
||||
#ifdef md_elf_symbol_type
|
||||
else if ((type = md_elf_symbol_type (type_name, sym, elfsym)) != -1)
|
||||
|
@ -2,6 +2,8 @@
|
||||
#as: --no-pad-sections
|
||||
#readelf: -Sg --wide
|
||||
#name: mbind sections
|
||||
# msp430 and hpux do not support SHF_GNU_MBIND
|
||||
#xfail: msp430-*-* *-*-hpux*
|
||||
|
||||
#...
|
||||
\[[ 0-9]+\] \.mbind\.data[ ]+PROGBITS[ ]+0+0 0+[0-9a-f]+ 0+1 00 WAD 0 0 1
|
||||
|
@ -2,8 +2,9 @@
|
||||
#as: --no-pad-sections
|
||||
#objdump: -s
|
||||
#name: mbind section contents
|
||||
# The RX port annoyingly reorders the sections so that they do not match the sequence expected below.
|
||||
#skip: rx-*-*
|
||||
# RX annoyingly reorders the sections so that they do not match the sequence
|
||||
# expected below. msp430 and hpux do not support SHF_GNU_MBIND
|
||||
#xfail: rx-*-* msp430-*-* *-*-hpux*
|
||||
|
||||
#...
|
||||
Contents of section .mbind.data:
|
||||
|
@ -1,2 +1,3 @@
|
||||
#name: mbind sections without SHF_ALLOC
|
||||
#error_output: section13.l
|
||||
#xfail: msp430-*-* *-*-hpux*
|
||||
|
@ -1,2 +1,2 @@
|
||||
[^:]*: Assembler messages:
|
||||
[^:]*:1: Fatal error: SHF_ALLOC isn't set for GNU_MBIND section: .mbind.data
|
||||
[^:]*:1: Error: SHF_ALLOC isn't set for GNU_MBIND section: .mbind.data
|
||||
|
@ -1,3 +1,8 @@
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* emultempl/elf32.em (gld${EMULATION_NAME}_place_orphan): Condition
|
||||
SHF_GNU_MBIND on osabi. Set output elf_gnu_osabi_mbind.
|
||||
|
||||
2019-07-23 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* testsuite/ld-elf/size-1.d,
|
||||
|
@ -2131,6 +2131,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
|
||||
&& elfinput
|
||||
&& elfoutput
|
||||
&& (s->flags & SEC_ALLOC) != 0
|
||||
&& (elf_tdata (s->owner)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
|
||||
&& (elf_section_flags (s) & SHF_GNU_MBIND) != 0)
|
||||
{
|
||||
/* Find the output mbind section with the same type, attributes
|
||||
@ -2168,6 +2169,7 @@ gld${EMULATION_NAME}_place_orphan (asection *s,
|
||||
secname = ".mbind.rodata";
|
||||
else
|
||||
secname = ".mbind.text";
|
||||
elf_tdata (link_info.output_bfd)->has_gnu_osabi |= elf_gnu_osabi_mbind;
|
||||
}
|
||||
|
||||
/* Look through the script to see where to place this section. The
|
||||
|
Loading…
Reference in New Issue
Block a user