From bf67427c67dac00ca10ed7423ae8d99e2901262f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 13 Apr 2017 01:15:25 -0400 Subject: [PATCH] fix crash when using zig to link without explicit dynamic linker --- src/link.cpp | 2 +- src/target.cpp | 77 +++++++++++++++++++++++++++++++++++++++++++++ src/target.hpp | 3 ++ src/zig_llvm.cpp | 81 ------------------------------------------------ src/zig_llvm.hpp | 2 -- 5 files changed, 81 insertions(+), 84 deletions(-) diff --git a/src/link.cpp b/src/link.cpp index b9328eff28..edf5243b40 100644 --- a/src/link.cpp +++ b/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) { diff --git a/src/target.cpp b/src/target.cpp index e813fbfedd..3ad232c44d 100644 --- a/src/target.cpp +++ b/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"); + } +} diff --git a/src/target.hpp b/src/target.hpp index 2e8ef6068e..07b1165944 100644 --- a/src/target.hpp +++ b/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 diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index e2641cd63e..5256af1b09 100644 --- a/src/zig_llvm.cpp +++ b/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(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 array_ref_args(args, arg_count); diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp index bec8f3e115..5d19e2ad59 100644 --- a/src/zig_llvm.hpp +++ b/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