Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The 1.27 rust-stable bootstrap build step fails on mips64 #52108

Closed
draganmladjenovic opened this issue Jul 6, 2018 · 28 comments · Fixed by #111772
Closed

The 1.27 rust-stable bootstrap build step fails on mips64 #52108

draganmladjenovic opened this issue Jul 6, 2018 · 28 comments · Fixed by #111772
Labels
C-bug Category: This is a bug. O-MIPS Target: MIPS processors P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@draganmladjenovic
Copy link
Contributor

The error mesage is:

`error: linking with `cc` failed: exit code: 1
  |
  = note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-L" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.138pesuvab4dy035.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.15kq92zzbmxot4k9.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.16u6js6g0l3k1ic6.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.1ckp3bwk0jmrbky4.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.1im38lueib99jsk0.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.1mvmz58owquyropc.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.1y16o1qfye96o7m0.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.1zeawhkbeobww1zn.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.1zwd8n7bcl3vhvvh.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.23tqyymcb18u96mb.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.2jqywn86b2gsqohu.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.2lyh15q6cjwzy18c.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.3171x0bwu82dptu7.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.35af7odfhiqsblci.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.3ayaeypdcro9d6yk.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.3cx7oljifvb206q7.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.3g94tobrpgum5dk6.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.3rngp6bm2u2q5z0y.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.43v6g0y2xsxoggnt.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.45nf4z58qqykpcpi.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.48721dc4k5qxei0u.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.49a7n47po4ttqjl7.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.4b8ptp1vn215jmoe.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.4dvpkvhelzqn37of.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.4xq48u46a1pwiqn7.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.4ybye971cqflgun6.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.4yh8x2b62dcih00t.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.4ypvbwho0bu5tnww.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.8xzrsc1ux72v29j.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.9elsx31vb4it187.rcgu.o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.e19kx9t7xhzajfl.rcgu.o" "-o" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50" "/home/draganm/work/rust/build/bootstrap/debug/deps/bootstrap-e1de2c0797369e50.crate.allocator.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "-L" "/home/draganm/work/rust/build/bootstrap/debug/deps" "-L" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib" "-Wl,-Bstatic" "/home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libpetgraph-21e72575365cd228.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libordermap-5f1d6b4d32742667.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libfixedbitset-18048728a1801049.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libtime-736f43167516e58e.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libtoml-51916d91f90fa53e.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libnum_cpus-12ac34ed547f3180.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libgetopts-2a463d2722dba7b8.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libfiletime-c8a8e6c0f3aa27b0.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/liblibc-2d42ca337778fc07.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libcfg_if-cf754c2e7fcf3720.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libcmake-72d576f6c4aa644f.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libcc-6cc2976f70db579f.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libserde_json-9db09363bcefa01f.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libitoa-9993a924e130a429.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libdtoa-ca37bbda1bb7c5a0.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libserde-9d7a61a020c48540.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libnum_traits-77a6d928f7bf0203.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/liblazy_static-83ca103b78acf207.rlib" "/home/draganm/work/rust/build/bootstrap/debug/deps/libbuild_helper-807bedf9f7568fde.rlib" "-Wl,--start-group" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/libstd-8d847bbe97fc9dc5.rlib" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/libpanic_unwind-008c42aad548e7dd.rlib" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/libunwind-0fe53371ec419e32.rlib" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/liballoc_system-9dec1cbd51097ce1.rlib" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/liblibc-6a4fb915dd86d140.rlib" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/liballoc-7ebba6af2d3cc324.rlib" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/libstd_unicode-7a26f8b3cf380464.rlib" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/libcore-b0c2d164a9741309.rlib" "-Wl,--end-group" "/home/draganm/work/rust/build/mips64el-unknown-linux-gnuabi64/stage0/lib/rustlib/mips64el-unknown-linux-gnuabi64/lib/libcompiler_builtins-66d072e25a9acee3.rlib" "-Wl,-Bdynamic" "-l" "util" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "gcc_s" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util"
  = note: /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `<std::collections::hash::map::HashMap<K, V, S> as core::clone::Clone>::clone':
          /checkout/src/libstd/collections/hash/map.rs:399:(.text._ZN102_$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$u20$as$u20$core..clone..Clone$GT$5clone17hde56aa8496891c67E+0x8c): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
          /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `<std::collections::hash::map::HashMap<K, V, S> as core::iter::traits::IntoIterator>::into_iter':
          /checkout/src/libstd/collections/hash/map.rs:1834:(.text._ZN116_$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$u20$as$u20$core..iter..traits..IntoIterator$GT$9into_iter17h3971322724732454E+0x84): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
          /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `<std::collections::hash::map::HashMap<K, V, S> as core::iter::traits::Extend<(K, V)>>::extend':
          /checkout/src/libstd/collections/hash/map.rs:2581:(.text._ZN136_$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$u20$as$u20$core..iter..traits..Extend$LT$$LP$K$C$$u20$V$RP$$GT$$GT$6extend17h8b839c2a084c624aE+0xcc): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
          /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `<std::collections::hash::map::HashMap<K, V, S> as core::iter::traits::Extend<(K, V)>>::extend':
          /checkout/src/libstd/collections/hash/map.rs:2581:(.text._ZN136_$LT$std..collections..hash..map..HashMap$LT$K$C$$u20$V$C$$u20$S$GT$$u20$as$u20$core..iter..traits..Extend$LT$$LP$K$C$$u20$V$RP$$GT$$GT$6extend17hb662b5607a17e017E+0xb4): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
          /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `<std::collections::hash::map::InternalEntry<K, V, &'a mut std::collections::hash::table::RawTable<K, V>>>::into_entry':
          /checkout/src/libstd/collections/hash/map.rs:1680:(.text._ZN157_$LT$std..collections..hash..map..InternalEntry$LT$K$C$$u20$V$C$$u20$$RF$$u27$a$u20$mut$u20$std..collections..hash..table..RawTable$LT$K$C$$u20$V$GT$$GT$$GT$10into_entry17h96e9d8440f6f2c01E+0x2ac): relocation truncated to fit: R_MIPS_CALL16 against `memcpy@@GLIBC_2.0'
          /checkout/src/libstd/collections/hash/map.rs:1686:(.text._ZN157_$LT$std..collections..hash..map..InternalEntry$LT$K$C$$u20$V$C$$u20$$RF$$u27$a$u20$mut$u20$std..collections..hash..table..RawTable$LT$K$C$$u20$V$GT$$GT$$GT$10into_entry17h96e9d8440f6f2c01E+0x44c): relocation truncated to fit: R_MIPS_CALL16 against `memcpy@@GLIBC_2.0'
          /checkout/src/libstd/collections/hash/map.rs:1686:(.text._ZN157_$LT$std..collections..hash..map..InternalEntry$LT$K$C$$u20$V$C$$u20$$RF$$u27$a$u20$mut$u20$std..collections..hash..table..RawTable$LT$K$C$$u20$V$GT$$GT$$GT$10into_entry17h96e9d8440f6f2c01E+0x478): relocation truncated to fit: R_MIPS_CALL16 against `memcpy@@GLIBC_2.0'
          /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `<std::collections::hash::map::InternalEntry<K, V, &'a mut std::collections::hash::table::RawTable<K, V>>>::into_entry':
          /checkout/src/libstd/collections/hash/map.rs:1680:(.text._ZN157_$LT$std..collections..hash..map..InternalEntry$LT$K$C$$u20$V$C$$u20$$RF$$u27$a$u20$mut$u20$std..collections..hash..table..RawTable$LT$K$C$$u20$V$GT$$GT$$GT$10into_entry17he24a1b5fedc0b2f6E+0x26c): relocation truncated to fit: R_MIPS_CALL16 against `memcpy@@GLIBC_2.0'
          /checkout/src/libstd/collections/hash/map.rs:1686:(.text._ZN157_$LT$std..collections..hash..map..InternalEntry$LT$K$C$$u20$V$C$$u20$$RF$$u27$a$u20$mut$u20$std..collections..hash..table..RawTable$LT$K$C$$u20$V$GT$$GT$$GT$10into_entry17he24a1b5fedc0b2f6E+0x46c): relocation truncated to fit: R_MIPS_CALL16 against `memcpy@@GLIBC_2.0'
          /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `std::collections::hash::map::robin_hood':
          /checkout/src/libstd/collections/hash/map.rs:503:(.text._ZN3std11collections4hash3map10robin_hood17h012217733b3b4b5aE+0xa4): relocation truncated to fit: R_MIPS_CALL16 against `_Unwind_Resume@@GCC_3.0'
          /home/draganm/work/rust/build/bootstrap/debug/deps/libbootstrap-ae75a7d683cd3583.rlib(bootstrap-ae75a7d683cd3583.2w6xsa2hbi53xhak.rcgu.o): In function `std::collections::hash::map::robin_hood':
          /checkout/src/libstd/collections/hash/map.rs:503:(.text._ZN3std11collections4hash3map10robin_hood17h03200646b79056ceE+0xa4): additional relocation overflows omitted from the output`

