mirror of
https://github.com/ziglang/zig.git
synced 2025-12-26 08:03:08 +00:00
x86_64: emit MachO TLV sequence
This commit is contained in:
parent
080ad94249
commit
5c4db4e578
@ -166,6 +166,8 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.zig_got_load
|
||||
else if (sym.flags.needs_got)
|
||||
.got_load
|
||||
else if (sym.flags.tlv)
|
||||
.tlv
|
||||
else
|
||||
.signed;
|
||||
try atom.addReloc(macho_file, .{
|
||||
@ -185,7 +187,6 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.linker_got,
|
||||
.linker_direct,
|
||||
.linker_import,
|
||||
.linker_tlv,
|
||||
=> |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |_| {
|
||||
unreachable;
|
||||
} else if (emit.lower.bin_file.cast(link.File.MachO)) |_| {
|
||||
|
||||
@ -62,7 +62,6 @@ pub const Reloc = struct {
|
||||
linker_got: bits.Symbol,
|
||||
linker_direct: bits.Symbol,
|
||||
linker_import: bits.Symbol,
|
||||
linker_tlv: bits.Symbol,
|
||||
};
|
||||
};
|
||||
|
||||
@ -428,7 +427,23 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
const macho_sym = macho_file.getSymbol(sym_index);
|
||||
|
||||
if (macho_sym.flags.tlv) {
|
||||
@panic("TODO lower TLS access on macOS");
|
||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .mov, &[_]Operand{
|
||||
.{ .reg = .rdi },
|
||||
.{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .call, &[_]Operand{
|
||||
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .rdi } }) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .rax },
|
||||
.disp = std.math.minInt(i32),
|
||||
}) };
|
||||
}
|
||||
|
||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||
@ -594,14 +609,13 @@ fn generic(lower: *Lower, inst: Mir.Inst) Error!void {
|
||||
.extern_fn_reloc => &.{
|
||||
.{ .imm = lower.reloc(.{ .linker_extern_fn = inst.data.reloc }) },
|
||||
},
|
||||
.got_reloc, .direct_reloc, .import_reloc, .tlv_reloc => ops: {
|
||||
.got_reloc, .direct_reloc, .import_reloc => ops: {
|
||||
const reg = inst.data.rx.r1;
|
||||
const extra = lower.mir.extraData(bits.Symbol, inst.data.rx.payload).data;
|
||||
_ = lower.reloc(switch (inst.ops) {
|
||||
.got_reloc => .{ .linker_got = extra },
|
||||
.direct_reloc => .{ .linker_direct = extra },
|
||||
.import_reloc => .{ .linker_import = extra },
|
||||
.tlv_reloc => .{ .linker_tlv = extra },
|
||||
else => unreachable,
|
||||
});
|
||||
break :ops &.{
|
||||
|
||||
@ -141,13 +141,23 @@ pub fn getAtomDataAlloc(self: ZigObject, macho_file: *MachO, atom: Atom) ![]u8 {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
assert(atom.file == self.index);
|
||||
const sect = macho_file.sections.items(.header)[atom.out_n_sect];
|
||||
const file_offset = sect.offset + atom.value - sect.addr;
|
||||
const size = std.math.cast(usize, atom.size) orelse return error.Overflow;
|
||||
const code = try gpa.alloc(u8, size);
|
||||
errdefer gpa.free(code);
|
||||
const amt = try macho_file.base.file.?.preadAll(code, file_offset);
|
||||
if (amt != code.len) return error.InputOutput;
|
||||
return code;
|
||||
|
||||
switch (sect.type()) {
|
||||
macho.S_THREAD_LOCAL_REGULAR => {
|
||||
const tlv = self.tls_variables.get(atom.atom_index).?;
|
||||
const code = try gpa.dupe(u8, tlv.code);
|
||||
return code;
|
||||
},
|
||||
else => {
|
||||
const file_offset = sect.offset + atom.value - sect.addr;
|
||||
const size = std.math.cast(usize, atom.size) orelse return error.Overflow;
|
||||
const code = try gpa.alloc(u8, size);
|
||||
errdefer gpa.free(code);
|
||||
const amt = try macho_file.base.file.?.preadAll(code, file_offset);
|
||||
if (amt != code.len) return error.InputOutput;
|
||||
return code;
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn getAtomRelocs(self: *ZigObject, atom: Atom) []const Relocation {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user