authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-26 23:38:26-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2015-11-26 23:43:29-07:00
log4060ae93fb14b333166ff9d8ba880ff128989d31
tree747e54aadebde32d3824dd9604ff1d036612429c
parentbd5cb3e50e9f9a887cd23a24f8c766914a5c4496

call ld with correct -dynamic-linker argument

It looks like Debian/Ubuntu are doing it correctly. See https://sourceware.org/glibc/wiki/ABIList NixOS has a clang patch which disables adding the -dynamic-linker argument to ld in order to ensure "purity" - that is - that all paths are in /nix/store/*. See https://github.com/NixOS/nixpkgs/blob/6b1651928e943bdb0d69a20764fdaae294e92dc1/pkgs/development/compilers/llvm/3.7/clang/purity.patch So, I changed the environment variable to ZIG_NATIVE_DYNAMIC_LINKER and allow it to be set to blank. And it only matters when building for the native target, since you might want to build for other targets without modifying your environment. closes #1

2 files changed, 135 insertions(+), 6 deletions(-)

src/codegen.cpp+132-3
...@@ -17,6 +17,8 @@...@@ -17,6 +17,8 @@
17#include <llvm/IR/DIBuilder.h>17#include <llvm/IR/DIBuilder.h>
18#include <llvm/IR/DiagnosticInfo.h>18#include <llvm/IR/DiagnosticInfo.h>
19#include <llvm/IR/DiagnosticPrinter.h>19#include <llvm/IR/DiagnosticPrinter.h>
20#include <llvm/Target/TargetMachine.h>
21#include <llvm/Support/TargetParser.h>
2022
21struct FnTableEntry {23struct FnTableEntry {
22 LLVMValueRef fn_value;24 LLVMValueRef fn_value;
...@@ -66,6 +68,7 @@ struct CodeGen {...@@ -66,6 +68,7 @@ struct CodeGen {
66 bool strip_debug_symbols;68 bool strip_debug_symbols;
67 CodeGenBuildType build_type;69 CodeGenBuildType build_type;
68 LLVMTargetMachineRef target_machine;70 LLVMTargetMachineRef target_machine;
71 bool is_native_target;
69 Buf in_file;72 Buf in_file;
70 Buf in_dir;73 Buf in_dir;
71 ZigList<llvm::DIScope *> block_scopes;74 ZigList<llvm::DIScope *> block_scopes;
...@@ -423,6 +426,7 @@ void semantic_analyze(CodeGen *g) {...@@ -423,6 +426,7 @@ void semantic_analyze(CodeGen *g) {
423 LLVMInitializeAllAsmParsers();426 LLVMInitializeAllAsmParsers();
424 LLVMInitializeNativeTarget();427 LLVMInitializeNativeTarget();
425428
429 g->is_native_target = true;
426 char *native_triple = LLVMGetDefaultTargetTriple();430 char *native_triple = LLVMGetDefaultTargetTriple();
427431
428 LLVMTargetRef target_ref;432 LLVMTargetRef target_ref;
...@@ -699,6 +703,121 @@ ZigList<ErrorMsg> *codegen_error_messages(CodeGen *g) {...@@ -699,6 +703,121 @@ ZigList<ErrorMsg> *codegen_error_messages(CodeGen *g) {
699 return &g->errors;703 return &g->errors;
700}704}
701705
706enum FloatAbi {
707 FloatAbiHard,
708 FloatAbiSoft,
709 FloatAbiSoftFp,
710};
711
712
713static int get_arm_sub_arch_version(const llvm::Triple &triple) {
714 return llvm::ARMTargetParser::parseArchVersion(triple.getArchName());
715}
716
717static FloatAbi get_float_abi(const llvm::Triple &triple) {
718 switch (triple.getOS()) {
719 case llvm::Triple::Darwin:
720 case llvm::Triple::MacOSX:
721 case llvm::Triple::IOS:
722 if (get_arm_sub_arch_version(triple) == 6 ||
723 get_arm_sub_arch_version(triple) == 7)
724 {
725 return FloatAbiSoftFp;
726 } else {
727 return FloatAbiSoft;
728 }
729 case llvm::Triple::Win32:
730 return FloatAbiHard;
731 case llvm::Triple::FreeBSD:
732 switch (triple.getEnvironment()) {
733 case llvm::Triple::GNUEABIHF:
734 return FloatAbiHard;
735 default:
736 return FloatAbiSoft;
737 }
738 default:
739 switch (triple.getEnvironment()) {
740 case llvm::Triple::GNUEABIHF:
741 return FloatAbiHard;
742 case llvm::Triple::GNUEABI:
743 return FloatAbiSoftFp;
744 case llvm::Triple::EABIHF:
745 return FloatAbiHard;
746 case llvm::Triple::EABI:
747 return FloatAbiSoftFp;
748 case llvm::Triple::Android:
749 if (get_arm_sub_arch_version(triple) == 7) {
750 return FloatAbiSoftFp;
751 } else {
752 return FloatAbiSoft;
753 }
754 default:
755 return FloatAbiSoft;
756 }
757 }
758}
759
760static Buf *get_dynamic_linker(CodeGen *g) {
761 llvm::TargetMachine *target_machine = reinterpret_cast<llvm::TargetMachine*>(g->target_machine);
762 const llvm::Triple &triple = target_machine->getTargetTriple();
763
764 const llvm::Triple::ArchType arch = triple.getArch();
765
766 if (triple.getEnvironment() == llvm::Triple::Android) {
767 if (triple.isArch64Bit()) {
768 return buf_create_from_str("/system/bin/linker64");
769 } else {
770 return buf_create_from_str("/system/bin/linker");
771 }
772 } else if (arch == llvm::Triple::x86 ||
773 arch == llvm::Triple::sparc ||
774 arch == llvm::Triple::sparcel)
775 {
776 return buf_create_from_str("/lib/ld-linux.so.2");
777 } else if (arch == llvm::Triple::aarch64) {
778 return buf_create_from_str("/lib/ld-linux-aarch64.so.1");
779 } else if (arch == llvm::Triple::aarch64_be) {
780 return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1");
781 } else if (arch == llvm::Triple::arm || arch == llvm::Triple::thumb) {
782 if (triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
783 get_float_abi(triple) == FloatAbiHard)
784 {
785 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
786 } else {
787 return buf_create_from_str("/lib/ld-linux.so.3");
788 }
789 } else if (arch == llvm::Triple::armeb || arch == llvm::Triple::thumbeb) {
790 if (triple.getEnvironment() == llvm::Triple::GNUEABIHF ||
791 get_float_abi(triple) == FloatAbiHard)
792 {
793 return buf_create_from_str("/lib/ld-linux-armhf.so.3");
794 } else {
795 return buf_create_from_str("/lib/ld-linux.so.3");
796 }
797 } else if (arch == llvm::Triple::mips || arch == llvm::Triple::mipsel ||
798 arch == llvm::Triple::mips64 || arch == llvm::Triple::mips64el)
799 {
800 // when you want to solve this TODO, grep clang codebase for
801 // getLinuxDynamicLinker
802 zig_panic("TODO figure out MIPS dynamic linker name");
803 } else if (arch == llvm::Triple::ppc) {
804 return buf_create_from_str("/lib/ld.so.1");
805 } else if (arch == llvm::Triple::ppc64) {
806 return buf_create_from_str("/lib64/ld64.so.2");
807 } else if (arch == llvm::Triple::ppc64le) {
808 return buf_create_from_str("/lib64/ld64.so.2");
809 } else if (arch == llvm::Triple::systemz) {
810 return buf_create_from_str("/lib64/ld64.so.1");
811 } else if (arch == llvm::Triple::sparcv9) {
812 return buf_create_from_str("/lib64/ld-linux.so.2");
813 } else if (arch == llvm::Triple::x86_64 &&
814 triple.getEnvironment() == llvm::Triple::GNUX32)
815 {
816 return buf_create_from_str("/libx32/ld-linux-x32.so.2");
817 } else {
818 return buf_create_from_str("/lib64/ld-linux-x86-64.so.2");
819 }
820}
702821
703void code_gen_link(CodeGen *g, const char *out_file) {822void code_gen_link(CodeGen *g, const char *out_file) {
704 LLVMPassRegistryRef registry = LLVMGetGlobalPassRegistry();823 LLVMPassRegistryRef registry = LLVMGetGlobalPassRegistry();
...@@ -721,13 +840,21 @@ void code_gen_link(CodeGen *g, const char *out_file) {...@@ -721,13 +840,21 @@ void code_gen_link(CodeGen *g, const char *out_file) {
721 if (g->is_static) {840 if (g->is_static) {
722 args.append("-static");841 args.append("-static");
723 }842 }
724 if (getenv("ZIG_DEBIAN_HACK") != nullptr) {843
725 // XXX: hack. see https://github.com/andrewrk/zig/issues/1844 char *ZIG_NATIVE_DYNAMIC_LINKER = getenv("ZIG_NATIVE_DYNAMIC_LINKER");
845 if (g->is_native_target && ZIG_NATIVE_DYNAMIC_LINKER) {
846 if (ZIG_NATIVE_DYNAMIC_LINKER[0] != 0) {
847 args.append("-dynamic-linker");
848 args.append(ZIG_NATIVE_DYNAMIC_LINKER);
849 }
850 } else {
726 args.append("-dynamic-linker");851 args.append("-dynamic-linker");
727 args.append("/lib64/ld-linux-x86-64.so.2");852 args.append(buf_ptr(get_dynamic_linker(g)));
728 }853 }
854
729 args.append("-o");855 args.append("-o");
730 args.append(out_file);856 args.append(out_file);
857
731 args.append((const char *)buf_ptr(&out_file_o));858 args.append((const char *)buf_ptr(&out_file_o));
732859
733 auto it = g->link_table.entry_iterator();860 auto it = g->link_table.entry_iterator();
...@@ -742,3 +869,5 @@ void code_gen_link(CodeGen *g, const char *out_file) {...@@ -742,3 +869,5 @@ void code_gen_link(CodeGen *g, const char *out_file) {
742869
743 os_spawn_process("ld", args, false);870 os_spawn_process("ld", args, false);
744}871}
872
873
test/standalone.cpp+3-3
...@@ -102,9 +102,9 @@ static void run_test(TestCase *test_case) {...@@ -102,9 +102,9 @@ static void run_test(TestCase *test_case) {
102102
103 if (return_code != 0) {103 if (return_code != 0) {
104 printf("\nProgram exited with return code %d:\n", return_code);104 printf("\nProgram exited with return code %d:\n", return_code);
105 printf("zig");105 printf("%s", tmp_exe_path);
106 for (int i = 0; i < test_case->compiler_args.length; i += 1) {106 for (int i = 0; i < test_case->program_args.length; i += 1) {
107 printf(" %s", test_case->compiler_args.at(i));107 printf(" %s", test_case->program_args.at(i));
108 }108 }
109 printf("\n");109 printf("\n");
110 printf("%s\n", buf_ptr(&program_stderr));110 printf("%s\n", buf_ptr(&program_stderr));