Commit d565c5dfcd

Jakub Konka <kubkon@jakubkonka.com>
2024-03-14 17:04:23
macho: fix a sad typo in calculating the address of a TLV pointer
1 parent 5193da3
Changed files (2)
src
link
test
src/link/MachO/synthetic.zig
@@ -532,7 +532,7 @@ pub const TlvPtrSection = struct {
     pub fn getAddress(tlv: TlvPtrSection, index: Index, macho_file: *MachO) u64 {
         assert(index < tlv.symbols.items.len);
         const header = macho_file.sections.items(.header)[macho_file.tlv_ptr_sect_index.?];
-        return header.addr + index * @sizeOf(u64) * 3;
+        return header.addr + index * @sizeOf(u64);
     }
 
     pub fn size(tlv: TlvPtrSection) usize {
test/link/macho.zig
@@ -72,6 +72,7 @@ pub fn testAll(b: *Build, build_opts: BuildOptions) *Step {
         macho_step.dependOn(testSearchStrategy(b, .{ .target = default_target }));
         macho_step.dependOn(testTbdv3(b, .{ .target = default_target }));
         macho_step.dependOn(testTls(b, .{ .target = default_target }));
+        macho_step.dependOn(testTlsPointers(b, .{ .target = default_target }));
         macho_step.dependOn(testTwoLevelNamespace(b, .{ .target = default_target }));
         macho_step.dependOn(testWeakLibrary(b, .{ .target = default_target }));
 
@@ -1654,6 +1655,71 @@ fn testTls(b: *Build, opts: Options) *Step {
     return test_step;
 }
 
+// https://github.com/ziglang/zig/issues/19221
+fn testTlsPointers(b: *Build, opts: Options) *Step {
+    const test_step = addTestStep(b, "tls-pointers", opts);
+
+    const foo_h = foo_h: {
+        const wf = WriteFile.create(b);
+        break :foo_h wf.add("foo.h",
+            \\template<typename just4fun>
+            \\struct Foo {
+            \\
+            \\public:
+            \\  static int getVar() {
+            \\  static int thread_local var = 0;
+            \\  ++var;
+            \\  return var;
+            \\}
+            \\};
+        );
+    };
+
+    const bar_o = addObject(b, opts, .{ .name = "bar", .cpp_source_bytes = 
+    \\#include "foo.h"
+    \\int bar() {
+    \\  int v1 = Foo<int>::getVar();
+    \\  return v1;
+    \\}
+    });
+    bar_o.root_module.addIncludePath(foo_h.dirname());
+    bar_o.linkLibCpp();
+
+    const baz_o = addObject(b, opts, .{ .name = "baz", .cpp_source_bytes = 
+    \\#include "foo.h"
+    \\int baz() {
+    \\  int v1 = Foo<unsigned>::getVar();
+    \\  return v1;
+    \\}
+    });
+    baz_o.root_module.addIncludePath(foo_h.dirname());
+    baz_o.linkLibCpp();
+
+    const main_o = addObject(b, opts, .{ .name = "main", .cpp_source_bytes = 
+    \\extern int bar();
+    \\extern int baz();
+    \\int main() {
+    \\  int v1 = bar();
+    \\  int v2 = baz();
+    \\  return v1 != v2;
+    \\}
+    });
+    main_o.root_module.addIncludePath(foo_h.dirname());
+    main_o.linkLibCpp();
+
+    const exe = addExecutable(b, opts, .{ .name = "main" });
+    exe.addObject(bar_o);
+    exe.addObject(baz_o);
+    exe.addObject(main_o);
+    exe.linkLibCpp();
+
+    const run = addRunArtifact(exe);
+    run.expectExitCode(0);
+    test_step.dependOn(&run.step);
+
+    return test_step;
+}
+
 fn testTlsLargeTbss(b: *Build, opts: Options) *Step {
     const test_step = addTestStep(b, "tls-large-tbss", opts);