mirror of
https://github.com/rust-lang/rust.git
synced 2025-10-04 19:28:29 +00:00

Set elf e_flags on ppc64 targets according to abi (This PR contains the non user-facing changes of https://github.com/rust-lang/rust/pull/142321) Fixes https://github.com/rust-lang/rust/issues/85589 by making sure that ld.lld errors out instead of generating a broken binary. Basically the problem is that ld.lld assumes that all ppc64 object files with e_flags=0 are object files which use the ELFv2 ABI (this here is the check https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/PPC64.cpp#L639). This pull request sets the correct e_flags to indicate the used ABI so ld.lld errors out when encountering ELFv1 ABI files instead of generating a broken binary. For example compare code generation for this program (file name ``min.rs``): ```rust #![feature(no_core, lang_items, repr_simd)] #![crate_type = "bin"] #![no_core] #![no_main] #[lang = "sized"] trait Sized {} #[lang = "copy"] trait Copy {} #[lang = "panic_cannot_unwind"] pub fn panic() -> ! { loop {} } pub fn my_rad_unmangled_function() { loop {} } pub fn my_rad_function() { loop {} } #[no_mangle] pub fn _start() { my_rad_unmangled_function(); my_rad_function(); } ``` Compile with ``rustc --target=powerpc64-unknown-linux-gnu -C linker=ld.lld -C relocation-model=static min.rs`` Before change: ``` $ llvm-objdump -d min Disassembly of section .text: 000000001001030c <.text>: ... 10010334: 7c 08 02 a6 mflr 0 10010338: f8 21 ff 91 stdu 1, -112(1) 1001033c: f8 01 00 80 std 0, 128(1) 10010340: 48 02 00 39 bl 0x10030378 <_ZN3min25my_rad_unmangled_function17h7471c49af58039f5E> 10010344: 60 00 00 00 nop 10010348: 48 02 00 49 bl 0x10030390 <_ZN3min15my_rad_function17h37112b8fd1008c9bE> 1001034c: 60 00 00 00 nop ... ``` The branch instructions ``bl 0x10030378`` and ``bl 0x10030390`` are jumping into the ``.opd`` section which is data. That is a broken binary (because fixing those branches is the task of the linker). After change: ``` error: linking with `ld.lld` failed: exit status: 1 | = note: "ld.lld" "/tmp/rustcNYKZCS/symbols.o" "<1 object files omitted>" "--as-needed" "-L" "/tmp/rustcNYKZCS/raw-dylibs" "-Bdynamic" "--eh-frame-hdr" "-z" "noexecstack" "-L" "<sysroot>/lib/rustlib/powerpc64-unknown-linux-gnu/lib" "-o" "min" "--gc-sections" "-z" "relro" "-z" "now" = note: some arguments are omitted. use `--verbose` to show all linker arguments = note: ld.lld: error: /tmp/rustcNYKZCS/symbols.o: ABI version 1 is not supported ``` Which is correct because ld.lld doesn't support ELFv1 ABI.
rustc_target
contains some very low-level details that are
specific to different compilation targets and so forth.
For more information about how rustc works, see the rustc dev guide.