about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsmrobtzz <148004237+smrobtzz@users.noreply.github.com>2025-05-05 00:21:14 -0400
committerSam Roberts <sam@smrobtzz.dev>2025-05-05 12:34:09 -0400
commit57941afb23ef59e956d2a5ef6604369543edf419 (patch)
treea92cf97bdaeca824aaec9b01b472d2a374b44f5f
parentfa6d0d1ba263c02d1fd660c06f3918ea6e591ce7 (diff)
downloadrust-57941afb23ef59e956d2a5ef6604369543edf419.tar.gz
rust-57941afb23ef59e956d2a5ef6604369543edf419.zip
Apply suggestions from code review
Co-authored-by: Jubilee <workingjubilee@gmail.com>
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs13
-rw-r--r--compiler/rustc_target/src/spec/mod.rs5
2 files changed, 17 insertions, 1 deletions
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 2739f3844b5..ec46c71b0e4 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -271,6 +271,8 @@ pub(super) fn elf_os_abi(sess: &Session) -> u8 {
 pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
     match architecture {
         Architecture::Mips | Architecture::Mips64 | Architecture::Mips64_N32 => {
+            // "N32" indicates an "ILP32" data model on a 64-bit MIPS CPU
+            // like SPARC's "v8+", x86_64's "x32", or the watchOS "arm64_32".
             let is_32bit = architecture == Architecture::Mips;
             let mut e_flags = match sess.target.options.cpu.as_ref() {
                 "mips1" if is_32bit => elf::EF_MIPS_ARCH_1,
@@ -293,7 +295,7 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
             };
 
             // If the ABI is explicitly given, use it, or default to O32 on 32-bit MIPS,
-            // which is the only option.
+            // which is the only "true" 32-bit option that LLVM supports.
             match sess.target.options.llvm_abiname.as_ref() {
                 "o32" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32,
                 "n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2,
@@ -307,6 +309,15 @@ pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
             };
 
             if sess.target.options.relocation_model != RelocModel::Static {
+                // PIC means position-independent code. CPIC means "calls PIC".
+                // CPIC was mutually exclusive with PIC according to
+                // the SVR4 MIPS ABI https://refspecs.linuxfoundation.org/elf/mipsabi.pdf
+                // and should have only appeared on static objects with dynamically calls.
+                // At some point someone (GCC?) decided to set CPIC even for PIC.
+                // Nowadays various things expect both set on the same object file
+                // and may even error if you mix CPIC and non-CPIC object files,
+                // despite that being the entire point of the CPIC ABI extension!
+                // As we are in Rome, we do as the Romans do.
                 e_flags |= elf::EF_MIPS_PIC | elf::EF_MIPS_CPIC;
             }
             if sess.target.options.cpu.contains("r6") {
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index a3f36e51f32..303be54a6d7 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -3568,6 +3568,11 @@ impl Target {
             "s390x" => (Architecture::S390x, None),
             "mips" | "mips32r6" => (Architecture::Mips, None),
             "mips64" | "mips64r6" => (
+                // While there are currently no builtin targets
+                // using the N32 ABI, it is possible to specify
+                // it using a custom target specification. N32
+                // is an ILP32 ABI like the Aarch64_Ilp32
+                // and X86_64_X32 cases above and below this one.
                 if self.options.llvm_abiname.as_ref() == "n32" {
                     Architecture::Mips64_N32
                 } else {