Not sure yet if there is a bug behind this. Posting this here just in case.

What happens is that we hit the limit of 8K GOT entries per single object file. I've tried using 1.25 instead of 1.26 as bootstrap compiler and the bootstrap build passes with offending object file having ~7K symbols needing GOT entry. I haven't been able to find exact reason for this. At first glance, while it sound counterintuitive, it seems that we have more inlining on 1.26 which pulls in more symbol references.

I was able to sidestep this by increasing opt-level for bootstrap build to 3. As a stopgap, is it ok to provide and option to bootstrap.py to build bootstrap tool in release mode ? I can send the PR.

@stokhos stokhos added the C-feature-request Category: A feature request, i.e: not implemented / a PR. label Jul 7, 2018
@Mark-Simulacrum
Copy link
Member

cc @michaelwoerister @rust-lang/compiler -- marking a stable/stable regression. I'm not sure what could cause this (bootstrap is fairly small).

@Mark-Simulacrum Mark-Simulacrum added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. regression-from-stable-to-stable Performance or correctness regression from one stable version to another. C-bug Category: This is a bug. and removed C-feature-request Category: A feature request, i.e: not implemented / a PR. labels Jul 7, 2018
@pnkfelix
Copy link
Member

visiting for triage.

Some notes, in part to self: mips64 is a tier 2 platform. We support building the tools (but not testing them) for such platforms ... and unfortunately we are doing such building via cross-compiles, so our continuous-integration system didn't catch whatever caused the build of bootstrap to start failing.

