| author | |
| committer | |
| log | 5c4db4e5787eb534c8a83a6f7fc8f0fcfb1d01ef |
| tree | cf4fe1055583f61d85d2b750d9d6c03a16b2e536 |
| parent | 080ad94249101ed167c06761eebbaf1f5d47cfa9 |
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_load | 166 | .zig_got_load |
| 167 | else if (sym.flags.needs_got) | 167 | else if (sym.flags.needs_got) |
| 168 | .got_load | 168 | .got_load |
| 169 | else if (sym.flags.tlv) | ||
| 170 | .tlv | ||
| 169 | else | 171 | 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 | }; |
| 68 | 67 | ||
| ... | @@ -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); |
| 429 | 428 | ||
| 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 | } |
| 433 | 448 | ||
| 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 | } |
| 152 | 162 | ||
| 153 | pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation { | 163 | pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation { |