Commit bf67427c67

Andrew Kelley <superjoe30@gmail.com>
2017-04-13 07:15:25
fix crash when using zig to link
without explicit dynamic linker
1 parent 41144a8
src/link.cpp
@@ -256,7 +256,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
         lj->args.append(buf_ptr(g->dynamic_linker));
     } else {
         lj->args.append("-dynamic-linker");
-        lj->args.append(buf_ptr(get_dynamic_linker(g->target_machine)));
+        lj->args.append(buf_ptr(target_dynamic_linker(&g->zig_target)));
     }
 
     if (shared) {
src/target.cpp
@@ -536,3 +536,80 @@ const char *target_o_file_ext(ZigTarget *target) {
     }
 }
 
+enum FloatAbi {
+    FloatAbiHard,
+    FloatAbiSoft,
+    FloatAbiSoftFp,
+};
+
+static FloatAbi get_float_abi(ZigTarget *target) {
+    const ZigLLVM_EnvironmentType env = target->env_type;
+    if (env == ZigLLVM_GNUEABIHF ||
+        env == ZigLLVM_EABIHF ||
+        env == ZigLLVM_MuslEABIHF)
+    {
+        return FloatAbiHard;
+    } else {
+        zig_panic("TODO: user needs to input if they want hard or soft floating point");
+    }
+}
+
+static bool is_64_bit(ZigLLVM_ArchType arch) {
+    return get_arch_pointer_bit_width(arch) == 64;
+}
+
+Buf *target_dynamic_linker(ZigTarget *target) {
+    const ZigLLVM_ArchType arch = target->arch.arch;
+    const ZigLLVM_EnvironmentType env = target->env_type;
+
+    if (env == ZigLLVM_Android) {
+        if (is_64_bit(arch)) {
+            return buf_create_from_str("/system/bin/linker64");
+        } else {
+            return buf_create_from_str("/system/bin/linker");
+        }
+    } else if (arch == ZigLLVM_x86 ||
+            arch == ZigLLVM_sparc ||
+            arch == ZigLLVM_sparcel)
+    {
+        return buf_create_from_str("/lib/ld-linux.so.2");
+    } else if (arch == ZigLLVM_aarch64) {
+        return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
+    } else if (arch == ZigLLVM_aarch64_be) {
+        return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
+    } else if (arch == ZigLLVM_arm || arch == ZigLLVM_thumb) {
+        if (get_float_abi(target) == FloatAbiHard) {
+            return buf_create_from_str("/lib/ld-linux-armhf.so.3");
+        } else {
+            return buf_create_from_str("/lib/ld-linux.so.3");
+        }
+    } else if (arch == ZigLLVM_armeb || arch == ZigLLVM_thumbeb) {
+        if (get_float_abi(target) == FloatAbiHard) {
+            return buf_create_from_str("/lib/ld-linux-armhf.so.3");
+        } else {
+            return buf_create_from_str("/lib/ld-linux.so.3");
+        }
+    } else if (arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
+            arch == ZigLLVM_mips64 || arch == ZigLLVM_mips64el)
+    {
+        // when you want to solve this TODO, grep clang codebase for
+        // getLinuxDynamicLinker
+        zig_panic("TODO figure out MIPS dynamic linker name");
+    } else if (arch == ZigLLVM_ppc) {
+        return buf_create_from_str("/lib/ld.so.1");
+    } else if (arch == ZigLLVM_ppc64) {
+        return buf_create_from_str("/lib64/ld64.so.2");
+    } else if (arch == ZigLLVM_ppc64le) {
+        return buf_create_from_str("/lib64/ld64.so.2");
+    } else if (arch == ZigLLVM_systemz) {
+        return buf_create_from_str("/lib64/ld64.so.1");
+    } else if (arch == ZigLLVM_sparcv9) {
+        return buf_create_from_str("/lib64/ld-linux.so.2");
+    } else if (arch == ZigLLVM_x86_64 &&
+            env == ZigLLVM_GNUX32)
+    {
+        return buf_create_from_str("/libx32/ld-linux-x32.so.2");
+    } else {
+        return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
+    }
+}
src/target.hpp
@@ -74,4 +74,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);
 
 const char *target_o_file_ext(ZigTarget *target);
 
