Skip to content

Commit 1c80ac0

Browse files
committed
Auto merge of #96930 - ayrtonm:mips32-tmp-file, r=petrochenkov
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 is invalid for 32-bit MIPS targets. Even though symbols.o doesn't contain code, linking these targets with [lld fails](https://github.com/llvm/llvm-project/blob/main/lld/ELF/Arch/MipsArchTree.cpp#L76-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 [mipsel-sony-psx target](ayrtonm/psx-sdk-rs#9), the builtin mipsel-sony-psp target (cc `@overdrivenpotato)` and probably 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 to avoid similar issues with the object file arch and PIC. I had to bump the object crate version since some of these constants were [added recently](gimli-rs/object#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.
2 parents 97d48be + 3d5b1ee commit 1c80ac0

File tree

3 files changed

+23
-15
lines changed

3 files changed

+23
-15
lines changed

Cargo.lock

+4-4
Original file line numberDiff line numberDiff line change
@@ -2509,9 +2509,9 @@ dependencies = [
25092509

25102510
[[package]]
25112511
name = "object"
2512-
version = "0.28.1"
2512+
version = "0.28.4"
25132513
source = "registry+https://github.com/rust-lang/crates.io-index"
2514-
checksum = "7ce8b38d41f9f3618fc23f908faae61510f8d8ce2d99cbe910641e8f1971f084"
2514+
checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424"
25152515
dependencies = [
25162516
"crc32fast",
25172517
"flate2",
@@ -3617,7 +3617,7 @@ dependencies = [
36173617
"itertools",
36183618
"jobserver",
36193619
"libc",
3620-
"object 0.28.1",
3620+
"object 0.28.4",
36213621
"pathdiff",
36223622
"regex",
36233623
"rustc_apfloat",
@@ -5207,7 +5207,7 @@ checksum = "dd95b4559c196987c8451b4e14d08a4c796c2844f9adf4d2a2dbc9b3142843be"
52075207
dependencies = [
52085208
"gimli 0.26.1",
52095209
"hashbrown 0.11.2",
5210-
"object 0.28.1",
5210+
"object 0.28.4",
52115211
"tracing",
52125212
]
52135213

compiler/rustc_codegen_ssa/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ rustc_target = { path = "../rustc_target" }
4141
rustc_session = { path = "../rustc_session" }
4242

4343
[dependencies.object]
44-
version = "0.28.0"
44+
version = "0.28.4"
4545
default-features = false
4646
features = ["read_core", "elf", "macho", "pe", "unaligned", "archive", "write"]

compiler/rustc_codegen_ssa/src/back/metadata.rs

+18-10
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_metadata::EncodedMetadata;
2020
use rustc_session::cstore::MetadataLoader;
2121
use rustc_session::Session;
2222
use rustc_target::abi::Endian;
23-
use rustc_target::spec::Target;
23+
use rustc_target::spec::{RelocModel, Target};
2424

2525
use crate::METADATA_FILENAME;
2626

@@ -132,15 +132,23 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
132132
let mut file = write::Object::new(binary_format, architecture, endianness);
133133
match architecture {
134134
Architecture::Mips => {
135-
// copied from `mipsel-linux-gnu-gcc foo.c -c` and
136-
// inspecting the resulting `e_flags` field.
137-
let e_flags = elf::EF_MIPS_CPIC
138-
| elf::EF_MIPS_PIC
139-
| if sess.target.options.cpu.contains("r6") {
140-
elf::EF_MIPS_ARCH_32R6 | elf::EF_MIPS_NAN2008
141-
} else {
142-
elf::EF_MIPS_ARCH_32R2
143-
};
135+
let arch = match sess.target.options.cpu.as_ref() {
136+
"mips1" => elf::EF_MIPS_ARCH_1,
137+
"mips2" => elf::EF_MIPS_ARCH_2,
138+
"mips3" => elf::EF_MIPS_ARCH_3,
139+
"mips4" => elf::EF_MIPS_ARCH_4,
140+
"mips5" => elf::EF_MIPS_ARCH_5,
141+
s if s.contains("r6") => elf::EF_MIPS_ARCH_32R6,
142+
_ => elf::EF_MIPS_ARCH_32R2,
143+
};
144+
// The only ABI LLVM supports for 32-bit MIPS CPUs is o32.
145+
let mut e_flags = elf::EF_MIPS_CPIC | elf::EF_MIPS_ABI_O32 | arch;
146+
if sess.target.options.relocation_model != RelocModel::Static {
147+
e_flags |= elf::EF_MIPS_PIC;
148+
}
149+
if sess.target.options.cpu.contains("r6") {
150+
e_flags |= elf::EF_MIPS_NAN2008;
151+
}
144152
file.flags = FileFlags::Elf { e_flags };
145153
}
146154
Architecture::Mips64 => {

0 commit comments

Comments
 (0)