Skip to content

Commit bf67427

Browse files
committed
fix crash when using zig to link
without explicit dynamic linker
1 parent 41144a8 commit bf67427

File tree

5 files changed

+81
-84
lines changed

5 files changed

+81
-84
lines changed

src/link.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,3 +536,80 @@ const char *target_o_file_ext(ZigTarget *target) {
536536
}
537537
}
538538

539+
enum FloatAbi {
540+
FloatAbiHard,
541+
FloatAbiSoft,
542+
FloatAbiSoftFp,
543+
};
544+
545+
static 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+
557+
static bool is_64_bit(ZigLLVM_ArchType arch) {
558+
return get_arch_pointer_bit_width(arch) == 64;
559+
}
560+
561+
Buf *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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id);
7474

7575
const char *target_o_file_ext(ZigTarget *target);
7676

77+
Buf *target_dynamic_linker(ZigTarget *target);
78+
79+
7780
#endif

src/zig_llvm.cpp

Lines changed: 0 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -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

775-
enum FloatAbi {
776-
FloatAbiHard,
777-
FloatAbiSoft,
778-
FloatAbiSoftFp,
779-
};
780-
781-
static 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-
792-
Buf *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-
854773
bool 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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,4 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
363363
ZigLLVM_ObjectFormatType *oformat);
364364

365365

366-
Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine);
367-
368366
#endif

0 commit comments

Comments
 (0)