Fix e_flags for 32-bit MIPS targets in generated object file
In #95604 the compiler started generating a temporary symbols.o which is added to the linker invocation. This object file has an `e_flags` which may be invalid for 32-bit MIPS targets. Even though symbols.o doesn't contain code, linking with [lld fails](https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/MipsArchTree.cpp#L79) with ``` rust-lld: error: foo-cgu.0.rcgu.o: ABI 'o32' is incompatible with target ABI 'n64' ``` because it omits the ABI bits (EF_MIPS_ABI_O32) so lld assumes it's using the N64 ABI. This breaks linking on nightly for the out-of-tree [psx target](https://github.com/ayrtonm/psx-sdk-rs/issues/9), the builtin mipsel-sony-psp target (cc @overdrivenpotato) and any other 32-bit MIPS target using lld. This PR sets the ABI in `e_flags` to O32 since that's the only ABI for 32-bit MIPS that LLVM supports. It also sets other `e_flags` bits based on the target. I had to bump the object crate version since some of these constants were [added recently](https://github.com/gimli-rs/object/pull/433). I'm not sure if this PR needs a test, but I can confirm that it fixes the linking issue on both targets I mentioned.
This commit is contained in:
parent
ecd44958e0
commit
3d5b1eeb75
@ -2509,9 +2509,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.28.1"
|
||||
version = "0.28.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ce8b38d41f9f3618fc23f908faae61510f8d8ce2d99cbe910641e8f1971f084"
|
||||
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
@ -3617,7 +3617,7 @@ dependencies = [
|
||||
"itertools",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"object 0.28.1",
|
||||
"object 0.28.4",
|
||||
"pathdiff",
|
||||
"regex",
|
||||
"rustc_apfloat",
|
||||
@ -5207,7 +5207,7 @@ checksum = "dd95b4559c196987c8451b4e14d08a4c796c2844f9adf4d2a2dbc9b3142843be"
|
||||
dependencies = [
|
||||
"gimli 0.26.1",
|
||||
"hashbrown 0.11.2",
|
||||
"object 0.28.1",
|
||||
"object 0.28.4",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
@ -41,6 +41,6 @@ rustc_target = { path = "../rustc_target" }
|
||||
rustc_session = { path = "../rustc_session" }
|
||||
|
||||
[dependencies.object]
|
||||
version = "0.28.0"
|
||||
version = "0.28.4"
|
||||
default-features = false
|
||||
features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"]
|
||||
|
@ -20,7 +20,7 @@
|
||||
use rustc_session::cstore::MetadataLoader;
|
||||
use rustc_session::Session;
|
||||
use rustc_target::abi::Endian;
|
||||
use rustc_target::spec::Target;
|
||||
use rustc_target::spec::{RelocModel, Target};
|
||||
|
||||
use crate::METADATA_FILENAME;
|
||||
|
||||
@ -132,15 +132,23 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
|
||||
let mut file = write::Object::new(binary_format, architecture, endianness);
|
||||
match architecture {
|
||||
Architecture::Mips => {
|
||||
// copied from `mipsel-linux-gnu-gcc foo.c -c` and
|
||||
// inspecting the resulting `e_flags` field.
|
||||
let e_flags = elf::EF_MIPS_CPIC
|
||||
| elf::EF_MIPS_PIC
|
||||
| if sess.target.options.cpu.contains("r6") {
|
||||
elf::EF_MIPS_ARCH_32R6 | elf::EF_MIPS_NAN2008
|
||||
} else {
|
||||
elf::EF_MIPS_ARCH_32R2
|
||||
};
|
||||
let arch = match sess.target.options.cpu.as_ref() {
|
||||
"mips1" => elf::EF_MIPS_ARCH_1,
|
||||
"mips2" => elf::EF_MIPS_ARCH_2,
|
||||
"mips3" => elf::EF_MIPS_ARCH_3,
|
||||
"mips4" => elf::EF_MIPS_ARCH_4,
|
||||
"mips5" => elf::EF_MIPS_ARCH_5,
|
||||
s if s.contains("r6") => elf::EF_MIPS_ARCH_32R6,
|
||||
_ => elf::EF_MIPS_ARCH_32R2,
|
||||
};
|
||||
// The only ABI LLVM supports for 32-bit MIPS CPUs is o32.
|
||||
let mut e_flags = elf::EF_MIPS_CPIC | elf::EF_MIPS_ABI_O32 | arch;
|
||||
if sess.target.options.relocation_model != RelocModel::Static {
|
||||
e_flags |= elf::EF_MIPS_PIC;
|
||||
}
|
||||
if sess.target.options.cpu.contains("r6") {
|
||||
e_flags |= elf::EF_MIPS_NAN2008;
|
||||
}
|
||||
file.flags = FileFlags::Elf { e_flags };
|
||||
}
|
||||
Architecture::Mips64 => {
|
||||
|
Loading…
Reference in New Issue
Block a user