Skip to content

Instantly share code, notes, and snippets.

@japaric
Created August 6, 2016 22:34
Show Gist options
  • Save japaric/9b5d41921b775e270bc02aa04aeb858d to your computer and use it in GitHub Desktop.
Save japaric/9b5d41921b775e270bc02aa04aeb858d to your computer and use it in GitHub Desktop.
How-to: figure out which compiler-rt intrinsics are *needed* to link `rustc`

Last updated: 2016-08-06

Summary: We'll modify the rustc-builtins crate to make all the intrinsics "undefined", then we'll proceed to bootstrap rustc normally. This will cause a linker error while linking rustc because the intrinsics are "undefined". The linker error message will list the intrinsics that are required to link rustc but the linker couldn't "find".

  1. First, we avoid building .so versions of std, rustc et al. because those will also fail to link but the linker error message will list all the intrinsics instead of only the ones that are actually needed to build a Rust program (binary). We do this by removing "dylib" from the crate-type list (if it's there) for every Cargo.toml.
 [package]
 (..)
-crate-type = ["dylib", "rlib"]
+crate-type = ["rlib"]
 (..)
  1. Stop building the C version of compiler-rt intrinsics. Simply remove the build field from rustc-builtins's Cargo.toml:
 [package]
 (..)
-build = "build.rs"
 (..)
  1. "Undefine" each and every compiler-rt intrinsic. Modify rustc-builtins's lib.rs like this:
+#[no_mangle]
+pub extern fn __addsf3() {
+    extern {
+        fn __addsf3_is_undefined();
+    }
+
+    unsafe {
+        __addsf3_is_undefined();
+    }
+}

For each intrinsic. In the previous example addsf3 is the name of the intrinsic. How many of these intrinsics needs to be "undefined"? Each and every intrinsics defined in libcompiler-rt.a. Use nm to get list of intrinsics from stage0's libcompiler-rt.a:

$ nm libcompiler-rt.a | grep 'T __' | cut -d' ' -f3 | sort -u'
__absvdi2
__absvsi2
__absvti2
(..)
  1. Bootstrap rustc using rustbuild, and observe the linker error

NOTE The example output below is for a compiler with host: arm-unknown-linux-gnueabi.

$ configure --enable-rustbuild && make
(..)
error: linking with `arm-linux-gnueabi-gcc` failed: exit code: 1
note: "arm-linux-gnueabi-gcc" (..)
note: /home/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/arm-unknown-linux-gnueabi/lib/librustc_builtins-e6891dc09c662475.rlib(rustc_builtins-e6891dc09c662475.0.o): In function `__absvdi2':
rustc_builtins.cgu-0.rs:(.text.__absvdi2+0x0): undefined reference to `__absvdi2_is_undefined'
/home/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/arm-unknown-linux-gnueabi/lib/librustc_builtins-e6891dc09c662475.rlib(rustc_builtins-e6891dc09c662475.0.o): In function `__absvsi2':
rustc_builtins.cgu-0.rs:(.text.__absvsi2+0x0): undefined reference to `__absvsi2_is_undefined'
/home/rust/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/arm-unknown-linux-gnueabi/lib/librustc_builtins-e6891dc09c662475.rlib(rustc_builtins-e6891dc09c662475.0.o): In function `__adddf3':
rustc_builtins.cgu-0.rs:(.text.__adddf3+0x0): undefined reference to `__adddf3_is_undefined'
(..)

The "undefined reference to __absvdi2_is_undefined" lines indicate which intrinsics are required to link rustc. In this last example, the required intrinsics are: absvdi2, absvsi2, adddf3, etc.

__absvdi2
__absvsi2
__adddf3
__addsf3
__addvdi3
__addvsi3
__aeabi_cdcmpeq
__aeabi_cdcmple
__aeabi_cdrcmple
__aeabi_cfcmpeq
__aeabi_cfcmple
__aeabi_cfrcmple
__aeabi_d2f
__aeabi_d2iz
__aeabi_d2lz
__aeabi_d2uiz
__aeabi_d2ulz
__aeabi_dadd
__aeabi_dcmpeq
__aeabi_dcmpge
__aeabi_dcmpgt
__aeabi_dcmple
__aeabi_dcmplt
__aeabi_dcmpun
__aeabi_ddiv
__aeabi_dmul
__aeabi_dneg
__aeabi_drsub
__aeabi_dsub
__aeabi_f2d
__aeabi_f2iz
__aeabi_f2lz
__aeabi_f2uiz
__aeabi_f2ulz
__aeabi_fadd
__aeabi_fcmpeq
__aeabi_fcmpge
__aeabi_fcmpgt
__aeabi_fcmple
__aeabi_fcmplt
__aeabi_fcmpun
__aeabi_fdiv
__aeabi_fmul
__aeabi_fneg
__aeabi_frsub
__aeabi_fsub
__aeabi_i2d
__aeabi_i2f
__aeabi_idiv
__aeabi_idivmod
__aeabi_l2d
__aeabi_l2f
__aeabi_lasr
__aeabi_lcmp
__aeabi_ldivmod
__aeabi_llsl
__aeabi_llsr
__aeabi_lmul
__aeabi_memclr
__aeabi_memclr4
__aeabi_memclr8
__aeabi_memcpy
__aeabi_memcpy4
__aeabi_memcpy8
__aeabi_memmove
__aeabi_memmove4
__aeabi_memmove8
__aeabi_memset
__aeabi_memset4
__aeabi_memset8
__aeabi_ui2d
__aeabi_ui2f
__aeabi_uidiv
__aeabi_uidivmod
__aeabi_ul2d
__aeabi_ul2f
__aeabi_ulcmp
__aeabi_uldivmod
__ashldi3
__ashrdi3
__bswapdi2
__bswapsi2
__clear_cache
__clzdi2
__clzsi2
__cmpdi2
__ctzdi2
__ctzsi2
__divdc3
__divdf3
__divdi3
__divsc3
__divsf3
__divsi3
__emutls_get_address
__eqdf2
__eqsf2
__extendsfdf2
__ffsdi2
__fixdfdi
__fixdfsi
__fixsfdi
__fixsfsi
__fixunsdfdi
__fixunsdfsi
__fixunssfdi
__fixunssfsi
__floatdidf
__floatdisf
__floatsidf
__floatsisf
__floatundidf
__floatundisf
__floatunsidf
__floatunsisf
__gcc_personality_v0
__gedf2
__gesf2
__gtdf2
__gtsf2
__ledf2
__lesf2
__lshrdi3
__ltdf2
__ltsf2
__moddi3
__modsi3
__muldc3
__muldf3
__muldi3
__mulodi4
__mulsc3
__mulsf3
__mulvdi3
__mulvsi3
__nedf2
__negdf2
__negdi2
__negsf2
__negvdi2
__negvsi2
__nesf2
__paritydi2
__paritysi2
__popcountdi2
__popcountsi2
__powidf2
__powisf2
__subdf3
__subsf3
__subvdi3
__subvsi3
__truncdfsf2
__ucmpdi2
__udivdi3
__udivmoddi4
__udivsi3
__umoddi3
__umodsi3
__unorddf2
__unordsf2
__absvdi2
__absvsi2
__absvti2
__addvdi3
__addvsi3
__addvti3
__ashlti3
__ashrti3
__clear_cache
__clzdi2
__clzti2
__cmpti2
__ctzdi2
__ctzti2
__divdc3
__divsc3
__divti3
__divxc3
__emutls_get_address
__ffsdi2
__ffsti2
__fixdfti
__fixsfti
__fixunsdfdi
__fixunsdfti
__fixunssfdi
__fixunssfti
__fixunsxfdi
__fixunsxfti
__fixxfti
__floattidf
__floattisf
__floattixf
__floatuntidf
__floatuntisf
__floatuntixf
__gcc_personality_v0
__lshrti3
__modti3
__muldc3
__mulsc3
__multi3
__mulvdi3
__mulvsi3
__mulvti3
__mulxc3
__negti2
__negvdi2
__negvsi2
__negvti2
__paritydi2
__parityti2
__popcountdi2
__popcountti2
__powidf2
__powisf2
__powixf2
__subvdi3
__subvsi3
__subvti3
__ucmpti2
__udivmodti4
__udivti3
__umodti3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment