aboutsummaryrefslogtreecommitdiff
path: root/ld
AgeCommit message (Collapse)AuthorFilesLines
22 hoursRISC-V: Fix libpath_suffix selection for ldscriptMark Goncharov6-6/+6
When building a cross-compiler ld for RISC-V Linux systems, you can specify target=riscv64*-linux* to create a linker that supports both 32-bit (-march=rv32*) and 64-bit (-march=rv64*) architectures. The specified -march value populates the EMULATION_NAME variable, which determines the default linker script selection. For proper riscv64 target support, the build process must prepare both elf32lriscv* and elf64lriscv* linker scripts. These should align with the standard RISC-V Linux sysroot directory structure. Signed-off-by: Mark Goncharov <mark.goncharov@syntacore.com>
29 hoursRISC-V: Bind defined symbol locally in PIELinsen Zhou5-0/+36
Reference commit 1dcb9720d62cd053a72c31881b7724ce9f74332c bfd/ * elfnn-riscv.c (RISCV_COPY_INPUT_RELOC): Bind defined symbol locally in PIE. ld/ * testsuite/ld-riscv-elf/pie-bind-locally-a.s: New test source. * testsuite/ld-riscv-elf/pie-bind-locally-b.s: Likewise. * testsuite/ld-riscv-elf/pie-bind-locally-rv32.d: New testcase. * testsuite/ld-riscv-elf/pie-bind-locally-rv64.d: Likewise. Signed-off-by: Linsen Zhou <i@lin.moe>
46 hoursLoongArch: Allow to relax instructions into NOPs after handling alignmentWANG Xuerui4-1/+81
Right now, LoongArch linker relaxation is 2-pass, since after alignment is done, byte deletion can no longer happen. However, as the alignment pass also shrinks text sections, new relaxation chances may well be created after alignment is done. Although at this point we can no longer delete unused instructions without disturbing alignment, we can still replace them with NOPs; popular LoongArch micro-architectures can eliminate NOPs during execution, so we can expect a (very) slight performance improvement from those late-created relaxation chances. To achieve this, the number of relax passes is raised to 3 for LoongArch, and every relaxation handler except loongarch_relax_align is migrated to a new helper loongarch_relax_delete_or_nop, that either deletes bytes or fills the bytes to be "deleted" with NOPs, depending on whether the containing section already has undergone alignment. Also, since no byte can be deleted during this relax pass, in the pass the pending_delete_ops structure is no longer allocated, and loongarch_calc_relaxed_addr(x) degrades to the trivial "return x" in this case. In addition, previously when calculating distances to symbols, an extra segment alignment must be considered, because alignment may increase distance between sites. However in the newly added 3rd pass code size can no longer increase for "closed" sections, so we can skip the adjustment for them to allow for a few more relaxation chances. A simple way to roughly measure this change's effectiveness is to check how many pcalau12i + addi.d pairs are relaxed into pcaddi's. Taking a Firefox 140.0.2 test build of mine as an example: Before: 47842 pcaddi's in libxul.so After: 48089 This is a 0.5% increase, which is kind of acceptable for a peephole optimization like this; of which 9 are due to the "relax"ed symbol distance treatment. Signed-off-by: WANG Xuerui <git@xen0n.name>
3 daysNEWS: sframe: mention new semantics for SFrame FDE function start addrIndu Bhagat1-0/+5
The SFrame FDE's function start address is always emitted as follows by GAS and ld: it is the offset of the start PC of the respective function from the FDE field itself. GAS and ld will emit a flag SFRAME_F_FDE_FUNC_START_PCREL set to 1 when emitting the field in this encoding. * binutils/NEWS: Announce the change of encoding for SFrame FDE func start addr field. * gas/NEWS: Announce the emission of new flag SFRAME_F_FDE_FUNC_START_PCREL. * ld/NEWS: Likewise. Relocatable links are now fixed.
3 daysld: bfd: sframe: fix incorrect r_offset in RELA entriesIndu Bhagat2-0/+36
PR/32666 Incorrect .rela.sframe when using ld -r Input SFrame sections are merged using _bfd_elf_merge_section_sframe (), which clubs all SFrame FDEs together in one blob and all SFrame FREs in another. This, of course, means the offset of an SFrame FDE in the output section cannot be simply derived from the output_offset of the sections. Fix this by providing _bfd_elf_sframe_section_offset () which returns the new offset of the SFrame FDE in the merged SFrame section. Unlike EH_Frame sections, which also use the _bfd_elf_section_offset (), to update the r_offset, SFrame sections have distinct merging semantics. In case of SFrame, the SFrame FDE will not simply sit at location "sec->output_offset + offset of SFrame FDE in sec". Recall that information layout in an SFrame section is as follows: SFrame Header SFrame FDE 1 SFrame FDE 2 ... SFrame FDEn SFrame FREs (Frame Row Entries) Note how the SFrame FDEs and SFrame FREs are clubber together in groups of their own. Next, also note how the elf_link_input_bfd () does a: irela->r_offset += o->output_offset; This, however, needs to be avoided for SFrame sections because the placement of all FDEs is at the beginning of the section. So, rather than conditionalizing this as follows: if (o->sec_info_type != SEC_INFO_TYPE_SFRAME) irela->r_offset += o->output_offset; the implementation in _bfd_elf_sframe_section_offset () does a reverse adjustment, so that the generic parts of the linking process in elf_link_input_bfd () are not made to do SFrame specific adjustments. Add a new enum to track the current state of the SFrame input section during the linking process (SFRAME_SEC_DECODED, SFRAME_SEC_MERGED) for each input SFrame section. This is then used to assert an assumption that _bfd_elf_sframe_section_offset () is being used on an input SFrame sections which have not been merged (via _bfd_elf_merge_section_sframe ()) yet. bfd/ * elf-bfd.h: New declaration. * elf-sframe.c (_bfd_elf_sframe_section_offset): New definition. * elf.c (_bfd_elf_section_offset): Adjust offset if SFrame section. ld/testsuite/ * ld-x86-64/x86-64.exp: New test. * ld-x86-64/sframe-reloc-1.d: New test.
3 daysbfd: gas: ld: libsframe: adopt new encoding for FDE func start addr fieldIndu Bhagat6-6/+12
This patch convenes a set of changes in bfd, gas, ld, libsframe towards moving to the new encoding for the 'sfde_func_start_address' field in SFrame FDE. First, gas must now mark all SFrame sections with the new flag SFRAME_F_FDE_FUNC_START_PCREL. gas was already emitting the field in the said encoding. * gas/gen-sframe.c (output_sframe_internal): Emit the flag SFRAME_F_FDE_FUNC_START_PCREL. Similarly for ld, adopt the new semantics of sfde_func_start_address consistently. This means: - When merging SFrame sections, check that all input SFrame sections have the SFRAME_F_FDE_FUNC_START_PCREL flag set. If the check fails, ld errors out. - When merging SFrame sections, keep even the in-memory contents of the FDE function start address (buffer passed to libsframe sframe_encoder_write () for writing out) encoded in the new semantics. While it is, in theory, possible that instead of doing this change here, we adjust the value of sfde_func_start_address at the final write (sframe_encoder_write) time. But latter is not favorable for maintenanance and may be generally confusing for developers. - When creating SFrame for PLT entries, emit flag SFRAME_F_FDE_FUNC_START_PCREL. include/ * sframe-api.h (SFRAME_F_LD_MUSTHAVE_FLAGS): New definition. bfd/ * elf-sframe.c (_bfd_elf_merge_section_sframe): Check for flag combinatation SFRAME_F_LD_MUSTHAVE_FLAGS set for all input and output SFrame sections. If not, error out. Also, adopt the new semantics of function start address encoding. * bfd/elfxx-x86.c (_bfd_x86_elf_create_sframe_plt): Emit flag SFRAME_F_FDE_FUNC_START_PCREL. Next, for dumping SFrame sections, now that we are emitting the same encoding in GAS, non-relocatable and relocatable SFrame links, it is the time to set relocate to TRUE in debug_displays[]. binutils/ * dwarf.c (struct dwarf_section_display): Allow sframe sections to now be relocated. gas/testsuite/ * gas/cfi-sframe/cfi-sframe-aarch64-pac-ab-key-1.d: Update the test. Relocatable SFrame sections now display non-zero value (appropriate function start address). Now, as the SFrame sections on-disk and in-memory use the new semantics of sfde_func_start_address encoding (i.e., function start address is the offset from the sfde_func_start_address field to the start PC), the calculation to make it human readable (i.e., relatable to the addresses in .text sections) needs adjustment. libsframe/ * sframe-dump.c (dump_sframe_func_with_fres): Adjust the function start address for dumping. Now that both the emission of the new encoding, and the relocation of sections before dumping them is in place, it is time to adjust the testcases. gas/testsuite/ * gas/cfi-sframe/cfi-sframe-aarch64-1.d: Update expected output to include SFRAME_F_FDE_FUNC_START_PCREL instead of NONE. * gas/cfi-sframe/cfi-sframe-aarch64-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-aarch64-3.d: Likewise. * gas/cfi-sframe/cfi-sframe-aarch64-4.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-1.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-10.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-11.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-3.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-4.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-5.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-6.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-7.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-8.d: Likewise. * gas/cfi-sframe/cfi-sframe-common-9.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-1.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-1.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-2.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-3.d: Likewise. * gas/cfi-sframe/cfi-sframe-x86_64-empty-4.d: Likewise. * gas/cfi-sframe/common-empty-1.d: Likewise. * gas/cfi-sframe/common-empty-2.d: Likewise. * gas/cfi-sframe/common-empty-3.d: Likewise. * gas/scfi/x86_64/scfi-cfi-sections-1.d: Likewise. * gas/scfi/x86_64/scfi-dyn-stack-1.d: Likewise. ld/testsuite/ * ld-aarch64/sframe-simple-1.d: Update expected output to include SFRAME_F_FDE_FUNC_START_PCREL. * ld-x86-64/sframe-ibt-plt-1.d: Likewise. * ld-x86-64/sframe-plt-1.d: Likewise. * ld-x86-64/sframe-pltgot-1.d: Likewise. * ld-x86-64/sframe-pltgot-2.d: Likewise. * ld-x86-64/sframe-simple-1.d: Likewise. Naturally, the change of semantics for 'SFrame FDE function start address' has consequences on the implementation in libsframe. As per the new semantics: - Function start address in the SFrame FDE (sfde_func_start_address) is an offset from the FDE function start address field to the start PC of the associated function. Note that, the libsframe library brings the SFrame section contents into its own memory to create a sframe_decoder_ctx object via sframe_decode (). Many internal and user-interfacing APIs then may use sframe_decoder_ctx object to interact and fulfill the work. In context of changing semantics for sfde_func_start_address, following relevant examples may help understand the impact: - sframe_find_fre () finds a the SFrame stack trace data (SFrame FRE) given a lookup offset (offset of lookup_pc from the start of SFrame section). Now that the sfde_func_start_address includes the distance from the sfde_func_start_address field to the start of SFrame section itself, the comparison checks of sfde_func_start_address with the incoming lookup offset need adjustment. - Some internal functions (sframe_get_funcdesc_with_addr_internal () finds SFrame FDE by using binary seach comparing sfde_func_start_address fields, etc.) need adjustments. - sframe_encoder_write () sorts the SFrame FDEs before writing out the SFrame data. Sorting of SFrame FDE via the internal function sframe_sort_funcdesc() needs adjustments: the new encoding of sfde_func_start_address means the distances are not from the same anchor, so cannot be sorted directly. This patch takes the approach of adding a new internal function: - sframe_decoder_get_secrel_func_start_addr (): This function returns the offset of the start PC of the function from the start of SFrame section, i.e., it gives a section-relative offset. As the sframe_decoder_get_secrel_func_start_addr () API needs the value of the function index in the FDE list, another internal API needs sframe_fre_check_range_p () adjustments too. Sorting the FDEs (via sframe_sort_funcdesc ()) is done by first bringing all offsets in sfde_func_start_address relative to start of SFrame section, followed by sorting, and then readjusting the offsets accroding to the new position in the FDE list. libsframe/ * sframe.c (sframe_decoder_get_secrel_func_start_addr): New static function. (sframe_fre_check_range_p): Adjust the interface a bit. (sframe_get_funcdesc_with_addr_internal): Use sframe_decoder_get_secrel_func_start_addr () when comparing sfde_func_start_address with user input offset. (sframe_find_fre): Adopt the new semantics. (sframe_sort_funcdesc): Likewise. For the libsframe testsuite, use the new encoding for FDE func start addr: distance between the FDE sfde_func_start_address field and the start PC of the function itself. Use SFRAME_F_FDE_FUNC_START_PCREL flag, though the sframe_encode () interface in libsframe applies no sanity checks for the encoding itself. libsframe/testsuite/ * libsframe.find/findfre-1.c: Adjust to use the new SFRAME_F_FDE_FUNC_START_PCREL specific encoding. * libsframe.find/findfunc-1.c: Likewise. * libsframe.find/plt-findfre-1.c: Likewise. * libsframe/testsuite/libsframe.decode/DATA2: Update data file due to usage of new SFRAME_F_FDE_FUNC_START_PCREL flag. * libsframe/testsuite/libsframe.encode/encode-1.c: Use flag SFRAME_F_FDE_FUNC_START_PCREL.
3 daysMIPS/LD/testsuite: Remove empty pic-and-nonpic-1-r6.s fileMaciej W. Rozycki1-0/+0
It was never used, pushed by mistake along with pic-and-nonpic-1a-r6.s.
3 daysMIPS/BFD: Fix RELA handling of borrow in the generic linkerMaciej W. Rozycki17-12/+111
Fix an issue with `_bfd_mips_elf_generic_reloc' not taking into account any borrow from the lower part in the handling of relocations of the HI/LO kind and resulting in incorrect calculations made for RELA targets in the generic used for non-ELF output such as S-records. This doesn't trigger for REL targets because they call `_bfd_mips_elf_generic_reloc' indirectly from `_bfd_mips_elf_lo16_reloc' so as to obtain a complete 32-bit addend from relocation pairs and in calculating the addend the latter function uses a hack to work around the lack of borrow handling in the former function. The MIPS/ELF linker is unaffected as it uses its own calculations. Correct the calculation of the relevant partial relocations made in `_bfd_mips_elf_generic_reloc' then to take the borrow into account and remove the hack from `_bfd_mips_elf_lo16_reloc' as no longer needed. Add generic linker test cases accordingly expecting the same disassembly from srec output produced as from ELF output produced by the MIPS/ELF linker.
3 daysMIPS/testsuite: Expand GAS and LD HI/LO relocation coverageMaciej W. Rozycki14-17/+2059
Expand test coverage for HI/LO relocation handling and add conventional MIPS and microMIPS GAS tests as well as conventional MIPS, microMIPS, and MIPS16e2 LD tests, covering R_MIPS_HI16, R_MIPS_LO16, R_MIPS16_HI16, R_MIPS16_LO16, R_MICROMIPS_HI16, and R_MICROMIPS_LO16 relocations, as well as 64-bit R_MIPS_HIGHEST, R_MIPS_HIGHER, R_MICROMIPS_HIGHEST, and R_MICROMIPS_HIGHER relocations. Modify the linker script so as to retain the `.MIPS.abiflags' section so as to disassemble MIPS16e2 code correctly, as MIPS16e2 ASE information is only carried in that section and not in ELF file header's `e_flags'. MIPS16e2 and microMIPS code requires at least the MIPS32r2 ISA (or the MIPS64r2 one for the n32 and n64 ABIs), which is incompatible with the `mips:5900' linker output architecture and causes link failures such as: ./ld-new: tmpdir/mips-hilo1.o: linking mips:isa32r2 module with previous mips:5900 modules ./ld-new: failed to merge target specific data of file tmpdir/mips-hilo1.o Therefore exclude `mips*el-ps2-elf*' targets from microMIPS and MIPS16e2 LD testing.
3 daysMIPS/LD/testsuite: Switch mips16-hilo tests to new disassembly formatMaciej W. Rozycki2-327/+329
Switch the o32 and n32 mips16-hilo MIPS LD tests to the new disassembly format, to reduce discrepancies in output in preparation to reuse for generic linker tests. Taking the first line of disassembly output as an example the difference is: 00500000 <stuff> 6c00 li a0,0 vs: 0x0000000000500000 6c00 li a0,0 for ELF and srec input respectively with the currently used older format requested with `--prefix-addresses', but with the new disassembly format it is exactly the same between the two input formats and no information that we need is lost in the transition: 500000: 6c00 li a0,0
3 daysMIPS/LD/testsuite: Remove symbol table output from mips16-hilo testsMaciej W. Rozycki2-4/+2
The o32 and n32 mips16-hilo MIPS LD tests request symbol table output only to discard it in matching. The symbol table is not relevant to these tests, so remove it from output requested and adjust matching patterns accordingly.
3 daysMIPS/testsuite: Fix %hi usage across MIPS16 GAS/LD testsMaciej W. Rozycki1-2/+2
Fix a couple of places in MIPS GAS and LD R_MIPS16_HI16/R_MIPS16_LO16 relocation tests where the %hi operator has been incorrectly used, but the %lo operator is expected to complement the preceding %hi operation.
3 daysMIPS/LD/testsuite: Fix mips16-hilo IRIX 6 emulation failuresMaciej W. Rozycki2-25/+25
IRIX 6 emulations place external small common symbols in the regular common section instead of the small common section. With mips16-hilo test this leads to a different symbol assignment to memory locations between o32 and n32 ABIs, as follows: --- o32.map +++ n32.map @@ -46,23 +46,22 @@ *(.sdata) 0x00765430 . = 0x765430 -.bss 0x00765430 0x7d8 +.bss 0x00765430 0x7d9 *(.bss) .bss 0x00765430 0x3f0 tmpdir/mips16-hilo.o .bss 0x00765820 0x0 tmpdir/mips16-hilo1.o *(COMMON) - COMMON 0x00765820 0x3e8 tmpdir/mips16-hilo.o + COMMON 0x00765820 0x3e9 tmpdir/mips16-hilo.o 0x00765820 big_external_common + 0x00765c08 small_external_common -.sbss 0x00765c08 0x2 +.sbss 0x00765c09 0x1 *(.sbss) - .sbss 0x00765c08 0x1 tmpdir/mips16-hilo.o + .sbss 0x00765c09 0x1 tmpdir/mips16-hilo.o *(.scommon) - .scommon 0x00765c09 0x1 tmpdir/mips16-hilo.o - 0x00765c09 small_external_common /DISCARD/ *(*) LOAD tmpdir/mips16-hilo.o LOAD tmpdir/mips16-hilo1.o -OUTPUT(tmpdir/dump elf32-bigmips) +OUTPUT(tmpdir/dump elf32-nbigmips) which in turn causes a testsuite regression. Since the specific mapping of symbols does not matter for the scope of the test, reorder the small common section ahead of SBSS, so that the `small_external_common' symbol ends up in the same place regardless of whether via the regular common section or the small common section. Adjust embedded addresses in the disassembly expected accordingly, removing the regression concerned: mips-sgi-irix6 -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs n32 mips64el-ps2-elf -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs n32
3 daysMIPS/LD/testsuite: Unify o32/n32 mips16-hilo test outputMaciej W. Rozycki1-332/+1
The mips16-hilo MIPS LD test case is supposed to produce the same final linked output regardless of whether the o32 or n32 ABI has been chosen for assembly. Reuse o32 output for the n32 test then.
3 daysMIPS/LD/testsuite: Set architecture for MIPS16 HI/LO testsMaciej W. Rozycki3-2/+4
Remove regressions across MIPSr6 targets with the MIPS16 HI/LO tests, which are incompatible with the default architecture of these targets: mips-img-elf -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mips-img-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mips64-img-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mips64-img-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs n32 mips64el-img-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mips64el-img-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs n32 mipsel-img-elf -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsel-img-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa32r6-elf -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa32r6-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa32r6el-elf -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa32r6el-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa64r6-elf -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa64r6-linux-gnuabi64 -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa64r6-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa64r6el-elf -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa64r6el-linux-gnuabi64 -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs mipsisa64r6el-linux -FAIL: R_MIPS16_HI16 and R_MIPS16_LO16 relocs
5 dayscris/testsuite: don't use --em=Jan Beulich172-172/+172
Using such abbreviations is fine when written on an interactive command line by a human. In scripts and alike, doing so risks colliding with later option additions, as is about to occur for gas: Shortly there'll be --emit-local-absolute.
2025-06-24ld/NEWS,binutils/NEWS: Updated supports for RISC-V zicfiss and zicfilpNelson Chu1-0/+3
2025-06-24RISC-V: Fxied failed testsuites when building rv32-linuxNelson Chu6-6/+6
2025-06-24RISC-V: Support for unlabeled landing pad PLT generationKito Cheng3-0/+58
This patch adds support for generating unlabeled landing pad PLT entries for the RISC-V architecture. Unlabeled landing pad will place a LPAD instruction at the PLT entry and PLT header, also PLT header will have few changes due to the offset is different from the original one. Ref: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/417
2025-06-24RISC-V: Implment the merge logic for GNU_PROPERTY_RISCV_FEATURE_1_ANDKito Cheng12-0/+164
GNU_PROPERTY_RISCV_FEATURE_1_AND will perform a bitwise AND operation on the properties of the input files.
2025-06-13ld,dlltool: move read-only delayimp data into .rdataJeremy Drake2-4/+11
This allows the delay IAT to be in its own section with nothing else, as required by IMAGE_GUARD_DELAYLOAD_IAT_IN_ITS_OWN_SECTION, documented at https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#load-configuration-layout Signed-off-by: Jeremy Drake <sourceware-bugzilla@jdrake.com>
2025-06-13bfd,ld,dlltool: Emit delay-load import data into its own sectionLIU Hao2-2/+51
A delay-import symbol (of a function) is resolved when a call to it is made. The delay loader may overwrite the `__imp_` pointer to the actual function after it has been resolved, which requires the pointer itself be in a writeable section. Previously it was placed in the ordinary Import Address Table (IAT), which is emitted into the `.idata` section, which had been changed to read-only in db00f6c3aceabbf03acdb69e74b59b2d2b043cd7, which caused segmentation faults when functions from delay-import library were called. This is PR 32675. This commit makes DLLTOOL emit delay-import IAT into `.didat`, as specified by Microsoft. Most of the code is copied from `.idata`, except that this section is writeable. As a side-effect of this, PR 14339 is also fixed. Using this DEF: ``` ; ws2_32.def LIBRARY "WS2_32.DLL" EXPORTS WSAGetLastError ``` and this C program: ``` // delay.c #define WIN32_LEAN_AND_MEAN 1 #include <windows.h> #include <stdio.h> ///////////////////////////////////////////////////////// // User code ///////////////////////////////////////////////////////// DWORD WINAPI WSAGetLastError(void); extern PVOID __imp_WSAGetLastError; int main(void) { fprintf(stderr, "before delay load, __imp_WSAGetLastError = %p\n", __imp_WSAGetLastError); SetLastError(123); fprintf(stderr, "WSAGetLastError() = %d\n", WSAGetLastError()); fprintf(stderr, "after delay load, __imp_WSAGetLastError = %p\n", __imp_WSAGetLastError); __imp_WSAGetLastError = (PVOID) 1234567; fprintf(stderr, "after plain write, __imp_WSAGetLastError = %p\n", __imp_WSAGetLastError); } ///////////////////////////////////////////////////////// // Overridden `__delayLoadHelper2` facility ///////////////////////////////////////////////////////// extern char __ImageBase[]; PVOID WINAPI ResolveDelayLoadedAPI(PVOID ParentModuleBase, LPCVOID DelayloadDescriptor, PVOID FailureDllHook, PVOID FailureSystemHook, FARPROC* ThunkAddress, ULONG Flags); FARPROC WINAPI DelayLoadFailureHook(LPCSTR name, LPCSTR function); FARPROC WINAPI __delayLoadHelper2(LPCVOID pidd, FARPROC* ppfnIATEntry) { return ResolveDelayLoadedAPI(&__ImageBase, pidd, NULL, (PVOID) DelayLoadFailureHook, ppfnIATEntry, 0); } ``` This program used to crash: ``` $ dlltool -nn -d ws2_32.def -y delay_ws2_32.a $ gcc -g delay.c delay_ws2_32.a -o delay.exe $ ./delay.exe before delay load, __imp_WSAGetLastError = 00007FF6937215C6 Segmentation fault ``` After this commit, it loads and calls `WSAGetLastError()` properly, and `__imp_WSAGetLastError` is writeable: ``` $ dlltool -nn -d ws2_32.def -y delay_ws2_32.a $ gcc -g delay.c delay_ws2_32.a -o delay.exe $ ./delay.exe before delay load, __imp_WSAGetLastError = 00007FF76E2215C6 WSAGetLastError() = 123 after delay load, __imp_WSAGetLastError = 00007FFF191FA720 after plain write, __imp_WSAGetLastError = 000000000012D687 ``` Reference: https://learn.microsoft.com/en-us/windows/win32/secbp/pe-metadata#import-handling Co-authored-by: Jeremy Drake <sourceware-bugzilla@jdrake.com> Signed-off-by: LIU Hao <lh_mouse@126.com> Signed-off-by: Jeremy Drake <sourceware-bugzilla@jdrake.com>
2025-06-11Arm tests: reduce objdump's output and improve some matching patternsMatthieu Longo4-29/+14
Linker scripts can change the sections order in the output. Some matching patterns in tests try to detect the end of a section by detecting the beginning of the next one. However, they mistakenly enforce the name of the next section without any need. This caused the tests to break due to minor changes to the linker scripts. This patch adds '-j <interesting-section>' to the arguments of objdump to dump only relevant information for the tests. This removed the issue related to the ordering of the sections. The matching patterns were also made stricter to match better the expected output.
2025-06-11ld/PE: special-case relocation types only for COFF inputsJan Beulich1-4/+5
In 72cd2c709779 ("ld/PE: no base relocs for section (relative) ones") I made a pre-existing problem quite a bit worse: When looking at a relocation's (numerical) howto->type, that value is meaningful only if the object was of corresponding COFF type. ELF objects in particular have their own enumeration. As it stands, specifically the not entirely unusual R_X86_64_32 and R_X86_64_32S did no longer have relocations emitted for them, due to matching R_AMD64_SECTION and R_AMD64_SECREL in value respectively.
2025-06-11AArch64 variant PCS tests: remove RWX permissions on segmentsMatthieu Longo4-114/+124
The symbols of variant PCS functions require special handling. The variant PCS tests check both the relocation information and the markings in the symbol table. Those tests dump a lot of addresses, so a custom linker script, variant_pcs.ld was used to control reliably the addresses of the sections. However, the linker script does not provide information enough to the linker to assess the right set of permisssions on segments (i.e. Read/Write/Execute). This insufficiency caused the linker to bundle all the sections in a same segment with the union of all the required permissions, i.e. RWX. A segment with such lax permissions constitutes a security hole, so the linker emits the following warning message: <ELF file> has a LOAD segment with RWX permissions. This warning message is noisy in the tests, and has no reason to exist. This issue can be addressed in two ways: - either by providing the right set of permissions on a section so that the linker assigns them to a segment with compatible permissions. - or by providing alignment constraints so that the linker can move the sections automatically to a new segment and set the right permission for non-executable data. The second option seems to be the preferred approach, even if not explicitly recommended. Examples of linker scripts for AArch64 are available at [1]. This patch reorganizes the linker script to eliminate RWX segments by changing the order of the sections and their offset. The tests needed to be amended to match the new addresses. [1]: https://developer.arm.com/documentation/dui0474/m/gnu-ld-script-support-in -armlink/default-gnu-ld-scripts-used-by-armlink/default-ld-script-when -building-an-executable?lang=en
2025-06-11AArch64 BTI/PAC PLT tests: remove RWX permissions on segmentsMatthieu Longo18-59/+86
The bti-far.ld and bti-plt.ld scripts don't provide information enough to the linker to assess the right set of permisssions on segments (i.e. Read/Write/Execute). This insufficiency caused the linker to bundle all the sections in a same segment with the union of all the required permissions, i.e. RWX. A segment with such lax permissions constitutes a security hole, so the linker emits the following warning message: <ELF file> has a LOAD segment with RWX permissions. This warning message is noisy in the tests, and has no reason to exist. This issue can be addressed in two ways: - either by providing the right set of permissions on a section so that the linker assigns them to a segment with compatible permissions. - or by providing alignment constraints so that the linker can move the sections automatically to a new segment and set the right permission for non-executable data. The second option seems to be the preferred approach, even if not explicitly recommended. Examples of linker scripts for AArch64 are available at [1]. The fixes in bti-far.ld and bti-plt.ld are the same, except that bti-far.ld also contains a ".far" section, to make sure that it generates the trampolines correctly. [1]: https://developer.arm.com/documentation/dui0474/m/gnu-ld-script-support-in -armlink/default-gnu-ld-scripts-used-by-armlink/default-ld-script-when -building-an-executable?lang=en
2025-06-11AArch64 tests: remove RWX permissions on segmentsMatthieu Longo6-56/+61
aarch64.ld is the linker script used by most of the relocation tests in AArch64 testsuite. The script does not provide information enough to the linker to assess the right set of permisssions on segments (i.e. Read/Write/Execute). This insufficiency caused the linker to bundle all the sections in a same segment with the union of all the required permissions, i.e. RWX. A segment with such lax permissions constitutes a security hole, so the linker emits the following warning message: <ELF file> has a LOAD segment with RWX permissions. This warning message is noisy in the tests, and has no reason to exist. This issue can be addressed in two ways: - either by providing the right set of permissions on a section so that the linker assigns them to a segment with compatible permissions. - or by providing alignment constraints so that the linker can move the sections automatically to a new segment and set the right permission for non-executable data. The second option seems to be the preferred approach, even if not explicitly recommended. Examples of linker scripts for AArch64 are available at [1]. [1]: https://developer.arm.com/documentation/dui0474/m/gnu-ld-script-support-in -armlink/default-gnu-ld-scripts-used-by-armlink/default-ld-script-when -building-an-executable?lang=en
2025-06-10AArch64, Arm and TIC6x tests: fix typo in linker scriptsMatthieu Longo11-12/+12
The linker scripts for AArch64 and TIC6x were probably originally copied from Arm testsuite, and contain the same typo in the name of the attributes section. This patch fixes the typo across all the testsuites.
2025-06-07AVR: ld/32968 - Assert that .progmem data resides in the lower 64 KiB.Georg-Johann Lay2-10/+15
This patch locates the linker stubs / trampolines *after* all the .progmem sections. This is the natural placement since progmem data has to reside in the lower 64 KiB (it is accessed using LPM), whereas the linker stubs are only required to be located in the lower 128 KiB of program memory. (They must be in the range of EICALL / EIJMP with EIND = 0.) The current location of the linker stubs was motivated by an invalid test case from PR13812 that allocates more than 64 KiB of progmem data. The patch adds an assertion that makes sure that no progmem data is allocated past 0xffff. Data that is accessed using ELPM should be located to .progmemx so that no .progmem addresses are wasted. .progmemx was introduced in 2017 and is used by __memx, __flashx and by the current AVR-LibC. (The compiler uses .jumptables.gcc for its jump dispatch tables since https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63223 / GCC v4.9.2). PR ld/32968 ld/ * scripttempl/avr.sc: Move the trampolines section after the .progmem sections. Assert that .progmem is in the lower 64 KiB.
2025-05-26LoongArch: overflow and underflow checks for R_LARCH_32_PCRELLulu Cai4-0/+16
Relocation overflows can silently write incorrect value to the file, so overflow checks are added to avoid this.
2025-05-19s390: Prevent GOT access rewrite for misaligned symbolsJens Remus6-0/+72
Dereferences of GOT slots with lgrl or lg for global symbols are rewritten to larl to get get rid of the extra memory access. However this is invalid for: - symbols marked for absolute addressing - symbols at odd addresses (larl can handle only even addresses) Commit e6213e09ed0e ("S/390: Prevent GOT access rewrite for certain symbols") added checks for the above. But instead of checking the address of a symbol for being halfword aligned, it tries to deduce this from whether the symbol value and section the symbol is defined in are halfword aligned. The way it is done has two issues: 1. The use of bfd_section_from_elf_index to obtain the section the symbol is defined in may not return the one that remains in the output. For instance for COMDAT sections getting deduplicated the section retrieved using bfd_section_from_elf_index may not be the same as h->root.u.def.section. If COMDAT sections of same group signature have different alignment properties the wrong one may be checked. This may then lead to an erroneous rewrite of lgrl %rX, sym@GOTENT to larl %rX, sym, although the symbol in the remaining section is not properly aligned, triggering an "relocation for misaligned symbol" error at link-time. This may for instance occur when mixing C++ modules compiled with GCC and Clang, as GCC emits a 2-byte alignment and Clang a 1-byte alignment for COMDAT sections containing type information: $ cat sample.cpp #include <typeinfo> struct A {}; const std::type_info &q() { return typeid(A); } $ g++ -c sample.cpp -o sample_gcc.o $ clang++ -c sample.cpp -o sample_clang.o $ readelf -WS sample_gcc.o sample_clang.o Produces (reformatted and reduced): File Name Off Size ES Flg Lk Inf Al sample_gcc.o .rodata._ZTS1A 000080 000004 00 AG 0 0 2 sample_clang.o .rodata._ZTS1A 000058 000003 00 AG 0 0 1 2. The symbol may end up at an even address, if both the symbol value and the section defining the symbol are 1-byte aligned. While this does not trigger an error, it fails an opportunity to rewrite a GOT access. In a Linux Kernel build this causes ~15k GOT accesses using lgrl to be skipped to be rewritten to larl. Resolve both issues by simply checking whether the symbol address is halfword aligned. Do not check the symbol value nor section defining the symbol for halfword alignment. bfd/ PR ld/32969 * elf64-s390.c (elf_s390_relocate_section): Only rewrite lgrl/lg from GOT to larl if symbol address is halfword aligned. ld/testsuite/ PR ld/32969 * ld-s390/s390.exp (pr32969_64-1, pr32969_64-2): Add tests for rewrite of GOT access when COMDAT section deduplication is involved. * ld-s390/pr32969_64-1.dd: New test for rewrite of GOT access when COMDAT section deduplication is involved. * ld-s390/pr32969_64-2.dd: Likewise. * ld-s390/pr32969a.s: Likewise. * ld-s390/pr32969b.s: Likewise. * ld-s390/pr32969c.s: Likewise. Bug: https://sourceware.org/PR32969 Fixes: e6213e09ed0e ("S/390: Prevent GOT access rewrite for certain symbols") Reported-by: Ilya Leoshkevich <iii@linux.ibm.com> Signed-off-by: Jens Remus <jremus@linux.ibm.com>
2025-05-16ld testsuite fail with --disable-pluginsAlan Modra1-6/+7
* testsuite/config/default.exp (dep_plug_opt): Don't set unless check_plugin_api_available returns true.
2025-05-16ld/doc: Remove '.info' suffix in @ref, etcCollin Funk1-2/+2
Texinfo 7.2 began showing warnings like: ld.texi:1026: warning: do not set .info suffix in reference for manual `gcc.info' ld.texi:9689: warning: do not set .info suffix in reference for manual `binutils.info' The Texinfo developers plan to stop removing the '.info' suffix internally in a future release so without this patch the references will break in the future. Signed-off-by: Collin Funk <collin.funk1@gmail.com>
2025-05-15ld: rename ldirname to stat_ldirnameAndreas Schwab1-2/+2
It conflicts with the ldirname function that will be added in the next libiberty sync. ld/: * ldlang.c (stat_ldirname): Rename from ldirname, all uses changed.
2025-05-15binutils: Don't complain plugin with all LTO sections removedH.J. Lu2-0/+22
When all LTO sections have been removed, the BFD lto_type is set to lto_non_ir_object by bfd_set_lto_type. In this case, don't complain needing a plugin when seeing a LTO slim symbol. bfd/ PR binutils/32967 * archive.c (_bfd_compute_and_write_armap): Call bfd_lto_slim_symbol_p to check LTO slim symbol. * bfd-in2.h: Generated. * bfd.c (bfd_lto_slim_symbol_p): New. binutils/ PR binutils/32967 * nm.c (filter_symbols): Call bfd_lto_slim_symbol_p to check LTO slim symbol. ld/ PR binutils/32967 * testsuite/ld-plugin/lto-binutils.exp: Run PR binutils/32967 tests. * testsuite/ld-plugin/strip-1a-s-all.nd: New file. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2025-05-14ld/testsuite: Use $plug_opt for --plugin optionH.J. Lu2-9/+6
Use $plug_opt for --plugin usage, instead of running: run_host_cmd "$CC_FOR_TARGET" "-print-prog-name=liblto_plugin.so" PR binutils/21479 * testsuite/ld-plugin/lto-binutils.exp (lto_plugin): Removed. Replace "--plugin $lto_plugin" with $plug_opt. * testsuite/ld-plugin/lto.exp (lto_plugin): Removed. Replace "--plugin $lto_plugin" with $plug_opt. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2025-05-14strip: Add GCC LTO IR supportH.J. Lu8-3/+367
Add GCC LTO IR support to strip by copying GCC LTO IR input as unknown object file. Don't enable LTO plugin in strip unless all LTO sections should be removed, assuming all LTO sections will be removed with -R .gnu.lto_.*. Add linker LTO tests for strip with --strip-unneeded and GCC LTO IR inputs. binutils/ PR binutils/21479 * objcopy.c: Include "plugin-api.h" and "plugin.h". (lto_sections_removed): New. (command_line_switch): Add OPTION_PLUGIN. (strip_options): Likewise. (strip_usage): Display "--plugin NAME". (copy_unknown_file): New function. (copy_unknown_object): Call copy_unknown_file. (copy_archive): Copy input LTO IR member as unknown object. (copy_file): Set input target to "plugin" for strip if it is unset unless all LTO sections should be removed. Copy input LTO IR file as unknown file. (strip_main): Call bfd_plugin_set_program_name. Handle OPTION_PLUGIN. Set lto_sections_removed to true if all GCC LTO sections should be removed. * doc/binutils.texi: Document --plugin for strip. ld/ PR binutils/21479 * testsuite/ld-plugin/lto-binutils.exp: New file. * testsuite/ld-plugin/strip-1a-fat.c: Likewise. * testsuite/ld-plugin/strip-1a-fat.rd: Likewise. * testsuite/ld-plugin/strip-1b-fat.c: Likewise. * testsuite/ld-plugin/strip-1b-fat.rd: Likewise. * testsuite/ld-plugin/strip-1a.c: Likewise. * testsuite/ld-plugin/strip-1b.c: Likewise. * testsuite/lib/ld-lib.exp (run_cc_link_tests): Add optional trailing ld options. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2025-05-14ld: fix C23 issue in vers7 testSam James1-2/+2
This test is UNSUPPORTED on arm64 with GCC 15 (which defaults to -std=gnu23) because it now prototypes "no arguments". PR ld/32546 * ld-elfvers/vers7.c: Fix function definitions for C23.
2025-05-08Remove unnecessary use of pragma once in pr25618 testAlan Modra2-2/+0
2025-04-30PR 32896 testcaseAlan Modra2-7/+11
Modify it a little to run on more targets.
2025-04-30kvxelf.em: translate error messagesAlan Modra1-7/+7
gettext calls were missing. Fix that, and change a couple of einfo calls to fatal.
2025-04-29elf: Properly set sh_offset for .tbss sectionsH.J. Lu2-0/+34
Set sh_offset for .tbss sections to their nominal offset after aligning. They are not loaded from disk so the value doesn't really matter, except when the .tbss section is the first one in a PT_TLS segment. In that case, it sets the p_offset for the PT_TLS segment, which according to the ELF gABI ought to satisfy p_offset % p_align == p_vaddr % p_align. bfd/ PR ld/32896 * elf.c (assign_file_positions_for_load_sections): Properly set sh_offset for .tbss sections. ld/ PR ld/32896 * testsuite/ld-elf/tbss4.d: New file. * testsuite/ld-elf/tbss4.s: Likewise. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2025-04-29dwarf: Dump .debug_loclists only for DWARF-5H.J. Lu5-0/+1163
.debug_loclists section is loaded into debug_information as DWARF-5 debug info and .debug_loc section is loaded into debug_information as pre-DWARF-5 debug info. When dumping .debug_loc section, we should only process pre-DWARF-5 debug info in debug_information. When dumping .debug_loclists section, we should only process DWARF-5 info in debug_information. binutils/ PR binutils/32809 * dwarf.c (display_debug_loc): Dump .debug_loclists only for DWARF-5. ld/ PR binutils/32809 * testsuite/ld-x86-64/dwarf4.s: New file. * testsuite/ld-x86-64/dwarf5a.s: Likewise. * testsuite/ld-x86-64/dwarf5b.s: Likewise. * testsuite/ld-x86-64/pr32809.d: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run pr32809. Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
2025-04-28Regenerate more configury files for 64-bit BFD detection fixMaciej W. Rozycki1-3/+0
The fix for 64-bit BFD detection omitted the regeneration of a bunch of configury files; fix that.
2025-04-28Fix 64-bit BFD detection causing build failuresMaciej W. Rozycki2-259/+38
We have a discrepancy with 64-bit BFD handling across our component subdirectories leading to link failures such as: ld: ../opcodes/.libs/libopcodes.a(disassemble.o): in function `disassembler': disassemble.c:(.text+0x65): undefined reference to `print_insn_alpha' ld: disassemble.c:(.text+0x105): undefined reference to `print_insn_ia64' ld: disassemble.c:(.text+0x11d): undefined reference to `print_insn_loongarch' ld: disassemble.c:(.text+0x1a1): undefined reference to `print_insn_big_mips' [...] with some configurations having a 32-bit host and 64-bit BFD, such as: `--host=i386-linux-gnu --target=riscv64-linux-gnu --enable-targets=all'. This is ultimately due to how 64-bit BFD is enabled for bfd/ itself and other subdirectorses and has been a regression from commit 1d5269c994bf ("unify 64-bit bfd checks"). For bfd/ the BFD_64_BIT autoconf macro from config/bfd64.m4 is used combined with this logic in bfd/configure.ac: case ${host64}-${target64}-${want64} in *true*) wordsize=64 bfd64_libs='$(BFD64_LIBS)' all_backends='$(BFD64_BACKENDS) $(BFD32_BACKENDS)' [...] ;; false-false-false) wordsize=32 all_backends='$(BFD32_BACKENDS)' ;; esac where the value of ${wordsize} switches between 32-bit and 64-bit BFD via these pieces: #define BFD_ARCH_SIZE @wordsize@ and: #if BFD_ARCH_SIZE >= 64 #define BFD64 #endif in bfd/bfd-in.h, which ultimately becomes a part of "bfd.h". Then ${host64} is determined in bfd/configure.ac from the host's word size, via the host's pointer size: if test "x${ac_cv_sizeof_void_p}" = "x8"; then host64=true fi And ${target64} is determined in bfd/configure.ac from the target's word size: if test ${target_size} = 64; then target64=true fi Where multiple targets have been requested with `--enable-targets=all' the presence of any 64-bit target will set "true" here. Finally ${want64} is set according to `--enable-64-bit-bfd' user option with an arrangement involving BFD_64_BIT: BFD_64_BIT if test $enable_64_bit_bfd = yes ; then want64=true else want64=false fi which also, redundantly, checks and sets its result upon the host's word size. Lastly ${want64} is also selectively set by target fragments in bfd/config.bfd, which mostly if not completely overlaps with ${target64} setting as described above. Conversely other subdirectories only rely on BFD_64_BIT, so they fail to notice that BFD is 64-bit and do not enable their 64-bit handling where the host requested is 32-bit and 64-bit BFD has been enabled other than with `--enable-64-bit-bfd'. One consequence is opcodes/disassemble.c enables calls to its numerous own 64-bit backends by checking the BFD64 macro from "bfd.h", however does not actually enable said backends in its Makefile. Hence the link errors quoted above. Address the problem then by moving the `--enable-64-bit-bfd' option back to bfd/configure.ac and remove the call to BFD_64_BIT from there and then rewrite the macro in terms of checking for the presence of BFD64 macro in "bfd.h", which is the canonical way of determining whether BFD is 64-bit or not. Rather than running `grep' directly on ../bfd/bfd-in3.h as the opcodes/ fragment used to before the problematic commit: if grep '#define BFD_ARCH_SIZE 64' ../bfd/bfd-in3.h > /dev/null; then run the preprocessor on "bfd.h", which allows to invoke the macro from configure.ac files placed in subdirectories located at deeper levels, by relying on the preprocessor's search path. This requires however that the invokers rely on `all-bfd' rather than `configure-bfd' for their `configure' invocation stage, because "bfd.h" is made by `make all' rather than `configure' in bfd/. Do not cache the result of this check however, as reconfiguring a tree such as to flip `--enable-64-bit-bfd' on or to change a secondary target may affect BFD64 and we have no access to information about secondary targets in BFD_64_BIT. Also remove the ENABLE_BFD_64_BIT automake conditional, as it's not used anywhere. Last but not least remove the hack from gdb/configure.ac to fail builds for `mips*-*-*' hosts where `--enable-targets=all' has been requested, but `--enable-64-bit-bfd' has not as it's no longer needed. Such builds complete successfully now, having enabled 64-bit BFD implicitly. Tested-By: Guinevere Larsen <guinevere@redhat.com> Tested-By: Luis Machado <luis.machado@arm.com> Approved-By: Alan Modra <amodra@gmail.com> Approved-By: Luis Machado <luis.machado@arm.com>
2025-04-25BFD linker: Allow target backends to provide alternate entry names.Pali Roh?r6-19/+88
PR 30144
2025-04-23string merge section map outputAlan Modra1-1/+2
This fixes an inconsistency in the linker map file, where string merge sections (other than the first) kept their sizes. String merge sections of like entsize all are accounted in the fisrt string merge section size. * ldlang.c (print_input_section): Print SEC_EXCLUDE section size as zero.
2025-04-23PR 32603 followup, remove %F from einfoAlan Modra1-10/+0
No uses of %F remain. * ldmisc.c (vfinfo): Remove %F handling.
2025-04-18build error with 32-bit host and 64-bit time_tAlan Modra1-2/+2
A fix for commit c4fce3ef2927.
2025-04-17testsuite: fix typo in bti-plt-1-b.d testYury Khrustalev1-1/+1
This test is not supposed to use -z force-bti