diff --git a/src/codegen.cpp b/src/codegen.cpp index 11a368cda6..44e66c4dd8 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7288,7 +7288,7 @@ static bool detect_dynamic_link(CodeGen *g) { return true; if (g->zig_target->os == OsFreestanding) return false; - if (target_requires_pic(g->zig_target)) + if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr)) return true; if (g->out_type == OutTypeExe) { // If there are no dynamic libraries then we can disable PIC @@ -7304,7 +7304,7 @@ static bool detect_dynamic_link(CodeGen *g) { } static bool detect_pic(CodeGen *g) { - if (target_requires_pic(g->zig_target)) + if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr)) return true; switch (g->want_pic) { case WantPICDisabled: @@ -7848,7 +7848,14 @@ static void init(CodeGen *g) { bool is_optimized = g->build_mode != BuildModeDebug; LLVMCodeGenOptLevel opt_level = is_optimized ? LLVMCodeGenLevelAggressive : LLVMCodeGenLevelNone; - LLVMRelocMode reloc_mode = g->have_pic ? LLVMRelocPIC: LLVMRelocStatic; + LLVMRelocMode reloc_mode; + if (g->have_pic) { + reloc_mode = LLVMRelocPIC; + } else if (g->have_dynamic_link) { + reloc_mode = LLVMRelocDynamicNoPic; + } else { + reloc_mode = LLVMRelocStatic; + } const char *target_specific_cpu_args; const char *target_specific_features; diff --git a/src/main.cpp b/src/main.cpp index 81aaaaa368..f58a00209a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -417,6 +417,7 @@ int main(int argc, char **argv) { ZigList link_libs = {0}; ZigList forbidden_link_libs = {0}; ZigList frameworks = {0}; + bool have_libc = false; const char *target_string = nullptr; bool rdynamic = false; const char *mmacosx_version_min = nullptr; @@ -745,6 +746,8 @@ int main(int argc, char **argv) { } else if (strcmp(arg, "--library-path") == 0 || strcmp(arg, "-L") == 0) { lib_dirs.append(argv[i]); } else if (strcmp(arg, "--library") == 0) { + if (strcmp(argv[i], "c") == 0) + have_libc = true; link_libs.append(argv[i]); } else if (strcmp(arg, "--forbid-library") == 0) { forbidden_link_libs.append(argv[i]); @@ -911,7 +914,7 @@ int main(int argc, char **argv) { return print_error_usage(arg0); } - if (target_requires_pic(&target) && want_pic == WantPICDisabled) { + if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) { Buf triple_buf = BUF_INIT; get_target_triple(&triple_buf, &target); fprintf(stderr, "`--disable-pic` is incompatible with target '%s'\n", buf_ptr(&triple_buf)); diff --git a/src/target.cpp b/src/target.cpp index 22d8dd2357..7239ea17ba 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -1300,9 +1300,10 @@ bool target_supports_fpic(const ZigTarget *target) { return target->os != OsWindows; } -bool target_requires_pic(const ZigTarget *target) { +bool target_requires_pic(const ZigTarget *target, bool linking_libc) { // This function returns whether non-pic code is completely invalid on the given target. - return target->os == OsWindows || target_os_requires_libc(target->os) || target_is_glibc(target); + return target->os == OsWindows || target_os_requires_libc(target->os) || + (linking_libc && target_is_glibc(target)); } bool target_is_glibc(const ZigTarget *target) { diff --git a/src/target.hpp b/src/target.hpp index 072bfc184c..d42ebcc576 100644 --- a/src/target.hpp +++ b/src/target.hpp @@ -161,7 +161,7 @@ bool target_can_build_libc(const ZigTarget *target); const char *target_libc_generic_name(const ZigTarget *target); bool target_is_libc_lib_name(const ZigTarget *target, const char *name); bool target_supports_fpic(const ZigTarget *target); -bool target_requires_pic(const ZigTarget *target); +bool target_requires_pic(const ZigTarget *target, bool linking_libc); bool target_abi_is_gnu(ZigLLVM_EnvironmentType abi); bool target_abi_is_musl(ZigLLVM_EnvironmentType abi); bool target_is_glibc(const ZigTarget *target); diff --git a/std/os/test.zig b/std/os/test.zig index ab21ea1568..943960a925 100644 --- a/std/os/test.zig +++ b/std/os/test.zig @@ -108,6 +108,10 @@ test "AtomicFile" { test "thread local storage" { if (builtin.single_threaded) return error.SkipZigTest; + if (!builtin.position_independent_code and !builtin.link_libc) { + // TODO https://github.com/ziglang/zig/issues/2063 + return error.SkipZigTest; + } const thread1 = try std.os.spawnThread({}, testTls); const thread2 = try std.os.spawnThread({}, testTls); testTls({}); diff --git a/test/stage1/behavior/misc.zig b/test/stage1/behavior/misc.zig index a2d752457c..36246162f5 100644 --- a/test/stage1/behavior/misc.zig +++ b/test/stage1/behavior/misc.zig @@ -688,6 +688,11 @@ fn getNull() ?*i32 { } test "thread local variable" { + if (!builtin.position_independent_code and !builtin.link_libc) { + // TODO https://github.com/ziglang/zig/issues/2063 + return error.SkipZigTest; + } + const S = struct { threadlocal var t: i32 = 1234; };