From df3a023bd614133fe69afb02cd0e8f3e590a36a9 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Tue, 23 Jul 2019 17:54:42 +0930 Subject: 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. --- gas/ChangeLog | 15 +++++++++ gas/config/obj-elf.c | 69 ++++++++++++++++++++++++-------------- gas/testsuite/gas/elf/section12a.d | 2 ++ gas/testsuite/gas/elf/section12b.d | 5 +-- gas/testsuite/gas/elf/section13.d | 1 + gas/testsuite/gas/elf/section13.l | 2 +- 6 files changed, 65 insertions(+), 29 deletions(-) (limited to 'gas') diff --git a/gas/ChangeLog b/gas/ChangeLog index 47938f7..19ca464 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,20 @@ 2019-07-23 Alan Modra + * 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 + * testsuite/gas/elf/section12a.d: Don't skip for rx. 2019-07-22 Barnaby Wilks diff --git a/gas/config/obj-elf.c b/gas/config/obj-elf.c index af35fee..fd2c943 100644 --- a/gas/config/obj-elf.c +++ b/gas/config/obj-elf.c @@ -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; - - 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) @@ -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) diff --git a/gas/testsuite/gas/elf/section12a.d b/gas/testsuite/gas/elf/section12a.d index 3e04171..2b6aa3e 100644 --- a/gas/testsuite/gas/elf/section12a.d +++ b/gas/testsuite/gas/elf/section12a.d @@ -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 diff --git a/gas/testsuite/gas/elf/section12b.d b/gas/testsuite/gas/elf/section12b.d index 717bc1a..fcbb697 100644 --- a/gas/testsuite/gas/elf/section12b.d +++ b/gas/testsuite/gas/elf/section12b.d @@ -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: diff --git a/gas/testsuite/gas/elf/section13.d b/gas/testsuite/gas/elf/section13.d index 940ccec..9f4fe36 100644 --- a/gas/testsuite/gas/elf/section13.d +++ b/gas/testsuite/gas/elf/section13.d @@ -1,2 +1,3 @@ #name: mbind sections without SHF_ALLOC #error_output: section13.l +#xfail: msp430-*-* *-*-hpux* diff --git a/gas/testsuite/gas/elf/section13.l b/gas/testsuite/gas/elf/section13.l index c56b5ae..3ddf54a 100644 --- a/gas/testsuite/gas/elf/section13.l +++ b/gas/testsuite/gas/elf/section13.l @@ -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 -- cgit v1.1