Skip to content

Conversation

@knickish
Copy link
Contributor

@knickish knickish commented Dec 13, 2024

Load the pc-rel got address to the base register in two steps to avoid the i16 displacement size limitation on the q addressing mode

@knickish knickish force-pushed the m68k_mxgot branch 5 times, most recently from 9f2d3ca to 441b5b3 Compare December 13, 2024 03:26
@glaubitz
Copy link
Contributor

@mshockwave Anything you could do to help with this?

FWIW, we have the full M68000 SysV ELF ABI available now, see: https://people.debian.org/~glaubitz/m68k-sysv-abi.pdf

@mshockwave
Copy link
Member

@mshockwave Anything you could do to help with this?

FWIW, we have the full M68000 SysV ELF ABI available now, see: https://people.debian.org/~glaubitz/m68k-sysv-abi.pdf

Oh I thought this is still a draft PR and that's why it didn't pop up in my radar. @knickish is this ready for review?

@knickish
Copy link
Contributor Author

It is not :/ I haven't figured out how to get this to work yet

@knickish
Copy link
Contributor Author

Although, if you wanted to take a look and tell me what I'm doing wrong that would be appreciated. Otherwise will just keep poking at it as I have time

@glaubitz
Copy link
Contributor

@jrtc27 Do you have any suggestions on this?

@glaubitz
Copy link
Contributor

glaubitz commented Aug 2, 2025

I think implementing support for -mxgot will be the last piece for getting std to build on m68k-unknown-linux-gnu.

After this change, trying to build a cross-compiler for m68k-unknown-linux-gnu fails due to truncated sections:

Building stage1 library artifacts (x86_64-unknown-linux-gnu -> m68k-unknown-linux-gnu)
   Compiling core v0.0.0 (/home/glaubitz/rust/library/core)
   Compiling libc v0.2.174
   Compiling object v0.37.1
   Compiling std v0.0.0 (/home/glaubitz/rust/library/std)
   Compiling compiler_builtins v0.1.160 (/home/glaubitz/rust/library/compiler-builtins/compiler-builtins)
   Compiling rustc-std-workspace-core v1.99.0 (/home/glaubitz/rust/library/rustc-std-workspace-core)
   Compiling alloc v0.0.0 (/home/glaubitz/rust/library/alloc)
   Compiling cfg-if v1.0.1
   Compiling memchr v2.7.5
   Compiling adler2 v2.0.1
   Compiling rustc-demangle v0.1.25
   Compiling panic_abort v0.0.0 (/home/glaubitz/rust/library/panic_abort)
   Compiling unwind v0.0.0 (/home/glaubitz/rust/library/unwind)
   Compiling rustc-std-workspace-alloc v1.99.0 (/home/glaubitz/rust/library/rustc-std-workspace-alloc)
   Compiling panic_unwind v0.0.0 (/home/glaubitz/rust/library/panic_unwind)
   Compiling std_detect v0.1.5 (/home/glaubitz/rust/library/std_detect)
   Compiling gimli v0.32.0
   Compiling hashbrown v0.15.4
   Compiling miniz_oxide v0.8.9
   Compiling addr2line v0.25.0
