Commit 20c36949e1

Andrew Kelley <andrew@ziglang.org>
2019-03-14 04:15:34
fix target_requires_pic and reloc_mode
disable failing thread local variable test. see #2063
1 parent 5d2edac
Changed files (6)
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;
src/main.cpp
@@ -417,6 +417,7 @@ int main(int argc, char **argv) {
     ZigList<const char *> link_libs = {0};
     ZigList<const char *> forbidden_link_libs = {0};
     ZigList<const char *> 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));
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) {
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);
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({});
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;
     };