authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-13 01:15:25-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-04-13 01:15:25-04:00
logbf67427c67dac00ca10ed7423ae8d99e2901262f
treea728030e7ea78935a7ccc5591d2b54428a5c734d
parent41144a8566a6fbd779403f6b69424bb640c94a7f

fix crash when using zig to link

without explicit dynamic linker

5 files changed, 81 insertions(+), 84 deletions(-)

src/link.cpp+1-1
......@@ -256,7 +256,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
256256 lj->args.append(buf_ptr(g->dynamic_linker));
257257 } else {
258258 lj->args.append("-dynamic-linker");
259 lj->args.append(buf_ptr(get_dynamic_linker(g->target_machine)));
259 lj->args.append(buf_ptr(target_dynamic_linker(&g->zig_target)));
260260 }
261261
262262 if (shared) {
src/target.cpp+77
......@@ -536,3 +536,80 @@ const char *target_o_file_ext(ZigTarget *target) {
536536 }
537537}
538538
539enum FloatAbi {
540 FloatAbiHard,
541 FloatAbiSoft,
542 FloatAbiSoftFp,
543};
544
545static FloatAbi get_float_abi(ZigTarget *target) {
546 const ZigLLVM_EnvironmentType env = target->env_type;
547 if (env == ZigLLVM_GNUEABIHF ||
548 env == ZigLLVM_EABIHF ||
549 env == ZigLLVM_MuslEABIHF)
550 {
551 return FloatAbiHard;
552 } else {
553 zig_panic("TODO: user needs to input if they want hard or soft floating point");
554 }
555}
556
557static bool is_64_bit(ZigLLVM_ArchType arch) {
558 return get_arch_pointer_bit_width(arch) == 64;
559}
560
561Buf *target_dynamic_linker(ZigTarget *target) {
562 const ZigLLVM_ArchType arch = target->arch.arch;
563 const ZigLLVM_EnvironmentType env = target->env_type;
564
565 if (env == ZigLLVM_Android) {
566 if (is_64_bit(arch)) {
567 return buf_create_from_str("/system/bin/linker64");
568 } else {
569 return buf_create_from_str("/system/bin/linker");
570 }
571 } else if (arch == ZigLLVM_x86 ||
572 arch == ZigLLVM_sparc ||
573 arch == ZigLLVM_sparcel)
574 {
575 return buf_create_from_str("/lib/ld-linux.so.2");
576 } else if (arch == ZigLLVM_aarch64) {
577 return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
578 } else if (arch == ZigLLVM_aarch64_be) {
579 return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
580 } else if (arch == ZigLLVM_arm || arch == ZigLLVM_thumb) {
581 if (get_float_abi(target) == FloatAbiHard) {
582 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
583 } else {
584 return buf_create_from_str("/lib/ld-linux.so.3");
585 }
586 } else if (arch == ZigLLVM_armeb || arch == ZigLLVM_thumbeb) {
587 if (get_float_abi(target) == FloatAbiHard) {
588 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
589 } else {
590 return buf_create_from_str("/lib/ld-linux.so.3");
591 }
592 } else if (arch == ZigLLVM_mips || arch == ZigLLVM_mipsel ||
593 arch == ZigLLVM_mips64 || arch == ZigLLVM_mips64el)
594 {
595 // when you want to solve this TODO, grep clang codebase for
596 // getLinuxDynamicLinker
597 zig_panic("TODO figure out MIPS dynamic linker name");
598 } else if (arch == ZigLLVM_ppc) {
599 return buf_create_from_str("/lib/ld.so.1");
600 } else if (arch == ZigLLVM_ppc64) {
601 return buf_create_from_str("/lib64/ld64.so.2");
602 } else if (arch == ZigLLVM_ppc64le) {
603 return buf_create_from_str("/lib64/ld64.so.2");
604 } else if (arch == ZigLLVM_systemz) {
605 return buf_create_from_str("/lib64/ld64.so.1");
606 } else if (arch == ZigLLVM_sparcv9) {
607 return buf_create_from_str("/lib64/ld-linux.so.2");
608 } else if (arch == ZigLLVM_x86_64 &&
609 env == ZigLLVM_GNUX32)
610 {
611 return buf_create_from_str("/libx32/ld-linux-x32.so.2");
612 } else {
613 return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
614 }
615}
src/target.hpp+3
......@@ -74,4 +74,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);
7474
7575const char *target_o_file_ext(ZigTarget *target);
7676
77Buf *target_dynamic_linker(ZigTarget *target);
78
79
7780#endif
src/zig_llvm.cpp-81
......@@ -768,89 +768,8 @@ LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMVa
768768 return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, false, true));
769769}
770770
771//------------------------------------
772
773771#include "buffer.hpp"
774772
775enum FloatAbi {
776 FloatAbiHard,
777 FloatAbiSoft,
778 FloatAbiSoftFp,
779};
780
781static FloatAbi get_float_abi(const Triple &triple) {
782 if (triple.getEnvironment() == Triple::GNUEABIHF ||
783 triple.getEnvironment() == Triple::EABIHF ||
784 triple.getEnvironment() == Triple::MuslEABIHF)
785 {
786 return FloatAbiHard;
787 } else {
788 zig_panic("TODO: user needs to input if they want hard or soft floating point");
789 }
790}
791
792Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine_ref) {
793 TargetMachine *target_machine = reinterpret_cast<TargetMachine*>(target_machine_ref);
794 const Triple &triple = target_machine->getTargetTriple();
795
796 const Triple::ArchType arch = triple.getArch();
797
798 if (triple.getEnvironment() == Triple::Android) {
799 if (triple.isArch64Bit()) {
800 return buf_create_from_str("/system/bin/linker64");
801 } else {
802 return buf_create_from_str("/system/bin/linker");
803 }
804 } else if (arch == Triple::x86 ||
805 arch == Triple::sparc ||
806 arch == Triple::sparcel)
807 {
808 return buf_create_from_str("/lib/ld-linux.so.2");
809 } else if (arch == Triple::aarch64) {
810 return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
811 } else if (arch == Triple::aarch64_be) {
812 return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
813 } else if (arch == Triple::arm || arch == Triple::thumb) {
814 if (triple.getEnvironment() == Triple::GNUEABIHF ||
815 get_float_abi(triple) == FloatAbiHard)
816 {
817 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
818 } else {
819 return buf_create_from_str("/lib/ld-linux.so.3");
820 }
821 } else if (arch == Triple::armeb || arch == Triple::thumbeb) {
822 if (triple.getEnvironment() == Triple::GNUEABIHF ||
823 get_float_abi(triple) == FloatAbiHard)
824 {
825 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
826 } else {
827 return buf_create_from_str("/lib/ld-linux.so.3");
828 }
829 } else if (arch == Triple::mips || arch == Triple::mipsel ||
830 arch == Triple::mips64 || arch == Triple::mips64el)
831 {
832 // when you want to solve this TODO, grep clang codebase for
833 // getLinuxDynamicLinker
834 zig_panic("TODO figure out MIPS dynamic linker name");
835 } else if (arch == Triple::ppc) {
836 return buf_create_from_str("/lib/ld.so.1");
837 } else if (arch == Triple::ppc64) {
838 return buf_create_from_str("/lib64/ld64.so.2");
839 } else if (arch == Triple::ppc64le) {
840 return buf_create_from_str("/lib64/ld64.so.2");
841 } else if (arch == Triple::systemz) {
842 return buf_create_from_str("/lib64/ld64.so.1");
843 } else if (arch == Triple::sparcv9) {
844 return buf_create_from_str("/lib64/ld-linux.so.2");
845 } else if (arch == Triple::x86_64 &&
846 triple.getEnvironment() == Triple::GNUX32)
847 {
848 return buf_create_from_str("/libx32/ld-linux-x32.so.2");
849 } else {
850 return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
851 }
852}
853
854773bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, Buf *diag_buf) {
855774 ArrayRef<const char *> array_ref_args(args, arg_count);
856775
src/zig_llvm.hpp-2
......@@ -363,6 +363,4 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
363363 ZigLLVM_ObjectFormatType *oformat);
364364
365365
366Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine);
367
368366#endif