authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-18 18:58:29+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:41+01:00
log96cc9fafbf0a382c0ed0b6142986cd8373cffaa3
treeec6cf83208e30a54f263807cf4e72f07b90457cd
parent76dc305d4e71a9a4c9de92e6dde40a53eac1e328

codegen: re-implement enough of codegen to error out instead panic


8 files changed, 197 insertions(+), 202 deletions(-)

src/arch/x86_64/CodeGen.zig+27-63
......@@ -139,10 +139,7 @@ const Owner = union(enum) {
139139 if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {
140140 return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
141141 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
142 _ = macho_file;
143 // const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
144 // return macho_file.getAtom(atom).getSymbolIndex().?;
145 @panic("TODO getSymbolIndex");
142 return macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, decl_index);
146143 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
147144 const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
148145 return coff_file.getAtom(atom).getSymbolIndex().?;
......@@ -155,11 +152,8 @@ const Owner = union(enum) {
155152 return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|
156153 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
157154 } else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
158 _ = macho_file;
159 // const atom = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
160 // return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
161 // return macho_file.getAtom(atom).getSymbolIndex().?;
162 @panic("TODO getSymbolIndex");
155 return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err|
156 ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
163157 } else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
164158 const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
165159 return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
......@@ -10955,12 +10949,10 @@ fn genCall(self: *Self, info: union(enum) {
1095510949 try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
1095610950 try self.asmRegister(.{ ._, .call }, .rax);
1095710951 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
10958 _ = macho_file;
10959 @panic("TODO genCall");
10960 // const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
10961 // const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
10962 // try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
10963 // try self.asmRegister(.{ ._, .call }, .rax);
10952 const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, func.owner_decl);
10953 const sym = macho_file.getSymbol(sym_index);
10954 try self.genSetReg(.rax, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } });
10955 try self.asmRegister(.{ ._, .call }, .rax);
1096410956 } else if (self.bin_file.cast(link.File.Plan9)) |p9| {
1096510957 const atom_index = try p9.seeDecl(func.owner_decl);
1096610958 const atom = p9.getAtom(atom_index);
......@@ -13556,30 +13548,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
1355613548 } },
1355713549 });
1355813550 },
13559 .lea_tlv => |sym_index| {
13560 const atom_index = try self.owner.getSymbolIndex(self);
13561 if (self.bin_file.cast(link.File.MachO)) |_| {
13562 _ = try self.addInst(.{
13563 .tag = .lea,
13564 .ops = .tlv_reloc,
13565 .data = .{ .rx = .{
13566 .r1 = .rdi,
13567 .payload = try self.addExtra(bits.Symbol{
13568 .atom_index = atom_index,
13569 .sym_index = sym_index,
13570 }),
13571 } },
13572 });
13573 // TODO: spill registers before calling
13574 try self.asmMemory(.{ ._, .call }, .{
13575 .base = .{ .reg = .rdi },
13576 .mod = .{ .rm = .{ .size = .qword } },
13577 });
13578 try self.genSetReg(dst_reg.to64(), Type.usize, .{ .register = .rax });
13579 } else return self.fail("TODO emit ptr to TLV sequence on {s}", .{
13580 @tagName(self.bin_file.tag),
13581 });
13582 },
13551 .lea_tlv => unreachable, // TODO: remove this
1358313552 .air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref)),
1358413553 }
1358513554}
......@@ -13816,19 +13785,14 @@ fn genExternSymbolRef(
1381613785 else => unreachable,
1381713786 }
1381813787 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
13819 const global_index = try macho_file.getGlobalSymbol(callee, lib);
1382013788 _ = try self.addInst(.{
1382113789 .tag = .call,
1382213790 .ops = .extern_fn_reloc,
13823 .data = .{
13824 .reloc = .{
13825 .atom_index = atom_index,
13826 // .sym_index = link.File.MachO.global_symbol_bit | global_index,
13827 .sym_index = global_index,
13828 },
13829 },
13791 .data = .{ .reloc = .{
13792 .atom_index = atom_index,
13793 .sym_index = try macho_file.getGlobalSymbol(callee, lib),
13794 } },
1383013795 });
13831 @panic("TODO genExternSymbolRef");
1383213796 } else return self.fail("TODO implement calling extern functions", .{});
1383313797}
1383413798
......@@ -13916,21 +13880,19 @@ fn genLazySymbolRef(
1391613880 else => unreachable,
1391713881 }
1391813882 } else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
13919 _ = macho_file;
13920 @panic("TODO genLazySymbolRef");
13921 // const atom_index = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
13922 // return self.fail("{s} creating lazy symbol", .{@errorName(err)});
13923 // const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
13924 // switch (tag) {
13925 // .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym_index }),
13926 // .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym_index }),
13927 // else => unreachable,
13928 // }
13929 // switch (tag) {
13930 // .lea, .mov => {},
13931 // .call => try self.asmRegister(.{ ._, .call }, reg),
13932 // else => unreachable,
13933 // }
13883 const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err|
13884 return self.fail("{s} creating lazy symbol", .{@errorName(err)});
13885 const sym = macho_file.getSymbol(sym_index);
13886 switch (tag) {
13887 .lea, .call => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }),
13888 .mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }),
13889 else => unreachable,
13890 }
13891 switch (tag) {
13892 .lea, .mov => {},
13893 .call => try self.asmRegister(.{ ._, .call }, reg),
13894 else => unreachable,
13895 }
1393413896 } else {
1393513897 return self.fail("TODO implement genLazySymbol for x86_64 {s}", .{@tagName(self.bin_file.tag)});
1393613898 }
......@@ -16103,6 +16065,8 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
1610316065 .{ .lea_symbol = .{ .sym = tlv_sym } },
1610416066 );
1610516067 break :init .{ .load_frame = .{ .index = frame_index } };
16068 } else if (self.bin_file.cast(link.File.MachO)) |_| {
16069 return self.fail("TODO implement lowering TLV variable to stack", .{});
1610616070 } else break :init const_mcv,
1610716071 else => break :init const_mcv,
1610816072 }
src/arch/x86_64/Emit.zig+47-39
......@@ -49,23 +49,21 @@ pub fn emitMir(emit: *Emit) Error!void {
4949 .r_addend = -4,
5050 });
5151 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
52 _ = macho_file;
53 @panic("TODO emitMir");
54 // // Add relocation to the decl.
55 // const atom_index =
56 // macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
57 // const target = if (link.File.MachO.global_symbol_bit & symbol.sym_index != 0)
58 // macho_file.getGlobalByIndex(link.File.MachO.global_symbol_mask & symbol.sym_index)
59 // else
60 // link.File.MachO.SymbolWithLoc{ .sym_index = symbol.sym_index };
61 // try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
62 // .type = .branch,
63 // .target = target,
64 // .offset = end_offset - 4,
65 // .addend = 0,
66 // .pcrel = true,
67 // .length = 2,
68 // });
52 // Add relocation to the decl.
53 const atom = macho_file.getSymbol(symbol.atom_index).getAtom(macho_file).?;
54 try atom.addReloc(macho_file, .{
55 .tag = .@"extern",
56 .offset = end_offset - 4,
57 .target = symbol.sym_index,
58 .addend = 0,
59 .type = .branch,
60 .meta = .{
61 .pcrel = true,
62 .has_subtractor = false,
63 .length = 2,
64 .symbolnum = 0,
65 },
66 });
6967 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
7068 // Add relocation to the decl.
7169 const atom_index = coff_file.getAtomIndexForSymbol(
......@@ -151,6 +149,36 @@ pub fn emitMir(emit: *Emit) Error!void {
151149 });
152150 }
153151 }
152 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
153 const is_obj_or_static_lib = switch (emit.lower.output_mode) {
154 .Exe => false,
155 .Obj => true,
156 .Lib => emit.lower.link_mode == .Static,
157 };
158 const atom = macho_file.getSymbol(data.atom_index).getAtom(macho_file).?;
159 const sym = macho_file.getSymbol(data.sym_index);
160 if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
161 _ = try sym.getOrCreateZigGotEntry(data.sym_index, macho_file);
162 }
163 const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
164 .zig_got_load
165 else if (sym.flags.needs_got)
166 .got_load
167 else
168 .signed;
169 try atom.addReloc(macho_file, .{
170 .tag = .@"extern",
171 .offset = @intCast(end_offset - 4),
172 .target = data.sym_index,
173 .addend = 0,
174 .type = @"type",
175 .meta = .{
176 .pcrel = true,
177 .has_subtractor = false,
178 .length = 2,
179 .symbolnum = 0,
180 },
181 });
154182 } else unreachable,
155183 .linker_got,
156184 .linker_direct,
......@@ -158,28 +186,8 @@ pub fn emitMir(emit: *Emit) Error!void {
158186 .linker_tlv,
159187 => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |_| {
160188 unreachable;
161 } else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
162 _ = macho_file;
163 @panic("TODO emitMir");
164 // const atom_index =
165 // macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
166 // const target = if (link.File.MachO.global_symbol_bit & symbol.sym_index != 0)
167 // macho_file.getGlobalByIndex(link.File.MachO.global_symbol_mask & symbol.sym_index)
168 // else
169 // link.File.MachO.SymbolWithLoc{ .sym_index = symbol.sym_index };
170 // try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
171 // .type = switch (lowered_relocs[0].target) {
172 // .linker_got => .got,
173 // .linker_direct => .signed,
174 // .linker_tlv => .tlv,
175 // else => unreachable,
176 // },
177 // .target = target,
178 // .offset = @intCast(end_offset - 4),
179 // .addend = 0,
180 // .pcrel = true,
181 // .length = 2,
182 // });
189 } else if (emit.lower.bin_file.cast(link.File.MachO)) |_| {
190 unreachable;
183191 } else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
184192 const atom_index = coff_file.getAtomIndexForSymbol(.{
185193 .sym_index = symbol.atom_index,
src/arch/x86_64/Lower.zig+89-80
......@@ -14,7 +14,7 @@ result_relocs_len: u8 = undefined,
1414result_insts: [
1515 std.mem.max(usize, &.{
1616 1, // non-pseudo instructions
17 3, // TLS local dynamic (LD) sequence in PIC mode
17 3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
1818 2, // cmovcc: cmovcc \ cmovcc
1919 3, // setcc: setcc \ setcc \ logicop
2020 2, // jcc: jcc \ jcc
......@@ -32,7 +32,7 @@ result_relocs: [
3232 2, // jcc: jcc \ jcc
3333 2, // test \ jcc \ probe \ sub \ jmp
3434 1, // probe \ sub \ jcc
35 3, // TLS local dynamic (LD) sequence in PIC mode
35 3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
3636 })
3737]Reloc = undefined,
3838
......@@ -326,18 +326,6 @@ fn reloc(lower: *Lower, target: Reloc.Target) Immediate {
326326 return Immediate.s(0);
327327}
328328
329fn needsZigGot(sym: bits.Symbol, ctx: *link.File) bool {
330 const elf_file = ctx.cast(link.File.Elf).?;
331 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
332 return elf_file.symbol(sym_index).flags.needs_zig_got;
333}
334
335fn isTls(sym: bits.Symbol, ctx: *link.File) bool {
336 const elf_file = ctx.cast(link.File.Elf).?;
337 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
338 return elf_file.symbol(sym_index).flags.is_tls;
339}
340
341329fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
342330 const is_obj_or_static_lib = switch (lower.output_mode) {
343331 .Exe => false,
......@@ -359,80 +347,101 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
359347 assert(mem_op.sib.disp == 0);
360348 assert(mem_op.sib.scale_index.scale == 0);
361349
362 if (isTls(sym, lower.bin_file)) {
363 // TODO handle extern TLS vars, i.e., emit GD model
364 if (lower.pic) {
365 // Here, we currently assume local dynamic TLS vars, and so
366 // we emit LD model.
367 _ = lower.reloc(.{ .linker_tlsld = sym });
368 lower.result_insts[lower.result_insts_len] =
369 try Instruction.new(.none, .lea, &[_]Operand{
370 .{ .reg = .rdi },
371 .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
372 });
373 lower.result_insts_len += 1;
374 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
350 if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
351 const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
352 const elf_sym = elf_file.symbol(sym_index);
353
354 if (elf_sym.flags.is_tls) {
355 // TODO handle extern TLS vars, i.e., emit GD model
356 if (lower.pic) {
357 // Here, we currently assume local dynamic TLS vars, and so
358 // we emit LD model.
359 _ = lower.reloc(.{ .linker_tlsld = sym });
360 lower.result_insts[lower.result_insts_len] =
361 try Instruction.new(.none, .lea, &[_]Operand{
362 .{ .reg = .rdi },
363 .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
364 });
365 lower.result_insts_len += 1;
375366 _ = lower.reloc(.{ .linker_extern_fn = .{
376367 .atom_index = sym.atom_index,
377368 .sym_index = try elf_file.getGlobalSymbol("__tls_get_addr", null),
378369 } });
370 lower.result_insts[lower.result_insts_len] =
371 try Instruction.new(.none, .call, &[_]Operand{
372 .{ .imm = Immediate.s(0) },
373 });
374 lower.result_insts_len += 1;
375 _ = lower.reloc(.{ .linker_dtpoff = sym });
376 emit_mnemonic = .lea;
377 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
378 .base = .{ .reg = .rax },
379 .disp = std.math.minInt(i32),
380 }) };
381 } else {
382 // Since we are linking statically, we emit LE model directly.
383 lower.result_insts[lower.result_insts_len] =
384 try Instruction.new(.none, .mov, &[_]Operand{
385 .{ .reg = .rax },
386 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .fs } }) },
387 });
388 lower.result_insts_len += 1;
389 _ = lower.reloc(.{ .linker_reloc = sym });
390 emit_mnemonic = .lea;
391 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
392 .base = .{ .reg = .rax },
393 .disp = std.math.minInt(i32),
394 }) };
379395 }
380 lower.result_insts[lower.result_insts_len] =
381 try Instruction.new(.none, .call, &[_]Operand{
382 .{ .imm = Immediate.s(0) },
383 });
384 lower.result_insts_len += 1;
385 _ = lower.reloc(.{ .linker_dtpoff = sym });
386 emit_mnemonic = .lea;
387 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
388 .base = .{ .reg = .rax },
389 .disp = std.math.minInt(i32),
390 }) };
391 } else {
392 // Since we are linking statically, we emit LE model directly.
393 lower.result_insts[lower.result_insts_len] =
394 try Instruction.new(.none, .mov, &[_]Operand{
395 .{ .reg = .rax },
396 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .fs } }) },
397 });
398 lower.result_insts_len += 1;
399 _ = lower.reloc(.{ .linker_reloc = sym });
400 emit_mnemonic = .lea;
401 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
402 .base = .{ .reg = .rax },
403 .disp = std.math.minInt(i32),
404 }) };
405396 }
406 }
407397
408 _ = lower.reloc(.{ .linker_reloc = sym });
409 break :op if (lower.pic) switch (mnemonic) {
410 .lea => {
411 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
412 },
413 .mov => {
414 if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
415 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
416 },
417 else => unreachable,
418 } else switch (mnemonic) {
419 .call => break :op if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) .{
420 .imm = Immediate.s(0),
421 } else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
422 .base = .{ .reg = .ds },
423 }) },
424 .lea => {
425 emit_mnemonic = .mov;
426 break :op .{ .imm = Immediate.s(0) };
427 },
428 .mov => {
429 if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
430 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
398 _ = lower.reloc(.{ .linker_reloc = sym });
399 break :op if (lower.pic) switch (mnemonic) {
400 .lea => {
401 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
402 },
403 .mov => {
404 if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea;
405 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
406 },
407 else => unreachable,
408 } else switch (mnemonic) {
409 .call => break :op if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) .{
410 .imm = Immediate.s(0),
411 } else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
431412 .base = .{ .reg = .ds },
432 }) };
433 },
434 else => unreachable,
435 };
413 }) },
414 .lea => {
415 emit_mnemonic = .mov;
416 break :op .{ .imm = Immediate.s(0) };
417 },
418 .mov => {
419 if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea;
420 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
421 .base = .{ .reg = .ds },
422 }) };
423 },
424 else => unreachable,
425 };
426 } else if (lower.bin_file.cast(link.File.MachO)) |macho_file| {
427 const macho_sym = macho_file.getSymbol(sym.sym_index);
428
429 if (macho_sym.flags.tlv) {
430 @panic("TODO lower TLS access on macOS");
431 }
432
433 _ = lower.reloc(.{ .linker_reloc = sym });
434 break :op switch (mnemonic) {
435 .lea => {
436 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
437 },
438 .mov => {
439 if (is_obj_or_static_lib and macho_sym.flags.needs_zig_got) emit_mnemonic = .lea;
440 break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
441 },
442 else => unreachable,
443 };
444 }
436445 },
437446 },
438447 };
src/codegen.zig+6-1
......@@ -1045,7 +1045,12 @@ fn genUnnamedConst(
10451045 const local = elf_file.symbol(local_sym_index);
10461046 return GenResult.mcv(.{ .load_symbol = local.esym_index });
10471047 },
1048 .macho, .coff => {
1048 .macho => {
1049 const macho_file = lf.cast(link.File.MachO).?;
1050 const local = macho_file.getSymbol(local_sym_index);
1051 return GenResult.mcv(.{ .load_symbol = local.nlist_idx });
1052 },
1053 .coff => {
10491054 return GenResult.mcv(.{ .load_direct = local_sym_index });
10501055 },
10511056 .plan9 => {
src/link/MachO.zig+1-1
......@@ -4280,7 +4280,7 @@ const Md5 = std.crypto.hash.Md5;
42804280const Module = @import("../Module.zig");
42814281const InternPool = @import("../InternPool.zig");
42824282const RebaseSection = synthetic.RebaseSection;
4283const Relocation = @import("MachO/Relocation.zig");
4283pub const Relocation = @import("MachO/Relocation.zig");
42844284const StringTable = @import("StringTable.zig");
42854285const StubsSection = synthetic.StubsSection;
42864286const StubsHelperSection = synthetic.StubsHelperSection;
src/link/MachO/Atom.zig+6
......@@ -686,6 +686,10 @@ fn resolveRelocInner(
686686 }
687687 },
688688
689 .zig_got_load => {
690 @panic("TODO resolve __got_zig indirection reloc");
691 },
692
689693 .tlv => {
690694 assert(rel.tag == .@"extern");
691695 assert(rel.meta.length == 2);
......@@ -987,6 +991,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: *std.Arra
987991 .subtractor => .ARM64_RELOC_SUBTRACTOR,
988992 .unsigned => .ARM64_RELOC_UNSIGNED,
989993
994 .zig_got_load,
990995 .signed,
991996 .signed1,
992997 .signed2,
......@@ -1030,6 +1035,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: *std.Arra
10301035 .subtractor => .X86_64_RELOC_SUBTRACTOR,
10311036 .unsigned => .X86_64_RELOC_UNSIGNED,
10321037
1038 .zig_got_load,
10331039 .page,
10341040 .pageoff,
10351041 .got_load_page,
src/link/MachO/Relocation.zig+2
......@@ -99,6 +99,8 @@ pub const Type = enum {
9999 got_load,
100100 /// RIP-relative TLV load (X86_64_RELOC_TLV)
101101 tlv,
102 /// Zig-specific __got_zig indirection
103 zig_got_load,
102104
103105 // arm64
104106 /// PC-relative load (distance to page, ARM64_RELOC_PAGE21)
src/link/MachO/ZigObject.zig+19-18
......@@ -248,7 +248,7 @@ pub fn getDeclVAddr(
248248 .pcrel = false,
249249 .has_subtractor = false,
250250 .length = 3,
251 .symbolnum = @intCast(sym.nlist_idx),
251 .symbolnum = 0,
252252 },
253253 });
254254 return vaddr;
......@@ -274,7 +274,7 @@ pub fn getAnonDeclVAddr(
274274 .pcrel = false,
275275 .has_subtractor = false,
276276 .length = 3,
277 .symbolnum = @intCast(sym.nlist_idx),
277 .symbolnum = 0,
278278 },
279279 });
280280 return vaddr;
......@@ -604,25 +604,26 @@ fn getDeclOutputSection(
604604 _ = self;
605605 const mod = macho_file.base.comp.module.?;
606606 const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
607 _ = any_non_single_threaded;
607608 const sect_id: u8 = switch (decl.ty.zigTypeTag(mod)) {
608609 .Fn => macho_file.zig_text_section_index.?,
609610 else => blk: {
610611 if (decl.getOwnedVariable(mod)) |variable| {
611 if (variable.is_threadlocal and any_non_single_threaded) {
612 const is_all_zeroes = for (code) |byte| {
613 if (byte != 0) break false;
614 } else true;
615 if (is_all_zeroes) break :blk macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
616 "__DATA",
617 "__thread_bss",
618 .{ .flags = macho.S_THREAD_LOCAL_ZEROFILL },
619 );
620 break :blk macho_file.getSectionByName("__DATA", "__thread_data") orelse try macho_file.addSection(
621 "__DATA",
622 "__thread_data",
623 .{ .flags = macho.S_THREAD_LOCAL_REGULAR },
624 );
625 }
612 // if (variable.is_threadlocal and any_non_single_threaded) {
613 // const is_all_zeroes = for (code) |byte| {
614 // if (byte != 0) break false;
615 // } else true;
616 // if (is_all_zeroes) break :blk macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
617 // "__DATA",
618 // "__thread_bss",
619 // .{ .flags = macho.S_THREAD_LOCAL_ZEROFILL },
620 // );
621 // break :blk macho_file.getSectionByName("__DATA", "__thread_data") orelse try macho_file.addSection(
622 // "__DATA",
623 // "__thread_data",
624 // .{ .flags = macho.S_THREAD_LOCAL_REGULAR },
625 // );
626 // }
626627
627628 if (variable.is_const) break :blk macho_file.zig_const_section_index.?;
628629 if (Value.fromInterned(variable.init).isUndefDeep(mod)) {
......@@ -917,7 +918,7 @@ fn updateLazySymbol(
917918
918919 sym.value = 0;
919920 sym.flags.needs_zig_got = true;
920 nlist.st_value = 0;
921 nlist.n_value = 0;
921922
922923 if (!macho_file.base.isRelocatable()) {
923924 const gop = try sym.getOrCreateZigGotEntry(symbol_index, macho_file);