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.
Remove none, any, all enums.
(struct elf_obj_tdata): Rename has_gnu_symbols field to has_gnu_osabi.
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,
};
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,
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 ++;
- }
- }
-
- /* Let the backend count up any program headers it might need. */
- if (bed->elf_backend_additional_program_headers)
+ 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)
{
int a;
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;
& (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;
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;
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 }
};
#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"
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
file used to set this variable.
{
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";
{
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;
}
}
}
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)
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;
}
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;
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);
}
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);
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.
2019-07-22 Barnaby Wilks <barnaby.wilks@arm.com>
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)
}
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;
attr |= SHF_TLS;
break;
case 'd':
- attr |= SHF_GNU_MBIND;
+ *gnu_attr |= SHF_GNU_MBIND;
break;
case '?':
*is_clone = TRUE;
char *beg;
int type, dummy;
bfd_vma attr;
+ bfd_vma gnu_attr;
int entsize;
int linkonce;
subsegT new_subsection = -1;
return;
type = SHT_NULL;
attr = 0;
+ gnu_attr = 0;
group_name = NULL;
entsize = 0;
linkonce = 0;
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 == ',')
++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
}
}
- if ((attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
+ if ((gnu_attr & SHF_GNU_MBIND) != 0 && *input_line_pointer == ',')
{
++input_line_pointer;
SKIP_WHITESPACE ();
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 ();
}
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);
}
|| strcmp (type_name, "10") == 0
|| strcmp (type_name, "STT_GNU_IFUNC") == 0)
{
- const 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);
+ struct elf_backend_data *bed;
+
+ 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)
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)
#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
#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:
#name: mbind sections without SHF_ALLOC
#error_output: section13.l
+#xfail: msp430-*-* *-*-hpux*
[^:]*: 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
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,
* testsuite/ld-elf/size-1.s,
* testsuite/ld-elf/size-1.t: New test.
&& 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
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