+Buf *target_dynamic_linker(ZigTarget *target);
+
+
 #endif
src/zig_llvm.cpp
@@ -768,89 +768,8 @@ LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMVa
     return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, false, true));
 }
 
-//------------------------------------
-
 #include "buffer.hpp"
 
-enum FloatAbi {
-    FloatAbiHard,
-    FloatAbiSoft,
-    FloatAbiSoftFp,
-};
-
-static FloatAbi get_float_abi(const Triple &triple) {
-    if (triple.getEnvironment() == Triple::GNUEABIHF ||
-        triple.getEnvironment() == Triple::EABIHF ||
-        triple.getEnvironment() == Triple::MuslEABIHF)
-    {
-        return FloatAbiHard;
-    } else {
-        zig_panic("TODO: user needs to input if they want hard or soft floating point");
-    }
-}
-
-Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine_ref) {
-    TargetMachine *target_machine = reinterpret_cast<TargetMachine*>(target_machine_ref);
-    const Triple &triple = target_machine->getTargetTriple();
-
-    const Triple::ArchType arch = triple.getArch();
-
-    if (triple.getEnvironment() == Triple::Android) {
-        if (triple.isArch64Bit()) {
-            return buf_create_from_str("/system/bin/linker64");
-        } else {
-            return buf_create_from_str("/system/bin/linker");
-        }
-    } else if (arch == Triple::x86 ||
-            arch == Triple::sparc ||
-            arch == Triple::sparcel)
-    {
-        return buf_create_from_str("/lib/ld-linux.so.2");
-    } else if (arch == Triple::aarch64) {
-        return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
-    } else if (arch == Triple::aarch64_be) {
-        return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
-    } else if (arch == Triple::arm || arch == Triple::thumb) {
-        if (triple.getEnvironment() == Triple::GNUEABIHF ||
-            get_float_abi(triple) == FloatAbiHard)
-        {
-            return buf_create_from_str("/lib/ld-linux-armhf.so.3");
-        } else {
-            return buf_create_from_str("/lib/ld-linux.so.3");
-        }
-    } else if (arch == Triple::armeb || arch == Triple::thumbeb) {
-        if (triple.getEnvironment() == Triple::GNUEABIHF ||
-            get_float_abi(triple) == FloatAbiHard)
-        {
-            return buf_create_from_str("/lib/ld-linux-armhf.so.3");
-        } else {
-            return buf_create_from_str("/lib/ld-linux.so.3");
-        }
-    } else if (arch == Triple::mips || arch == Triple::mipsel ||
-            arch == Triple::mips64 || arch == Triple::mips64el)
-    {
-        // when you want to solve this TODO, grep clang codebase for
-        // getLinuxDynamicLinker
-        zig_panic("TODO figure out MIPS dynamic linker name");
-    } else if (arch == Triple::ppc) {
-        return buf_create_from_str("/lib/ld.so.1");
-    } else if (arch == Triple::ppc64) {
-        return buf_create_from_str("/lib64/ld64.so.2");
-    } else if (arch == Triple::ppc64le) {
-        return buf_create_from_str("/lib64/ld64.so.2");
-    } else if (arch == Triple::systemz) {
-        return buf_create_from_str("/lib64/ld64.so.1");
-    } else if (arch == Triple::sparcv9) {
-        return buf_create_from_str("/lib64/ld-linux.so.2");
-    } else if (arch == Triple::x86_64 &&
-            triple.getEnvironment() == Triple::GNUX32)
-    {
-        return buf_create_from_str("/libx32/ld-linux-x32.so.2");
-    } else {
-        return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
-    }
-}
-
 bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag_buf) {
     ArrayRef<const char *> array_ref_args(args, arg_count);
 
src/zig_llvm.hpp
@@ -363,6 +363,4 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
         ZigLLVM_ObjectFormatType *oformat);
 
 
-Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine);
-
 #endif