Variables defined in shared libraries are copied into an executable's
.bss section when code in the executable is non-PIC and thus would
require dynamic text relocations to access the variable directly in
the shared library. Recent x86 toolchains also copy variables into
the executable to gain a small speed improvement.
The problem is that if the variable was originally read-only, the copy
in .bss is writable, potentially opening a security hole. This patch
cures that problem by putting the copy in a section that becomes
read-only after ld.so relocation, provided -z relro is in force.
The patch also fixes a microblaze linker segfault on attempting to
use dynamic bss variables.
bfd/
PR ld/20995
* elf-bfd.h (struct elf_link_hash_table): Add sdynrelro and
sreldynrelro.
(struct elf_backend_data): Add want_dynrelro.
* elfxx-target.h (elf_backend_want_dynrelro): Define.
(elfNN_bed): Update initializer.
* elflink.c (_bfd_elf_create_dynamic_sections): Create
sdynrelro and sreldynrelro sections.
* elf32-arm.c (elf32_arm_adjust_dynamic_symbol): Place variables
copied into the executable from read-only sections into sdynrelro.
(elf32_arm_size_dynamic_sections): Handle sdynrelro.
(elf32_arm_finish_dynamic_symbol): Select sreldynrelro for
dynamic relocs in sdynrelro.
(elf_backend_want_dynrelro): Define.
* elf32-hppa.c (elf32_hppa_adjust_dynamic_symbol)
(elf32_hppa_size_dynamic_sections, elf32_hppa_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-i386.c (elf_i386_adjust_dynamic_symbol)
(elf_i386_size_dynamic_sections, elf_i386_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-metag.c (elf_metag_adjust_dynamic_symbol)
(elf_metag_size_dynamic_sections, elf_metag_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol)
(microblaze_elf_size_dynamic_sections)
(microblaze_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-nios2.c (nios2_elf32_finish_dynamic_symbol)
(nios2_elf32_adjust_dynamic_symbol)
(nios2_elf32_size_dynamic_sections)
(elf_backend_want_dynrelro): As above.
* elf32-or1k.c (or1k_elf_finish_dynamic_symbol)
(or1k_elf_adjust_dynamic_symbol, or1k_elf_size_dynamic_sections)
(elf_backend_want_dynrelro): As above.
* elf32-ppc.c (ppc_elf_adjust_dynamic_symbol)
(ppc_elf_size_dynamic_sections, ppc_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-s390.c (elf_s390_adjust_dynamic_symbol)
(elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-tic6x.c (elf32_tic6x_adjust_dynamic_symbol)
(elf32_tic6x_size_dynamic_sections)
(elf32_tic6x_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf32-tilepro.c (tilepro_elf_adjust_dynamic_symbol)
(tilepro_elf_size_dynamic_sections)
(tilepro_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf64-ppc.c (ppc64_elf_adjust_dynamic_symbol)
(ppc64_elf_size_dynamic_sections, ppc64_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf64-s390.c (elf_s390_adjust_dynamic_symbol)
(elf_s390_size_dynamic_sections, elf_s390_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elf64-x86-64.c (elf_x86_64_adjust_dynamic_symbol)
(elf_x86_64_size_dynamic_sections)
(elf_x86_64_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elfnn-aarch64.c (elfNN_aarch64_adjust_dynamic_symbol)
(elfNN_aarch64_size_dynamic_sections)
(elfNN_aarch64_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elfnn-riscv.c (riscv_elf_adjust_dynamic_symbol)
(riscv_elf_size_dynamic_sections, riscv_elf_finish_dynamic_symbol)
(elf_backend_want_dynrelro): As above.
* elfxx-mips.c (_bfd_mips_elf_adjust_dynamic_symbol)
(_bfd_mips_elf_size_dynamic_sections)
(_bfd_mips_vxworks_finish_dynamic_symbol): As above.
* elfxx-sparc.c (_bfd_sparc_elf_adjust_dynamic_symbol)
(_bfd_sparc_elf_size_dynamic_sections)
(_bfd_sparc_elf_finish_dynamic_symbol): As above.
* elfxx-tilegx.c (tilegx_elf_adjust_dynamic_symbol)
(tilegx_elf_size_dynamic_sections)
(tilegx_elf_finish_dynamic_symbol): As above.
* elf32-mips.c (elf_backend_want_dynrelro): Define.
* elf64-mips.c (elf_backend_want_dynrelro): Define.
* elf32-sparc.c (elf_backend_want_dynrelro): Define.
* elf64-sparc.c (elf_backend_want_dynrelro): Define.
* elf32-tilegx.c (elf_backend_want_dynrelro): Define.
* elf64-tilegx.c (elf_backend_want_dynrelro): Define.
* elf32-microblaze.c (microblaze_elf_adjust_dynamic_symbol): Tidy.
(microblaze_elf_size_dynamic_sections): Handle sdynbss.
* elf32-nios2.c (nios2_elf32_size_dynamic_sections): Make use
of linker shortcuts to dynamic sections rather than comparing
names. Correctly set "got" flag.
ld/
PR ld/20995
* testsuite/ld-arm/farcall-mixed-app-v5.d: Update to suit changed
stub hash table traversal caused by section id increment. Accept
the previous output too.
* testsuite/ld-arm/farcall-mixed-app.d: Likewise.
* testsuite/ld-arm/farcall-mixed-lib-v4t.d: Likewise.
* testsuite/ld-arm/farcall-mixed-lib.d: Likewise.
* testsuite/ld-elf/pr20995a.s, * testsuite/ld-elf/pr20995b.s,
* testsuite/ld-elf/pr20995.r: New test.
* testsuite/ld-elf/elf.exp: Run it.
We've decided to standardize on two flags for RISC-V: "-march" sets the
target architecture (which determines which instructions can be
generated), and "-mabi" sets the target ABI. We needed to rework this
because the old flag set didn't support soft-float or single-float ABIs,
and didn't support an x32-style ABI on RISC-V.
Additionally, we've changed the behavior of the -march flag: it's now a
lot stricter and only parses things we can actually understand.
Additionally, it's now lowercase-only: the rationale is that while the
RISC-V ISA manual specifies that ISA strings are case-insensitive, in
Linux-land things are usually case-sensitive. Since this flag can be
used to determine library paths, we didn't want to bake some
case-insensitivity in there that would case trouble later.
This patch implements these two new flags and removes the old flags that
could conflict with these. There wasn't a RISC-V release before, so we
want to just support a clean flag set.
include/
* elf/riscv.h (EF_RISCV_SOFT_FLOAT): Don't define.
(EF_RISCV_FLOAT_ABI, EF_RISCV_FLOAT_ABI_SOFT): Define.
(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI_DOUBLE): Define.
(EF_RISCV_FLOAT_ABI_QUAD): Define.
bfd/
* elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Use
EF_RISCV_FLOAT_ABI_SOFT instead of EF_RISCV_SOFT_FLOAT.
binutils/
* readelf.c (get_machine_flags): Use
EF_RISCV_FLOAT_ABI_{SOFT,SINGLE,DOBULE,QUAD) instead of
EF_RISCV_{SOFT,HARD}_FLOAT.
gas/
* config/tc-riscv.h (xlen): Delete.
* config/tc-riscv.c (xlen): Make static.
(abi_xlen): New variable.
(options): Replace OPTION_{M32,M64,MSOFT_FLOAT,MHARD_FLOAT,MRVC}
with OPTION_MABI.
(md_longopts): Likewise.
(md_parse_option): Likewise.
(riscv_elf_final_processing): Likewise.
* doc/as.texinfo (Target RISC-V options): Likewise.
* doc/c-riscv.texi (OPTIONS): Likewise.
* config/tc-riscv.c (float_mode): Removed.
(float_abi): New type, specifies the floating-point ABI.
(riscv_set_abi): New function.
(riscv_add_subset): Only allow lower-case ISA names and require
them to start with "rv".
(riscv_after_parse_args): Likewise.
opcodes/
* riscv-dis.c (riscv_disassemble_insn): Default to the ELF's
XLEN when none is provided.
Before this commit we didn't cleanly support CFI directives because the
internal offsets used to get relaxed which broke them. This patch
significantly reworks how we handle linker relaxations:
* DWARF is now properly supported
* There is a ".option norelax" to disable relaxations, for when users
write assembly that can't be relaxed (if it's to be later patched up,
for example).
* There is an additional _RELAX relocation that specifies when previous
relocations can be relaxed.
We're in the process of documenting the RISC-V ELF ABI, which will
include documentation of our relocations
https://github.com/riscv/riscv-elf-psabi-doc/blob/master/riscv-elf.md
but we expect that this relocation set will remain ABI compatible in the
future (ie, it's safe to release).
Thanks to Kuan-Lin Chen for figuring out how to correctly relax the
debug info!
include/
* elf/riscv.h: Add R_RISCV_TPREL_I through R_RISCV_SET32.
bfd/
* reloc.c (BFD_RELOC_RISCV_TPREL_I): New relocation.
(BFD_RELOC_RISCV_TPREL_S): Likewise.
(BFD_RELOC_RISCV_RELAX): Likewise.
(BFD_RELOC_RISCV_CFA): Likewise.
(BFD_RELOC_RISCV_SUB6): Likewise.
(BFD_RELOC_RISCV_SET8): Likewise.
(BFD_RELOC_RISCV_SET8): Likewise.
(BFD_RELOC_RISCV_SET16): Likewise.
(BFD_RELOC_RISCV_SET32): Likewise.
* elfnn-riscv.c (perform_relocation): Handle the new
relocations.
(_bfd_riscv_relax_tls_le): Likewise.
(_bfd_riscv_relax_align): Likewise.
(_bfd_riscv_relax_section): Likewise.
(howto_table): Likewise.
(riscv_reloc_map): Likewise.
(relax_func_t): New type.
(_bfd_riscv_relax_call): Add reserve_size argument, which
controls the maximal offset pessimism. Correct type of max_alignment.
(_bfd_riscv_relax_lui): Likewise.
(_bfd_riscv_relax_tls_le): Likewise.
(_bfd_riscv_relax_align): Likewise.
(_bfd_riscv_relax_section): Compute the required reserve size
when relocating and use it to when calling relax_func.
* bfd-in2.h: Regenerate.
* libbfd.h: Likewise.
gas/
* config/tc-riscv.c (riscv_set_options): Add relax.
(riscv_opts): Likewise.
(s_riscv_option): Add relax and norelax.
(riscv_apply_const_reloc): New function.
(append_insn): Move constant relocation handling to
riscv_apply_const_reloc.
(md_pcrel_from): Likewise.
(parse_relocation): Skip BFD_RELOC_UNUSED.
(md_pcrel_from): Handle BFD_RELOC_RISCV_SUB6,
BFD_RELOC_RISCV_RELAX, BFD_RELOC_RISCV_CFA.
(md_apply_fix): Likewise.
(riscv_pre_output_hook): New function.
* config/tc-riscv.h (md_pre_output_hook): Define.
(riscv_pre_output_hook): Declare.
(DWARF_CIE_DATA_ALIGNMENT): Always -4.
This is a mixed bag of format changes:
* Replacing constants with macros (0xffffffff with MINUS_ONE, for
example). There's one technically functional change in here (some
MINUS_ONEs are changed to 0), but it only changes the behavior of an
otherwise-unused field.
* Using 0 instead of 0x0 in the relocation table.
* There were some missing spaces before parens, the spaces have been
added.
* A handful of comments are now more descriptive.
* A bunch of whitespace-only changes, mostly alignment and brace
newlines.
bfd/
* elfnn-riscv.c: Formatting and comment fixes throughout.
* elfxx-riscv.c: Likewise.
(howto_table): Change the src_mask field from MINUS_ONE to 0 for
R_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPREL32,
R_RISCV_TLS_DTPREL64, R_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL64.
opcodes/
* riscv-opc.c: Formatting fixes.
gas/
* config/tc-riscv.c: Formatting and comment fixes throughout.
I recently ran into this error message and found it's not helpful: it
just tells me some temporary file can't be linked. This slightly
improved one at least tells me it's because of an elf32/elf64 conflict.
* elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Improve
error message when linking elf32 and elf64.