kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

run.sh (4773B)


      1 #!/bin/sh
      2 # test/extlink/run.sh — external-linker linkability harness (Type-K mode-P).
      3 #
      4 # Proves that objects emitted by `kit cc` are consumable by the *system*
      5 # linkers, not just kit's own `ld`: LLVM lld in its three personalities
      6 # (ld.lld / lld-link / ld64.lld) plus Apple's ld on macOS. One lane per
      7 # (object-format, linker); a lane is SKIPPED (never failed) when its linker
      8 # or a required SDK is missing, so the suite is portable across CI hosts.
      9 #
     10 # Regression guard for two fixes:
     11 #   - COFF: .bss size must live in SizeOfRawData (not VirtualSize), else lld
     12 #     discards the section -> "relocation against symbol in discarded section".
     13 #   - Mach-O: kit no longer emits a raw __eh_frame whose FDE pc-begin reloc
     14 #     ld64 / ld64.lld reject ("UNSIGNED relocation must not be PC-relative").
     15 #
     16 # The corpus is two TUs that reference each other across a call and a shared
     17 # global (so the link exercises both a branch reloc and a data reloc).
     18 
     19 set -u
     20 
     21 script_dir=$(cd "$(dirname "$0")" && pwd)
     22 repo_root=$(cd "$script_dir/../.." && pwd)
     23 KIT_KIT_DIR="$repo_root/test/lib"
     24 . "$repo_root/test/lib/kit_sh_kit.sh"
     25 
     26 KIT="${KIT:-$repo_root/build/kit}"
     27 export KIT
     28 kit_require_kit extlink
     29 kit_workdir extlink
     30 work="$KIT_WORK"
     31 kit_report_init
     32 
     33 cat > "$work/a.c" <<'EOF'
     34 extern int kx_b(int);
     35 int kx_g = 7;
     36 int kx_a(void) { return kx_b(kx_g) + kx_g; }
     37 EOF
     38 cat > "$work/b.c" <<'EOF'
     39 extern int kx_g;
     40 int kx_b(int x) { return x + kx_g; }
     41 EOF
     42 
     43 # compile TARGET EXT : build a.<EXT> and b.<EXT> for TARGET (empty = native).
     44 # Returns nonzero (with the diagnostic in cc.err) if kit cc fails.
     45 compile() {
     46   _t=$1
     47   _ext=$2
     48   "$KIT" cc ${_t:+-target "$_t"} -O0 -c "$work/a.c" -o "$work/a.$_ext" \
     49     2>"$work/cc.err" &&
     50     "$KIT" cc ${_t:+-target "$_t"} -O0 -c "$work/b.c" -o "$work/b.$_ext" \
     51       2>>"$work/cc.err"
     52 }
     53 
     54 # ---- ELF: ld.lld --------------------------------------------------------
     55 if command -v ld.lld >/dev/null 2>&1; then
     56   for t in aarch64-linux x86_64-linux riscv64-linux; do
     57     if compile "$t" o; then
     58       run_ok "elf-ld.lld-$t" ld.lld -static -no-pie -e kx_a \
     59         -o "$work/$t.elf" "$work/a.o" "$work/b.o"
     60       is_executable "elf-ld.lld-$t-exe" "$work/$t.elf"
     61     else
     62       not_ok "elf-ld.lld-$t" "$work/cc.err"
     63     fi
     64   done
     65 else
     66   skip_test "elf-ld.lld" "ld.lld not on PATH"
     67 fi
     68 
     69 # ---- COFF: lld-link -----------------------------------------------------
     70 if command -v lld-link >/dev/null 2>&1; then
     71   for t in x86_64-windows aarch64-windows; do
     72     if compile "$t" obj; then
     73       run_ok "coff-lld-link-$t" lld-link /dll /noentry \
     74         /export:kx_a /export:kx_b \
     75         "/out:$work/$t.dll" "$work/a.obj" "$work/b.obj"
     76     else
     77       not_ok "coff-lld-link-$t" "$work/cc.err"
     78     fi
     79   done
     80 else
     81   skip_test "coff-lld-link" "lld-link not on PATH"
     82 fi
     83 
     84 # ---- Mach-O: Apple ld + ld64.lld (macOS, Apple Silicon) -----------------
     85 # Needs an SDK (libSystem + crt), so gate on xcrun. x86_64-macOS has a
     86 # separate, still-open __text addend-reloc bug, so restrict the native lane
     87 # to arm64 hosts (see doc note); link+run a real main() through the clang
     88 # driver, exercising the default Apple ld and lld end to end.
     89 machos_skip=""
     90 if ! command -v xcrun >/dev/null 2>&1; then
     91   machos_skip="no macOS SDK (xcrun)"
     92 elif [ "$(uname -m 2>/dev/null)" != "arm64" ]; then
     93   machos_skip="x86_64-macOS __text reloc fix pending"
     94 elif ! command -v clang >/dev/null 2>&1; then
     95   machos_skip="clang not on PATH"
     96 fi
     97 if [ -n "$machos_skip" ]; then
     98   skip_test "macho" "$machos_skip"
     99 else
    100   SDK=$(xcrun --show-sdk-path 2>/dev/null || echo)
    101   cat > "$work/m.c" <<'EOF'
    102 extern int kx_helper(int);
    103 int main(void) { return kx_helper(21); }   /* expect exit 42 */
    104 EOF
    105   cat > "$work/mh.c" <<'EOF'
    106 int kx_g2 = 0;
    107 int kx_helper(int x) { kx_g2 = x; return kx_g2 * 2; }
    108 EOF
    109   if "$KIT" cc -O0 -c "$work/m.c" -o "$work/m.o" 2>"$work/cc.err" &&
    110     "$KIT" cc -O0 -c "$work/mh.c" -o "$work/mh.o" 2>>"$work/cc.err"; then
    111     # Apple ld (clang's default linker).
    112     if clang -isysroot "$SDK" -o "$work/m_apple" "$work/m.o" "$work/mh.o" \
    113       2>"$work/apple.err"; then
    114       "$work/m_apple" 2>/dev/null
    115       if [ $? -eq 42 ]; then ok "macho-apple-ld"
    116       else echo "wrong exit code" >"$work/apple.err"; not_ok "macho-apple-ld" "$work/apple.err"; fi
    117     else
    118       not_ok "macho-apple-ld" "$work/apple.err"
    119     fi
    120     # ld64.lld.
    121     if clang -fuse-ld=lld -isysroot "$SDK" -o "$work/m_lld" \
    122       "$work/m.o" "$work/mh.o" 2>"$work/lld.err"; then
    123       "$work/m_lld" 2>/dev/null
    124       if [ $? -eq 42 ]; then ok "macho-ld64.lld"
    125       else echo "wrong exit code" >"$work/lld.err"; not_ok "macho-ld64.lld" "$work/lld.err"; fi
    126     else
    127       not_ok "macho-ld64.lld" "$work/lld.err"
    128     fi
    129   else
    130     not_ok "macho-compile" "$work/cc.err"
    131   fi
    132 fi
    133 
    134 kit_summary extlink
    135 kit_exit