Marking at P-medium for now.

@draganmladjenovic I think we would be happy to look at any PR you provide that gives a way to sidestep the issue you are facing as long as it does not change the default behavior....

@pnkfelix pnkfelix added the P-medium Medium priority label Jul 12, 2018
@sanxiyn
Copy link
Member

sanxiyn commented Jul 25, 2018

GCC MIPS documentation suggests that you should use -mxgot if you see "relocation truncated to fit" errors.

@sanxiyn sanxiyn added the O-MIPS Target: MIPS processors label Jul 25, 2018
@jiangtao9999
Copy link

jiangtao9999 commented Jul 25, 2018

@sanxiyn
Add -mxgot with cc command ?It seems not usefull ...
export RUSTFLAGS=-Clink-arg=-mxgot ? It seems not pass to linker ....

sh-4.4# ls which cc -l
lrwxrwxrwx 1 root root 3 Jul 20 00:44 /usr/bin/cc -> gcc
sh-4.4# cat /usr/bin/cc
#!/bin/bash
exec /usr/bin/gcc.aaa -mxgot -Wa,-xgot $@
sh-4.4#

Output
mock's build.log
build.log

@draganmladjenovic
Copy link
Contributor Author

draganmladjenovic commented Jul 25, 2018

@jiangtao9999 I haven't tested it but I think you should use RUSTFLAGS="-C llvm-args=-mxgot".
Edit: Also note that bootstrap tool build sets its own RUSTFLAGS https://github.com/rust-lang/rust/blob/master/src/bootstrap/bootstrap.py#L622 .

@jiangtao9999
Copy link

@draganmladjenovic
Add this line in the .spec file:
sed -i 's/-Cdebuginfo=2/-Cdebuginfo=2 -C llvm-args=-mxgot/' src/bootstrap/bootstrap.py
And RPMs were built successful .
🤗🤗

@wzssyqa
Copy link
Contributor

wzssyqa commented Aug 1, 2018

With this patch, rustc can build on mips64el.

Index: rustc-1.27.1+dfsg1/src/bootstrap/bootstrap.py
===================================================================
--- rustc-1.27.1+dfsg1.orig/src/bootstrap/bootstrap.py
+++ rustc-1.27.1+dfsg1/src/bootstrap/bootstrap.py
@@ -591,6 +591,8 @@ class RustBuild(object):
             (os.pathsep + env["LIBRARY_PATH"]) \
             if "LIBRARY_PATH" in env else ""
         env["RUSTFLAGS"] = "-Cdebuginfo=2"
+        if self.build_triple().startswith('mips'):
+            env["RUSTFLAGS"] += " -Cllvm-args=-mxgot"
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
             os.pathsep + env["PATH"]
         if not os.path.isfile(self.cargo()):

@infinity0
Copy link
Contributor

Is this needed all the time? (What's special about the bootstrap process?) If it's needed all the time, perhaps rustc should always be passing that flag to LLVM? In which case the change should be made to a more internal file, bootstrap.py only applies when compiling rustc itself.

@infinity0
Copy link
Contributor

infinity0 commented Aug 2, 2018

(By "all the time" I mean "including when compiling other rust programs not the rustc compiler to mips")

@sanxiyn
Copy link
Member

sanxiyn commented Aug 2, 2018

I think what's special about rustc is that it is compiled with dynamic linking. Rust defaults to static linking, and for static linking -mxgot is irrelevant and ignored. But rustc is compiled with dynamic linking, IIRC, for compiler plugins.

I think always passing -mxgot to LLVM is okay, since it won't affect most Rust builds which use static linking.

@draganmladjenovic
Copy link
Contributor Author

@sanxiyn @infinity0 But static linking will affected too because the use of GOT is tied to use of PIC code on Mips platform https://godbolt.org/g/cwU5Xc. I'd rather not do this by default or at least limit its use to debug builds. In the end it is a crutch that it's used when number of GOT entries per object exceeds 8K/16K on mips64 and mips32 respectively. Because the problem right now is limited to building of the bootstrap tool and nothing else (Actually I'm not sure for tests because I've run them with optimize-tests=true) I thought of adding of new env variable like BOOTSTRAP_RUSTFLAGS that will allow the users to control RUSTFLAGS for bootstrap tool build.
About what is special about bootstrap process (except that is always built in debug mode) I don't know. I didn't have time to look into it thoroughly. Will post if I find something.

@sanxiyn
Copy link
Member

sanxiyn commented Aug 2, 2018

Ah yes, it's PIC, not dynamic linking. On the other hand, do we build static linking with PIC?

@draganmladjenovic
Copy link
Contributor Author

draganmladjenovic commented Aug 2, 2018

On the other hand, do we build static linking with PIC?

Don't know for sure but it looks that choice of relocation-model is orthogonal to the choice of linking. I believe the -linux- targets default to PIC which should cover all cases. There are some limitation in practice tho. For example the relocation-model=static code on mips64 cannot participate in dynamic linking.

@ambrosehua
Copy link

MIPS SVR4 ABI insist all userspace codes use PIC, even static linking, for GNU/MIPS, there is an extension for exec to use non-pic(since exec loaded at fixed position), which only works on N32/O32 ABI;

@horsley
Copy link

horsley commented Apr 16, 2019

With this patch, rustc can build on mips64el.

Index: rustc-1.27.1+dfsg1/src/bootstrap/bootstrap.py
===================================================================
--- rustc-1.27.1+dfsg1.orig/src/bootstrap/bootstrap.py
+++ rustc-1.27.1+dfsg1/src/bootstrap/bootstrap.py
@@ -591,6 +591,8 @@ class RustBuild(object):
             (os.pathsep + env["LIBRARY_PATH"]) \
             if "LIBRARY_PATH" in env else ""
         env["RUSTFLAGS"] = "-Cdebuginfo=2"
+        if self.build_triple().startswith('mips'):
+            env["RUSTFLAGS"] += " -Cllvm-args=-mxgot"
         env["PATH"] = os.path.join(self.bin_root(), "bin") + \
             os.pathsep + env["PATH"]
         if not os.path.isfile(self.cargo()):

it worked like a charm

@xen0n
Copy link
Contributor

xen0n commented Mar 2, 2020

Hi everyone involved in the discussion,

While -mxgot certainly has its performance downsides The -mxgot patch seems to affect bootstrap only, it might be in our interest to fix bootstrap upstream instead of all carrying the same patch separately. Just confirmed yesterday with (yesterday's) master that we only have two testcases failing:

  • run-make-fulldeps/relocation-model
  • ui/statics/static-function-pointer

This is on a Loongson 3A4000 box running mips64el-unknown-linux-gnuabi64 Gentoo (the Gentoo CHOST is actually different but it doesn't matter).

How about we just go ahead and apply the -mxgot workaround to bootstrap.py?

EDIT: realized the flag setting is only for building bootstrap and not the main compiler

@infinity0
Copy link
Contributor

Something about 1.46.0 (current beta) is breaking this patch: https://buildd.debian.org/status/fetch.php?pkg=rustc&arch=mips64el&ver=1.46.0%7Ebeta.2%2Bdfsg1-1%7Eexp4&stamp=1597142242&raw=0

error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `/usr/bin/rustc - --crate-name ___ --print=file-names -Cdebuginfo=2 -Cllvm-args=-mxgot -C linker=mips64el-linux-gnuabi64-gcc -Wrust_2018_idioms -Wunused_lifetimes -Dwarnings --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro --print=sysroot --print=cfg` (exit code: 1)
--- stderr
rustc: Unknown command line argument '-mxgot'.  Try: 'rustc --help'
rustc: Did you mean '--mgpopt'?

Traceback (most recent call last):
  File "src/bootstrap/bootstrap.py", line 997, in <module>
    main()
  File "src/bootstrap/bootstrap.py", line 980, in main
    bootstrap(help_triggered)
  File "src/bootstrap/bootstrap.py", line 947, in bootstrap
    build.build_bootstrap()
  File "src/bootstrap/bootstrap.py", line 732, in build_bootstrap
    run(args, env=env, verbose=self.verbose)
  File "src/bootstrap/bootstrap.py", line 144, in run
    raise RuntimeError(err)
RuntimeError: failed to run: /usr/bin/cargo build --manifest-path /<<PKGBUILDDIR>>/src/bootstrap/Cargo.toml --verbose --verbose

@infinity0
Copy link
Contributor

-Ctarget-feature=+xgot seems to work.

--- rust.orig/src/bootstrap/bootstrap.py
+++ rust/src/bootstrap/bootstrap.py
@@ -681,6 +681,8 @@ class RustBuild(object):
         # preserve existing RUSTFLAGS
         env.setdefault("RUSTFLAGS", "")
         env["RUSTFLAGS"] += " -Cdebuginfo=2"
+        if self.build_triple().startswith('mips'):
+            env["RUSTFLAGS"] += " -Ctarget-feature=+xgot"
 
         build_section = "target.{}".format(self.build_triple())
         target_features = []

@infinity0
Copy link
Contributor

@xen0n We are running into this problem now for the cargo build - attempt 1 attempt 2 attempt 3. The error messages are from the hashbrown crate, although I am having trouble reproducing it on a different mips64el machine.

I am thinking of just adding "+xgot" to compiler/rustc_target/src/spec/mips64el_unknown_linux_gnuabi64.rs and not having to worry about this problem in random rust crates in the future, because it is going to be a maintenance annoyance otherwise. What are the specific performance problems, and what would "the proper solution" be and who is supposed to work on it? Someone in LLVM?

@xen0n
Copy link
Contributor

xen0n commented Dec 9, 2020

What are the specific performance problems, and what would "the proper solution" be and who is supposed to work on it? Someone in LLVM?

GOT loads with -mxgot need more instructions. That might or might not be a problem, actually, considering the mips platforms are already slow by modern standards; and I originally meant that -mxgot should be turned on globally only as a last measure.

It might be possible to generate code like -mxgot is unconditionally on, then relax and relocate things during linking wherever it turns out to be unnecessary. But I imagine that to be enormous toolchain work and unlikely to pan out in the short- and mid-term. So I'm afraid turning on -mxgot globally is the only sensible choice.

@wzssyqa
Copy link
Contributor

wzssyqa commented Dec 9, 2020

I agree with xen0n. We meet more and more packages in Debian needing xgot.
And I think that is is a reasonable choice to enable xgot globally.

@xen0n
Copy link
Contributor

xen0n commented Dec 9, 2020

I might need some time to setup a local benchmark environment, as I haven't been doing much rustc development lately. Who's going to own the work?

@infinity0
Copy link
Contributor

Thanks for the explanation. Setting this feature unconditionally is just a 1-line patch which I am happy to apply in Debian, it is trivial work and I can own that. Or did you mean you wanted to do more things like testing?

@xen0n
Copy link
Contributor

xen0n commented Dec 9, 2020

@infinity0 I'd prefer to benchmark rustc's performance before and after the global switch, if somehow we could successfully build rustc without the patch (might have to do the benchmark with a previous version of rustc). Or popular applications (think ripgrep and such) could be benchmarked for the real-world performance impact of global -mxgot.

This benchmark work is not meant to block the one-liner PR, though. It's just a suggestion to help fellow developers on MIPS better understand the situation.

@infinity0
Copy link
Contributor

OK that makes sense. Currently in Debian we are successfully building rustc without the global switch, and to my knowledge we are only applying it for the rustc builder program ("bootstrap"/"x.py") and now cargo 0.47.

So, I could apply the global switch to the current version of rustc in Debian so you can compare the same version 1.48.0 with (1.48.0-dfsg1-2) or without the switch (1.48.0-dfsg1-1). They will remain available on snapshot.debian.org even after the next upgrade pushes them out of the main Debian archive.

If you want to benchmark other programs, I guess it might be possible to disable the feature (after the global switch) with RUSTFLAGS=-Ctarget-feature=-xgot? Although I never tried this myself.

@xen0n
Copy link
Contributor

xen0n commented Dec 10, 2020

OK that makes sense. Currently in Debian we are successfully building rustc without the global switch, and to my knowledge we are only applying it for the rustc builder program ("bootstrap"/"x.py") and now cargo 0.47.

So, I could apply the global switch to the current version of rustc in Debian so you can compare the same version 1.48.0 with (1.48.0-dfsg1-2) or without the switch (1.48.0-dfsg1-1). They will remain available on snapshot.debian.org even after the next upgrade pushes them out of the main Debian archive.

Sure, thanks for the information!

If you want to benchmark other programs, I guess it might be possible to disable the feature (after the global switch) with RUSTFLAGS=-Ctarget-feature=-xgot? Although I never tried this myself.

Yes that's the way to do it. I'm not quite sure if linking with std built with different xgot setting would work though; last time I investigated was long ago.

@infinity0
Copy link
Contributor

Did anyone ever investigate this? We are still patching in +xgot on Debian which makes a recently-enabled test (#83485) fail:

failures
------------------------------------------

error in revision `mips64`: verification with 'FileCheck' failed
status: exit status: 1
command: "/usr/lib/llvm-12/bin/FileCheck" "--input-file" "/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/assembly/asm/mips-types.mips64/mips-types.s" "/<<PKGBUILDDIR>>/src/test/assembly/asm/mips-types.rs" "--check-prefixes" "CH>
stdout:
------------------------------------------

------------------------------------------
stderr:
------------------------------------------
/<<PKGBUILDDIR>>/src/test/assembly/asm/mips-types.rs:95:12: error: mips64: expected string not found in input
// mips64: ld $3, %got_disp(extern_static)
           ^
/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/assembly/asm/mips-types.mips64/mips-types.s:24:2: note: scanning from here
 .set push
 ^
/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/assembly/asm/mips-types.mips64/mips-types.s:29:2: note: possible intended match here
 lui $3, %got_hi(extern_static)
 ^
/<<PKGBUILDDIR>>/src/test/assembly/asm/mips-types.rs:105:12: error: mips64: expected string not found in input
// mips64: ld $3, %got_disp(extern_func)
           ^
/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/assembly/asm/mips-types.mips64/mips-types.s:63:2: note: scanning from here
 .set push
 ^
/<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/assembly/asm/mips-types.mips64/mips-types.s:68:2: note: possible intended match here
 lui $3, %got_hi(extern_func)
 ^

Input file: /<<PKGBUILDDIR>>/build/x86_64-unknown-linux-gnu/test/assembly/asm/mips-types.mips64/mips-types.s
Check file: /<<PKGBUILDDIR>>/src/test/assembly/asm/mips-types.rs

-dump-input=help explains the following input dump.

Input was:
<<<<<<
             .
             .
             .
            19:  .set noreorder
            20:  .set nomacro
            21:  .set noat
            22:  .cfi_def_cfa_offset 0
            23:  #APP
            24:  .set push
check:95'0       X~~~~~~~~ error: no match found
            25:  .set at
check:95'0      ~~~~~~~~
            26:  .set macro
check:95'0      ~~~~~~~~~~~
            27:  .set reorder
check:95'0      ~~~~~~~~~~~~~
            28: 
check:95'0      ~
            29:  lui $3, %got_hi(extern_static)
check:95'0      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
check:95'1       ?                              possible intended match
            30:  daddu $3, $3, $gp
check:95'0      ~~~~~~~~~~~~~~~~~~
            31:  ld $3, %got_lo(extern_static)($3)
check:95'0      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            32:  ld $3, 0($3)
check:95'0      ~~~~~~~~~~~~~
            33: 
check:95'0      ~
            34:  .set pop
check:95'0      ~~~~~~~~~
             .
             .
             .
            58:  .set noreorder
            59:  .set nomacro
            60:  .set noat
            61:  .cfi_def_cfa_offset 0
            62:  #APP
            63:  .set push
check:105'0      X~~~~~~~~ error: no match found
            64:  .set at
check:105'0     ~~~~~~~~
            65:  .set macro
check:105'0     ~~~~~~~~~~~
            66:  .set reorder
check:105'0     ~~~~~~~~~~~~~
            67: 
check:105'0     ~
            68:  lui $3, %got_hi(extern_func)
check:105'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
check:105'1      ?                            possible intended match
            69:  daddu $3, $3, $gp
check:105'0     ~~~~~~~~~~~~~~~~~~
            70:  ld $3, %got_lo(extern_func)($3)
check:105'0     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            71:  ld $3, 0($3)
check:105'0     ~~~~~~~~~~~~~
            72: ·
check:105'0     ~
            73:  .set pop
check:105'0     ~~~~~~~~~
             .
             .
             .
>>>>>>

According to @jrtc27 this difference is exactly what is expected when +xgot is enabled, so for now I will disable this test in Debian.

@workingjubilee
Copy link
Member

Uhh... Does someone want to send in a PR? A few different solutions have been proposed by now and it's not actually clear which one is the necessary/desired one.

Noratrieb added a commit to Noratrieb/rust that referenced this issue May 30, 2023
…jackh726

Fix linkage for large binaries on mips64 platforms

This pull request fixes the linkage for large binaries on mips64 platforms by enabling the `xgot` feature in LLVM.

It is well understood that the generated binary will gain a hefty performance penalty where the external symbol jumps now cost at least three instructions each.

Also, this pull request does not address the same issue on the mips32 counterparts (due to being unable to test the changes thoroughly).

Should fix rust-lang#52108
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue May 31, 2023
…jackh726

Fix linkage for large binaries on mips64 platforms

This pull request fixes the linkage for large binaries on mips64 platforms by enabling the `xgot` feature in LLVM.

It is well understood that the generated binary will gain a hefty performance penalty where the external symbol jumps now cost at least three instructions each.

Also, this pull request does not address the same issue on the mips32 counterparts (due to being unable to test the changes thoroughly).

Should fix rust-lang#52108
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue May 31, 2023
…jackh726

Fix linkage for large binaries on mips64 platforms

This pull request fixes the linkage for large binaries on mips64 platforms by enabling the `xgot` feature in LLVM.

It is well understood that the generated binary will gain a hefty performance penalty where the external symbol jumps now cost at least three instructions each.

Also, this pull request does not address the same issue on the mips32 counterparts (due to being unable to test the changes thoroughly).

Should fix rust-lang#52108
@bors bors closed this as completed in fd1c0d8 May 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: This is a bug. O-MIPS Target: MIPS processors P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.