aboutsummaryrefslogtreecommitdiff
path: root/gas/config
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 /gas/config
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 'gas/config')
-rw-r--r--gas/config/obj-elf.c69
1 files changed, 43 insertions, 26 deletions
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)