Repository: gimli-rs/object (rust)

Issue:
Please add support for 32-bit SPARC
The `object` crate has already support for 64-bit SPARC (`Sparc64`) while support for 32-bit SPARC (`Sparc`) is missing.

Since `rustc` itself has support for both 32- and 64-bit SPARC, it would be great if `object` could support both flavors as well.

I haven't had the time to write the code myself yet as I just discovered that the missing support in `object` is the reason why `rustc` currently cannot be built for `sparc-linux-unknown-gnu`, so I'm just opening the issue for the time being in the hope that someone might beat me to it.

Pull request description:
Add Architecture::Sparc32
Closes #698 

Patch:
diff --git a/src/common.rs b/src/common.rs
index 4327edb..41f7191 100644
--- a/src/common.rs
+++ b/src/common.rs
@@ -27,6 +27,7 @@ pub enum Architecture {
     S390x,
     Sbf,
     Sharc,
+    Sparc,
     Sparc64,
     Wasm32,
     Wasm64,
@@ -70,6 +71,7 @@ impl Architecture {
             Architecture::S390x => Some(AddressSize::U64),
             Architecture::Sbf => Some(AddressSize::U64),
             Architecture::Sharc => Some(AddressSize::U32),
+            Architecture::Sparc => Some(AddressSize::U32),
             Architecture::Sparc64 => Some(AddressSize::U64),
             Architecture::Wasm32 => Some(AddressSize::U32),
             Architecture::Wasm64 => Some(AddressSize::U64),
diff --git a/src/read/elf/file.rs b/src/read/elf/file.rs
index 01615e1..107a521 100644
--- a/src/read/elf/file.rs
+++ b/src/read/elf/file.rs
@@ -226,6 +226,7 @@ where
             (elf::EM_S390, true) => Architecture::S390x,
             (elf::EM_SBF, _) => Architecture::Sbf,
             (elf::EM_SHARC, false) => Architecture::Sharc,
+            (elf::EM_SPARC, false) => Architecture::Sparc,
             (elf::EM_SPARCV9, true) => Architecture::Sparc64,
             (elf::EM_XTENSA, false) => Architecture::Xtensa,
             _ => Architecture::Unknown,
diff --git a/src/write/elf/object.rs b/src/write/elf/object.rs
index 2785c51..ef97f4f 100644
--- a/src/write/elf/object.rs
+++ b/src/write/elf/object.rs
@@ -141,6 +141,7 @@ impl<'a> Object<'a> {
             Architecture::S390x => true,
             Architecture::Sbf => false,
             Architecture::Sharc => true,
+            Architecture::Sparc => true,
             Architecture::Sparc64 => true,
             Architecture::Xtensa => true,
             _ => {
@@ -411,6 +412,13 @@ impl<'a> Object<'a> {
                     return Err(Error(format!("unimplemented relocation {:?}", reloc)));
                 }
             },
+            Architecture::Sparc => match (kind, encoding, size) {
+                // TODO: use R_SPARC_32 if aligned.
+                (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32,
+                _ => {
+                    return Err(Error(format!("unimplemented relocation {:?}", reloc)));
+                }
+            },
             Architecture::Sparc64 => match (kind, encoding, size) {
                 // TODO: use R_SPARC_32/R_SPARC_64 if aligned.
                 (RelocationKind::Absolute, _, 32) => elf::R_SPARC_UA32,
@@ -631,6 +639,7 @@ impl<'a> Object<'a> {
             (Architecture::S390x, None) => elf::EM_S390,
             (Architecture::Sbf, None) => elf::EM_SBF,
             (Architecture::Sharc, None) => elf::EM_SHARC,
+            (Architecture::Sparc, None) => elf::EM_SPARC,
             (Architecture::Sparc64, None) => elf::EM_SPARCV9,
             (Architecture::Xtensa, None) => elf::EM_XTENSA,
             _ => {


Test patch:
diff --git a/tests/round_trip/mod.rs b/tests/round_trip/mod.rs
index 30a5bb2..11eb757 100644
--- a/tests/round_trip/mod.rs
+++ b/tests/round_trip/mod.rs
@@ -279,6 +279,7 @@ fn elf_any() {
         (Architecture::Riscv64, Endianness::Little),
         (Architecture::S390x, Endianness::Big),
         (Architecture::Sbf, Endianness::Little),
+        (Architecture::Sparc, Endianness::Big),
         (Architecture::Sparc64, Endianness::Big),
         (Architecture::Xtensa, Endianness::Little),
     ]