authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-20 22:31:50+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:42+01:00
log5c4db4e5787eb534c8a83a6f7fc8f0fcfb1d01ef
treecf4fe1055583f61d85d2b750d9d6c03a16b2e536
parent080ad94249101ed167c06761eebbaf1f5d47cfa9

x86_64: emit MachO TLV sequence


3 files changed, 37 insertions(+), 12 deletions(-)

src/arch/x86_64/Emit.zig+2-1
...@@ -166,6 +166,8 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -166,6 +166,8 @@ pub fn emitMir(emit: *Emit) Error!void {
166 .zig_got_load166 .zig_got_load
167 else if (sym.flags.needs_got)167 else if (sym.flags.needs_got)
168 .got_load168 .got_load
169 else if (sym.flags.tlv)
170 .tlv
169 else171 else
170 .signed;172 .signed;
171 try atom.addReloc(macho_file, .{173 try atom.addReloc(macho_file, .{
...@@ -185,7 +187,6 @@ pub fn emitMir(emit: *Emit) Error!void {...@@ -185,7 +187,6 @@ pub fn emitMir(emit: *Emit) Error!void {
185 .linker_got,187 .linker_got,
186 .linker_direct,188 .linker_direct,
187 .linker_import,189 .linker_import,
188 .linker_tlv,
189 => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |_| {190 => |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |_| {
190 unreachable;191 unreachable;
191 } else if (emit.lower.bin_file.cast(link.File.MachO)) |_| {192 } else if (emit.lower.bin_file.cast(link.File.MachO)) |_| {
src/arch/x86_64/Lower.zig+18-4
...@@ -62,7 +62,6 @@ pub const Reloc = struct {...@@ -62,7 +62,6 @@ pub const Reloc = struct {
62 linker_got: bits.Symbol,62 linker_got: bits.Symbol,
63 linker_direct: bits.Symbol,63 linker_direct: bits.Symbol,
64 linker_import: bits.Symbol,64 linker_import: bits.Symbol,
65 linker_tlv: bits.Symbol,
66 };65 };
67};66};
6867
...@@ -428,7 +427,23 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)...@@ -428,7 +427,23 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
428 const macho_sym = macho_file.getSymbol(sym_index);427 const macho_sym = macho_file.getSymbol(sym_index);
429428
430 if (macho_sym.flags.tlv) {429 if (macho_sym.flags.tlv) {
431 @panic("TODO lower TLS access on macOS");430 _ = lower.reloc(.{ .linker_reloc = sym });
431 lower.result_insts[lower.result_insts_len] =
432 try Instruction.new(.none, .mov, &[_]Operand{
433 .{ .reg = .rdi },
434 .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
435 });
436 lower.result_insts_len += 1;
437 lower.result_insts[lower.result_insts_len] =
438 try Instruction.new(.none, .call, &[_]Operand{
439 .{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .rdi } }) },
440 });
441 lower.result_insts_len += 1;
442 emit_mnemonic = .lea;
443 break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
444 .base = .{ .reg = .rax },
445 .disp = std.math.minInt(i32),
446 }) };
432 }447 }
433448
434 _ = lower.reloc(.{ .linker_reloc = sym });449 _ = lower.reloc(.{ .linker_reloc = sym });
...@@ -594,14 +609,13 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {...@@ -594,14 +609,13 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
594 .extern_fn_reloc => &.{609 .extern_fn_reloc => &.{
595 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },610 .{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },
596 },611 },
597 .got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {612 .got_reloc, .direct_reloc, .import_reloc => ops: {
598 const reg = inst.data.rx.r1;613 const reg = inst.data.rx.r1;
599 const extra = lower.mir.extraData(bits.Symbol, inst.data.rx.payload).data;614 const extra = lower.mir.extraData(bits.Symbol, inst.data.rx.payload).data;
600 _ = lower.reloc(switch (inst.ops) {615 _ = lower.reloc(switch (inst.ops) {
601 .got_reloc => .{ .linker_got = extra },616 .got_reloc => .{ .linker_got = extra },
602 .direct_reloc => .{ .linker_direct = extra },617 .direct_reloc => .{ .linker_direct = extra },
603 .import_reloc => .{ .linker_import = extra },618 .import_reloc => .{ .linker_import = extra },
604 .tlv_reloc => .{ .linker_tlv = extra },
605 else => unreachable,619 else => unreachable,
606 });620 });
607 break :ops &.{621 break :ops &.{
src/link/MachO/ZigObject.zig+17-7
...@@ -141,13 +141,23 @@ pub fn getAtomDataAlloc(self: ZigObject, macho_file: *MachO, atom: Atom) ![]u8 {...@@ -141,13 +141,23 @@ pub fn getAtomDataAlloc(self: ZigObject, macho_file: *MachO, atom: Atom) ![]u8 {
141 const gpa = macho_file.base.comp.gpa;141 const gpa = macho_file.base.comp.gpa;
142 assert(atom.file == self.index);142 assert(atom.file == self.index);
143 const sect = macho_file.sections.items(.header)[atom.out_n_sect];143 const sect = macho_file.sections.items(.header)[atom.out_n_sect];
144 const file_offset = sect.offset + atom.value - sect.addr;144
145 const size = std.math.cast(usize, atom.size) orelse return error.Overflow;145 switch (sect.type()) {
146 const code = try gpa.alloc(u8, size);146 macho.S_THREAD_LOCAL_REGULAR => {
147 errdefer gpa.free(code);147 const tlv = self.tls_variables.get(atom.atom_index).?;
148 const amt = try macho_file.base.file.?.preadAll(code, file_offset);148 const code = try gpa.dupe(u8, tlv.code);
149 if (amt != code.len) return error.InputOutput;149 return code;
150 return code;150 },
151 else => {
152 const file_offset = sect.offset + atom.value - sect.addr;
153 const size = std.math.cast(usize, atom.size) orelse return error.Overflow;
154 const code = try gpa.alloc(u8, size);
155 errdefer gpa.free(code);
156 const amt = try macho_file.base.file.?.preadAll(code, file_offset);
157 if (amt != code.len) return error.InputOutput;
158 return code;
159 },
160 }
151}161}
152162
153pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation {163pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation {