From 0b7bef19b6b43d66667f8bd35701fa45ebee7f16 Mon Sep 17 00:00:00 2001 From: Jakub Konka Date: Thu, 14 Mar 2024 16:38:27 +0100 Subject: [PATCH] macho: fix a sad typo in calculating the address of a TLV pointer --- src/MachO/synthetic.zig | 2 +- test/macho.zig | 67 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/src/MachO/synthetic.zig b/src/MachO/synthetic.zig index d99aee56..1bef39ca 100644 --- a/src/MachO/synthetic.zig +++ b/src/MachO/synthetic.zig @@ -412,7 +412,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 { diff --git a/test/macho.zig b/test/macho.zig index 3e9ecb1b..148de705 100644 --- a/test/macho.zig +++ b/test/macho.zig @@ -70,6 +70,7 @@ pub fn addMachOTests(b: *Build, options: common.Options) *Step { macho_step.dependOn(testThunks(b, opts)); macho_step.dependOn(testTls(b, opts)); macho_step.dependOn(testTlsLargeTbss(b, opts)); + macho_step.dependOn(testTlsPointers(b, opts)); macho_step.dependOn(testTwoLevelNamespace(b, opts)); macho_step.dependOn(testUndefinedFlag(b, opts)); macho_step.dependOn(testUnwindInfo(b, opts)); @@ -2922,6 +2923,72 @@ fn testTlsLargeTbss(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 = b.step("test-macho-tls-pointers", ""); + + const includes = WriteFile.create(b); + _ = includes.add("foo.h", + \\template + \\struct Foo { + \\ + \\public: + \\ static int getVar() { + \\ static int thread_local var = 0; + \\ ++var; + \\ return var; + \\} + \\}; + ); + + const bar_o = cc(b, "bar.o", opts); + bar_o.addCppSource( + \\#include "foo.h" + \\int bar() { + \\ int v1 = Foo::getVar(); + \\ return v1; + \\} + ); + bar_o.addArgs(&.{ "-c", "-std=c++17" }); + bar_o.addPrefixedDirectorySource("-I", includes.getDirectory()); + + const baz_o = cc(b, "baz.o", opts); + baz_o.addCppSource( + \\#include "foo.h" + \\int baz() { + \\ int v1 = Foo::getVar(); + \\ return v1; + \\} + ); + baz_o.addArgs(&.{ "-c", "-std=c++17" }); + baz_o.addPrefixedDirectorySource("-I", includes.getDirectory()); + + const main_o = cc(b, "main.o", opts); + main_o.addCppSource( + \\extern int bar(); + \\extern int baz(); + \\int main() { + \\ int v1 = bar(); + \\ int v2 = baz(); + \\ return v1 != v2; + \\} + ); + main_o.addArgs(&.{ "-c", "-std=c++17" }); + main_o.addPrefixedDirectorySource("-I", includes.getDirectory()); + + const exe = cc(b, "a.out", opts); + exe.addFileSource(bar_o.getFile()); + exe.addFileSource(baz_o.getFile()); + exe.addFileSource(main_o.getFile()); + exe.addArg("-lc++"); + + const run = exe.run(); + run.expectExitCode(0); + test_step.dependOn(run.step()); + + return test_step; +} + fn testUndefinedFlag(b: *Build, opts: Options) *Step { const test_step = b.step("test-macho-undefined-flag", "");