error: linking with `m68k-linux-gnu-gcc` failed: exit status: 1
  |
  = note:  "m68k-linux-gnu-gcc" "-Wl,--version-script=/tmp/rustcK1ntgn/list" "-Wl,--no-undefined-version" "/tmp/rustcK1ntgn/symbols.o" "<16 object files omitted>" "/tmp/rustcK1ntgn/rmeta.o" "<1 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "/home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/{libpanic_unwind-41954d64cd0e5131,libobject-e7dfe859492e5a92,libmemchr-904192e833d8658e,libaddr2line-bdd16ac6594eb4ec,libgimli-06cea671b41d1cdb,librustc_demangle-1c25569d8f953578,libstd_detect-67ced8ec75312637,libhashbrown-e99b721c6daa8274,librustc_std_workspace_alloc-dc4cb631b4b0371a,libminiz_oxide-266aaf724348ab44,libadler2-3f06c74eae179545,libunwind-08f83db3fc345c63,libcfg_if-cec9171082ee08e4,liblibc-f7f7de4e63c839c7,librustc_std_workspace_core-e05d712ea321af2a,liballoc-09c7b5f14549671f,libcore-086b16fd023003ef,libcompiler_builtins-175b35e00a2eb49a}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/tmp/rustcK1ntgn/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/usr/m68k-linux-gnu/lib/" "-L" "<sysroot>-std/m68k-unknown-linux-gnu/release/build/compiler_builtins-5d87df611ece33fa/out" "-L" "<sysroot>/lib/rustlib/m68k-unknown-linux-gnu/lib" "-o" "<sysroot>-std/m68k-unknown-linux-gnu/release/deps/libstd-a16e04ed26b3b450.so" "-shared" "-Wl,-soname=libstd-a16e04ed26b3b450.so" "-Wl,-z,relro,-z,now" "-Wl,-O1" "-nodefaultlibs" "-Wl,-z,origin" "-Wl,-rpath,$ORIGIN/../lib"
  = note: some arguments are omitted. use `--verbose` to show all linker arguments
  = note: /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/std-a16e04ed26b3b450.std.b9b2668642209c3a-cgu.03.rcgu.o: in function `<&T as core::fmt::Debug>::fmt':
          std.b9b2668642209c3a-cgu.03:(.text._ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h472b78aaa4f6be72E+0x1c): relocation truncated to fit: R_68K_PLT16 against symbol `<std::sys_common::wtf8::Wtf8 as core::fmt::Debug>::fmt' defined in .text._ZN64_$LT$std..sys_common..wtf8..Wtf8$u20$as$u20$core..fmt..Debug$GT$3fmt17h42e207a2f1798686E section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/std-a16e04ed26b3b450.std.b9b2668642209c3a-cgu.03.rcgu.o
          /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/std-a16e04ed26b3b450.std.b9b2668642209c3a-cgu.03.rcgu.o: in function `<&T as core::fmt::Debug>::fmt':
          std.b9b2668642209c3a-cgu.03:(.text._ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6080b056058b9a0aE+0x12): relocation truncated to fit: R_68K_PC16 against `.rodata.cst16'
          std.b9b2668642209c3a-cgu.03:(.text._ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6080b056058b9a0aE+0x2e): relocation truncated to fit: R_68K_PLT16 against symbol `core::fmt::Formatter::debug_tuple' defined in .text._ZN4core3fmt9Formatter11debug_tuple17h9067524984b1253eE section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/libcore-086b16fd023003ef.rlib(core-086b16fd023003ef.core.96277101e887f271-cgu.15.rcgu.o)
          std.b9b2668642209c3a-cgu.03:(.text._ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6080b056058b9a0aE+0x38): relocation truncated to fit: R_68K_PC16 against `.data.rel.ro..Lanon.8b7e79c921bf64809c31e332eda2ec20.65'
          std.b9b2668642209c3a-cgu.03:(.text._ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6080b056058b9a0aE+0x46): relocation truncated to fit: R_68K_PLT16 against symbol `core::fmt::builders::DebugTuple::field' defined in .text._ZN4core3fmt8builders10DebugTuple5field17h094a038c299c5ac5E section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/libcore-086b16fd023003ef.rlib(core-086b16fd023003ef.core.96277101e887f271-cgu.05.rcgu.o)
          std.b9b2668642209c3a-cgu.03:(.text._ZN42_$LT$$RF$T$u20$as$u20$core..fmt..Debug$GT$3fmt17h6080b056058b9a0aE+0x4c): relocation truncated to fit: R_68K_PLT16 against symbol `core::fmt::builders::DebugTuple::finish' defined in .text._ZN4core3fmt8builders10DebugTuple6finish17h6eecb3a577c4183aE section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/libcore-086b16fd023003ef.rlib(core-086b16fd023003ef.core.96277101e887f271-cgu.05.rcgu.o)
          /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/std-a16e04ed26b3b450.std.b9b2668642209c3a-cgu.03.rcgu.o: in function `core::fmt::num::<impl core::fmt::Debug for i32>::fmt':
          std.b9b2668642209c3a-cgu.03:(.text._ZN4core3fmt3num50_$LT$impl$u20$core..fmt..Debug$u20$for$u20$i32$GT$3fmt17h27630fa28532ecf5E+0x3c): relocation truncated to fit: R_68K_PLT16 against symbol `core::fmt::num::imp::<impl core::fmt::Display for i32>::fmt' defined in .text._ZN4core3fmt3num3imp52_$LT$impl$u20$core..fmt..Display$u20$for$u20$i32$GT$3fmt17hc83db331b6f1e2a6E section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/libcore-086b16fd023003ef.rlib(core-086b16fd023003ef.core.96277101e887f271-cgu.12.rcgu.o)
          std.b9b2668642209c3a-cgu.03:(.text._ZN4core3fmt3num50_$LT$impl$u20$core..fmt..Debug$u20$for$u20$i32$GT$3fmt17h27630fa28532ecf5E+0x56): relocation truncated to fit: R_68K_PLT16 against symbol `core::fmt::num::<impl core::fmt::LowerHex for i32>::fmt' defined in .text._ZN4core3fmt3num53_$LT$impl$u20$core..fmt..LowerHex$u20$for$u20$i32$GT$3fmt17hbf7c72afe10669fdE section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/libcore-086b16fd023003ef.rlib(core-086b16fd023003ef.core.96277101e887f271-cgu.00.rcgu.o)
          std.b9b2668642209c3a-cgu.03:(.text._ZN4core3fmt3num50_$LT$impl$u20$core..fmt..Debug$u20$for$u20$i32$GT$3fmt17h27630fa28532ecf5E+0x70): relocation truncated to fit: R_68K_PLT16 against symbol `core::fmt::num::<impl core::fmt::UpperHex for i32>::fmt' defined in .text._ZN4core3fmt3num53_$LT$impl$u20$core..fmt..UpperHex$u20$for$u20$i32$GT$3fmt17h9b0a939ed41c6306E section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/libcore-086b16fd023003ef.rlib(core-086b16fd023003ef.core.96277101e887f271-cgu.00.rcgu.o)
          /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/std-a16e04ed26b3b450.std.b9b2668642209c3a-cgu.03.rcgu.o: in function `core::ptr::drop_in_place<alloc::vec::Vec<u8>>':
          std.b9b2668642209c3a-cgu.03:(.text._ZN4core3ptr46drop_in_place$LT$alloc..vec..Vec$LT$u8$GT$$GT$17hd5f5412e1703927bE.llvm.6252559591537011569+0x22): relocation truncated to fit: R_68K_PLT16 against symbol `__rustc::__rust_dealloc' defined in .text._RNvCs8U6DUB3qQ2r_7___rustc14___rust_dealloc section in /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/std-a16e04ed26b3b450.0ik6ynatekbmgq2qygacp4ml4.rcgu.o
          /home/glaubitz/rust/build/x86_64-unknown-linux-gnu/stage1-std/m68k-unknown-linux-gnu/release/deps/std-a16e04ed26b3b450.std.b9b2668642209c3a-cgu.03.rcgu.o: in function `core::ptr::drop_in_place<std::ffi::os_str::OsString>':
          std.b9b2668642209c3a-cgu.03:(.text._ZN4core3ptr47drop_in_place$LT$std..ffi..os_str..OsString$GT$17h0e8fbd0660a0fb23E+0x26): additional relocation overflows omitted from the output
          collect2: error: ld returned 1 exit status


error: could not compile `std` (lib) due to 1 previous error
Build completed unsuccessfully in 0:14:07

@mshockwave Any chance you could get -mxgot implemented?

@glaubitz
Copy link
Contributor

glaubitz commented Aug 4, 2025

I have applied the patch to Rust's LLVM compiler and then patched the bootstrap.py script as follows:

diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 40e08361a0f..c453a22ff0b 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1117,6 +1117,9 @@ class RustBuild(object):
         if deny_warnings:
             env["RUSTFLAGS"] += " -Dwarnings"
 
+        if self.build_triple().startswith('m68k'):
+            env["RUSTFLAGS"] += " -Cllvm-args=-mxgot"
+
         # Add RUSTFLAGS_BOOTSTRAP to RUSTFLAGS for bootstrap compilation.
         # Note that RUSTFLAGS_BOOTSTRAP should always be added to the end of
         # RUSTFLAGS to be actually effective (e.g., if we have `-Dwarnings` in

Unfortunately, that doesn't work.

; CHECK-NEXT: suba.l %a0, %a1 ; encoding: [0x93,0xc8]
; CHECK-NEXT: move.l #VBRTag@GOTOFF, %d0 ; encoding: [0x20,0x3c,A,A,A,A]
; CHECK-NEXT: ; fixup A - offset: 2, value: VBRTag@GOTOFF, kind: FK_Data_4
; CHECK-NEXT: move.b (1,%a1,%d0), %d0 ; encoding: [0x10,0x31,0x08,0x01]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are two problems here: (1) %a1 tries to compute the "pc-relative" offset of the GOT -- but the PC was from several instructions before (pointed at lea _GLOBAL_OFFSET_TABLE_, %a1), rather than this instruction, so we need to add another offset to compensate the difference (2) Assuming we have the correct %a1 value, I don't think (1,%a1,%d0) here is correct: what we really want is %a1 + pc + %d0 + 1, which should probably use Program Counter Memory Indirect Postindexed addressing mode, or the "x" addressing mode. But sadly we haven't implemented that one yet

@mshockwave
Copy link
Member

Reading GCC's -mxgot description, it seems like the problem is not about the address of _GLOBAL_OFFSET_TABLE_ exceeding 16 bits -- it's the offset that gets over 16 bits. That's why they used an example error message "relocation truncated to fit: R_68K_GOT16O foobar", where GOT16O is the offset between the beginning of GOT to the target entry.

@github-actions
Copy link

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff HEAD~1 HEAD --extensions cpp,h -- llvm/lib/Target/M68k/M68kInstrInfo.cpp llvm/lib/Target/M68k/M68kSubtarget.cpp llvm/lib/Target/M68k/M68kSubtarget.h
View the diff from clang-format here.
diff --git a/llvm/lib/Target/M68k/M68kSubtarget.cpp b/llvm/lib/Target/M68k/M68kSubtarget.cpp
index 8525a8d77..87b592363 100644
--- a/llvm/lib/Target/M68k/M68kSubtarget.cpp
+++ b/llvm/lib/Target/M68k/M68kSubtarget.cpp
@@ -51,10 +51,10 @@ void M68kSubtarget::anchor() {}
 M68kSubtarget::M68kSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
                              const M68kTargetMachine &TM)
     : M68kGenSubtargetInfo(TT, CPU, /*TuneCPU*/ CPU, FS),
-      UseXGOT(this->useXGOT()), TM(TM), InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
-      FrameLowering(*this, this->getStackAlignment()),
-      TLInfo(TM, *this), TargetTriple(TT),
-      TSInfo() {
+      UseXGOT(this->useXGOT()), TM(TM),
+      InstrInfo(initializeSubtargetDependencies(CPU, TT, FS, TM)),
+      FrameLowering(*this, this->getStackAlignment()), TLInfo(TM, *this),
+      TargetTriple(TT), TSInfo() {
   TSInfo = std::make_unique<M68kSelectionDAGInfo>();
 
   CallLoweringInfo.reset(new M68kCallLowering(*getTargetLowering()));

@glaubitz
Copy link
Contributor

Reading GCC's -mxgot description, it seems like the problem is not about the address of _GLOBAL_OFFSET_TABLE_ exceeding 16 bits -- it's the offset that gets over 16 bits. That's why they used an example error message "relocation truncated to fit: R_68K_GOT16O foobar", where GOT16O is the offset between the beginning of GOT to the target entry.

Isn't the too large offset what the linker in the above rustc build is complaining about?

If understand the flag correctly, the backend must emit two instructions instead of one to load offsets larger than 64k. And this is enabled by passing -mxgot.

@knickish
Copy link
Contributor Author

And this is enabled by passing -mxgot.

Will be enabled, to be clear. This is a draft PR and the feature does not really work yet

@mshockwave
Copy link
Member

Isn't the too large offset what the linker in the above rustc build is complaining about?

Correct.
_GLOBAL_OFFSET_TABLE_ pointed to the beginning of the GOT, even if we're able to materialize it when it's over 16 bits, -- which I believe is what this patch does -- that still doesn't solve the problem as the offset to, for example the 9000-th GOT entry, still cannot fit into 16 bits.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants