Age | Commit message (Collapse) | Author | Files | Lines |
|
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>
|
|
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>
|
|
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>
|
|
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.
|
|
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.
|
|
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.
|
|
It was never used, pushed by mistake along with pic-and-nonpic-1a-r6.s.
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
|
|
|
|
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
|
|
GNU_PROPERTY_RISCV_FEATURE_1_AND will perform a bitwise AND operation
on the properties of the input files.
|
|
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>
|
|
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>
|
|
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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
Relocation overflows can silently write incorrect value to
the file, so overflow checks are added to avoid this.
|
|
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>
|
|
* testsuite/config/default.exp (dep_plug_opt): Don't set unless
check_plugin_api_available returns true.
|
|
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>
|
|
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.
|
|
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>
|
|
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>
|
|
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>
|
|
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.
|
|
|
|
Modify it a little to run on more targets.
|
|
gettext calls were missing. Fix that, and change a couple of einfo
calls to fatal.
|
|
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>
|
|
.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>
|
|
The fix for 64-bit BFD detection omitted the regeneration of a bunch
of configury files; fix that.
|
|
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>
|
|
PR 30144
|
|
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.
|
|
No uses of %F remain.
* ldmisc.c (vfinfo): Remove %F handling.
|
|
A fix for commit c4fce3ef2927.
|
|
This test is not supposed to use -z force-bti
|