authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-04 08:48:48+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-13 11:47:51+02:00
log1795b8eb4e8db95cb639349c6c1bc4b0b82741bb
treec6bba1429161f3372ec8153d3a0f523f7d4ebde8
parentcf9ba2965eb90de994dd648950ad81041f90b755

macho: emit TLS sections


1 files changed, 29 insertions(+), 1 deletions(-)

src/link/MachO.zig+29-1
...@@ -138,6 +138,8 @@ got_section_index: ?u8 = null,...@@ -138,6 +138,8 @@ got_section_index: ?u8 = null,
138data_const_section_index: ?u8 = null,138data_const_section_index: ?u8 = null,
139la_symbol_ptr_section_index: ?u8 = null,139la_symbol_ptr_section_index: ?u8 = null,
140data_section_index: ?u8 = null,140data_section_index: ?u8 = null,
141tls_vars_section_index: ?u8 = null,
142tls_data_section_index: ?u8 = null,
141143
142locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},144locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
143globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{},145globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{},
...@@ -2366,6 +2368,7 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {...@@ -2366,6 +2368,7 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {
2366 const val = decl.val;2368 const val = decl.val;
2367 const zig_ty = ty.zigTypeTag();2369 const zig_ty = ty.zigTypeTag();
2368 const mode = self.base.options.optimize_mode;2370 const mode = self.base.options.optimize_mode;
2371 const single_threaded = self.base.options.single_threaded;
2369 const sect_id: u8 = blk: {2372 const sect_id: u8 = blk: {
2370 // TODO finish and audit this function2373 // TODO finish and audit this function
2371 if (val.isUndefDeep()) {2374 if (val.isUndefDeep()) {
...@@ -2376,7 +2379,10 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {...@@ -2376,7 +2379,10 @@ fn getDeclOutputSection(self: *MachO, decl_index: Module.Decl.Index) u8 {
2376 }2379 }
2377 }2380 }
23782381
2379 if (val.castTag(.variable)) |_| {2382 if (val.castTag(.variable)) |variable| {
2383 if (variable.data.is_threadlocal and !single_threaded) {
2384 break :blk self.tls_data_section_index.?;
2385 }
2380 break :blk self.data_section_index.?;2386 break :blk self.data_section_index.?;
2381 }2387 }
23822388
...@@ -2800,6 +2806,28 @@ fn populateMissingMetadata(self: *MachO) !void {...@@ -2800,6 +2806,28 @@ fn populateMissingMetadata(self: *MachO) !void {
2800 self.segment_table_dirty = true;2806 self.segment_table_dirty = true;
2801 }2807 }
28022808
2809 if (!self.base.options.single_threaded) {
2810 if (self.tls_vars_section_index == null) {
2811 self.tls_vars_section_index = try self.allocateSection("__DATA2", "__thread_vars", .{
2812 .size = @sizeOf(u64) * 3,
2813 .alignment = @alignOf(u64),
2814 .flags = macho.S_THREAD_LOCAL_VARIABLES,
2815 .prot = macho.PROT.READ | macho.PROT.WRITE,
2816 });
2817 self.segment_table_dirty = true;
2818 }
2819
2820 if (self.tls_data_section_index == null) {
2821 self.tls_data_section_index = try self.allocateSection("__DATA3", "__thread_data", .{
2822 .size = @sizeOf(u64),
2823 .alignment = @alignOf(u64),
2824 .flags = macho.S_THREAD_LOCAL_REGULAR,
2825 .prot = macho.PROT.READ | macho.PROT.WRITE,
2826 });
2827 self.segment_table_dirty = true;
2828 }
2829 }
2830
2803 if (self.linkedit_segment_cmd_index == null) {2831 if (self.linkedit_segment_cmd_index == null) {
2804 self.linkedit_segment_cmd_index = @intCast(u8, self.segments.items.len);2832 self.linkedit_segment_cmd_index = @intCast(u8, self.segments.items.len);
28052833