codegen: re-implement enough of codegen to error out instead panic
This commit is contained in:
@@ -139,10 +139,7 @@ const Owner = union(enum) {
|
||||
if (ctx.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
return elf_file.zigObjectPtr().?.getOrCreateMetadataForDecl(elf_file, decl_index);
|
||||
} else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
_ = macho_file;
|
||||
// const atom = try macho_file.getOrCreateAtomForDecl(decl_index);
|
||||
// return macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
@panic("TODO getSymbolIndex");
|
||||
return macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, decl_index);
|
||||
} else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
const atom = try coff_file.getOrCreateAtomForDecl(decl_index);
|
||||
return coff_file.getAtom(atom).getSymbolIndex().?;
|
||||
@@ -155,11 +152,8 @@ const Owner = union(enum) {
|
||||
return elf_file.zigObjectPtr().?.getOrCreateMetadataForLazySymbol(elf_file, lazy_sym) catch |err|
|
||||
ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
} else if (ctx.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
_ = macho_file;
|
||||
// const atom = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
|
||||
// return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
// return macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
@panic("TODO getSymbolIndex");
|
||||
return macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err|
|
||||
ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
} else if (ctx.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
const atom = coff_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
|
||||
return ctx.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
@@ -10955,12 +10949,10 @@ fn genCall(self: *Self, info: union(enum) {
|
||||
try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
|
||||
try self.asmRegister(.{ ._, .call }, .rax);
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
_ = macho_file;
|
||||
@panic("TODO genCall");
|
||||
// const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
|
||||
// const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
|
||||
// try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index });
|
||||
// try self.asmRegister(.{ ._, .call }, .rax);
|
||||
const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, func.owner_decl);
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
try self.genSetReg(.rax, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } });
|
||||
try self.asmRegister(.{ ._, .call }, .rax);
|
||||
} else if (self.bin_file.cast(link.File.Plan9)) |p9| {
|
||||
const atom_index = try p9.seeDecl(func.owner_decl);
|
||||
const atom = p9.getAtom(atom_index);
|
||||
@@ -13556,30 +13548,7 @@ fn genSetReg(self: *Self, dst_reg: Register, ty: Type, src_mcv: MCValue) InnerEr
|
||||
} },
|
||||
});
|
||||
},
|
||||
.lea_tlv => |sym_index| {
|
||||
const atom_index = try self.owner.getSymbolIndex(self);
|
||||
if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
_ = try self.addInst(.{
|
||||
.tag = .lea,
|
||||
.ops = .tlv_reloc,
|
||||
.data = .{ .rx = .{
|
||||
.r1 = .rdi,
|
||||
.payload = try self.addExtra(bits.Symbol{
|
||||
.atom_index = atom_index,
|
||||
.sym_index = sym_index,
|
||||
}),
|
||||
} },
|
||||
});
|
||||
// TODO: spill registers before calling
|
||||
try self.asmMemory(.{ ._, .call }, .{
|
||||
.base = .{ .reg = .rdi },
|
||||
.mod = .{ .rm = .{ .size = .qword } },
|
||||
});
|
||||
try self.genSetReg(dst_reg.to64(), Type.usize, .{ .register = .rax });
|
||||
} else return self.fail("TODO emit ptr to TLV sequence on {s}", .{
|
||||
@tagName(self.bin_file.tag),
|
||||
});
|
||||
},
|
||||
.lea_tlv => unreachable, // TODO: remove this
|
||||
.air_ref => |src_ref| try self.genSetReg(dst_reg, ty, try self.resolveInst(src_ref)),
|
||||
}
|
||||
}
|
||||
@@ -13816,19 +13785,14 @@ fn genExternSymbolRef(
|
||||
else => unreachable,
|
||||
}
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const global_index = try macho_file.getGlobalSymbol(callee, lib);
|
||||
_ = try self.addInst(.{
|
||||
.tag = .call,
|
||||
.ops = .extern_fn_reloc,
|
||||
.data = .{
|
||||
.reloc = .{
|
||||
.atom_index = atom_index,
|
||||
// .sym_index = link.File.MachO.global_symbol_bit | global_index,
|
||||
.sym_index = global_index,
|
||||
},
|
||||
},
|
||||
.data = .{ .reloc = .{
|
||||
.atom_index = atom_index,
|
||||
.sym_index = try macho_file.getGlobalSymbol(callee, lib),
|
||||
} },
|
||||
});
|
||||
@panic("TODO genExternSymbolRef");
|
||||
} else return self.fail("TODO implement calling extern functions", .{});
|
||||
}
|
||||
|
||||
@@ -13916,21 +13880,19 @@ fn genLazySymbolRef(
|
||||
else => unreachable,
|
||||
}
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
_ = macho_file;
|
||||
@panic("TODO genLazySymbolRef");
|
||||
// const atom_index = macho_file.getOrCreateAtomForLazySymbol(lazy_sym) catch |err|
|
||||
// return self.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
// const sym_index = macho_file.getAtom(atom_index).getSymbolIndex().?;
|
||||
// switch (tag) {
|
||||
// .lea, .call => try self.genSetReg(reg, Type.usize, .{ .lea_got = sym_index }),
|
||||
// .mov => try self.genSetReg(reg, Type.usize, .{ .load_got = sym_index }),
|
||||
// else => unreachable,
|
||||
// }
|
||||
// switch (tag) {
|
||||
// .lea, .mov => {},
|
||||
// .call => try self.asmRegister(.{ ._, .call }, reg),
|
||||
// else => unreachable,
|
||||
// }
|
||||
const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, lazy_sym) catch |err|
|
||||
return self.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
switch (tag) {
|
||||
.lea, .call => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }),
|
||||
.mov => try self.genSetReg(reg, Type.usize, .{ .load_symbol = .{ .sym = sym.nlist_idx } }),
|
||||
else => unreachable,
|
||||
}
|
||||
switch (tag) {
|
||||
.lea, .mov => {},
|
||||
.call => try self.asmRegister(.{ ._, .call }, reg),
|
||||
else => unreachable,
|
||||
}
|
||||
} else {
|
||||
return self.fail("TODO implement genLazySymbol for x86_64 {s}", .{@tagName(self.bin_file.tag)});
|
||||
}
|
||||
@@ -16103,6 +16065,8 @@ fn resolveInst(self: *Self, ref: Air.Inst.Ref) InnerError!MCValue {
|
||||
.{ .lea_symbol = .{ .sym = tlv_sym } },
|
||||
);
|
||||
break :init .{ .load_frame = .{ .index = frame_index } };
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |_| {
|
||||
return self.fail("TODO implement lowering TLV variable to stack", .{});
|
||||
} else break :init const_mcv,
|
||||
else => break :init const_mcv,
|
||||
}
|
||||
|
||||
@@ -49,23 +49,21 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.r_addend = -4,
|
||||
});
|
||||
} else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
_ = macho_file;
|
||||
@panic("TODO emitMir");
|
||||
// // Add relocation to the decl.
|
||||
// const atom_index =
|
||||
// macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
|
||||
// const target = if (link.File.MachO.global_symbol_bit & symbol.sym_index != 0)
|
||||
// macho_file.getGlobalByIndex(link.File.MachO.global_symbol_mask & symbol.sym_index)
|
||||
// else
|
||||
// link.File.MachO.SymbolWithLoc{ .sym_index = symbol.sym_index };
|
||||
// try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
|
||||
// .type = .branch,
|
||||
// .target = target,
|
||||
// .offset = end_offset - 4,
|
||||
// .addend = 0,
|
||||
// .pcrel = true,
|
||||
// .length = 2,
|
||||
// });
|
||||
// Add relocation to the decl.
|
||||
const atom = macho_file.getSymbol(symbol.atom_index).getAtom(macho_file).?;
|
||||
try atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = end_offset - 4,
|
||||
.target = symbol.sym_index,
|
||||
.addend = 0,
|
||||
.type = .branch,
|
||||
.meta = .{
|
||||
.pcrel = true,
|
||||
.has_subtractor = false,
|
||||
.length = 2,
|
||||
.symbolnum = 0,
|
||||
},
|
||||
});
|
||||
} else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
// Add relocation to the decl.
|
||||
const atom_index = coff_file.getAtomIndexForSymbol(
|
||||
@@ -151,6 +149,36 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const is_obj_or_static_lib = switch (emit.lower.output_mode) {
|
||||
.Exe => false,
|
||||
.Obj => true,
|
||||
.Lib => emit.lower.link_mode == .Static,
|
||||
};
|
||||
const atom = macho_file.getSymbol(data.atom_index).getAtom(macho_file).?;
|
||||
const sym = macho_file.getSymbol(data.sym_index);
|
||||
if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
|
||||
_ = try sym.getOrCreateZigGotEntry(data.sym_index, macho_file);
|
||||
}
|
||||
const @"type": link.File.MachO.Relocation.Type = if (sym.flags.needs_zig_got and !is_obj_or_static_lib)
|
||||
.zig_got_load
|
||||
else if (sym.flags.needs_got)
|
||||
.got_load
|
||||
else
|
||||
.signed;
|
||||
try atom.addReloc(macho_file, .{
|
||||
.tag = .@"extern",
|
||||
.offset = @intCast(end_offset - 4),
|
||||
.target = data.sym_index,
|
||||
.addend = 0,
|
||||
.type = @"type",
|
||||
.meta = .{
|
||||
.pcrel = true,
|
||||
.has_subtractor = false,
|
||||
.length = 2,
|
||||
.symbolnum = 0,
|
||||
},
|
||||
});
|
||||
} else unreachable,
|
||||
.linker_got,
|
||||
.linker_direct,
|
||||
@@ -158,28 +186,8 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
.linker_tlv,
|
||||
=> |symbol| if (emit.lower.bin_file.cast(link.File.Elf)) |_| {
|
||||
unreachable;
|
||||
} else if (emit.lower.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
_ = macho_file;
|
||||
@panic("TODO emitMir");
|
||||
// const atom_index =
|
||||
// macho_file.getAtomIndexForSymbol(.{ .sym_index = symbol.atom_index }).?;
|
||||
// const target = if (link.File.MachO.global_symbol_bit & symbol.sym_index != 0)
|
||||
// macho_file.getGlobalByIndex(link.File.MachO.global_symbol_mask & symbol.sym_index)
|
||||
// else
|
||||
// link.File.MachO.SymbolWithLoc{ .sym_index = symbol.sym_index };
|
||||
// try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
|
||||
// .type = switch (lowered_relocs[0].target) {
|
||||
// .linker_got => .got,
|
||||
// .linker_direct => .signed,
|
||||
// .linker_tlv => .tlv,
|
||||
// else => unreachable,
|
||||
// },
|
||||
// .target = target,
|
||||
// .offset = @intCast(end_offset - 4),
|
||||
// .addend = 0,
|
||||
// .pcrel = true,
|
||||
// .length = 2,
|
||||
// });
|
||||
} else if (emit.lower.bin_file.cast(link.File.MachO)) |_| {
|
||||
unreachable;
|
||||
} else if (emit.lower.bin_file.cast(link.File.Coff)) |coff_file| {
|
||||
const atom_index = coff_file.getAtomIndexForSymbol(.{
|
||||
.sym_index = symbol.atom_index,
|
||||
|
||||
@@ -14,7 +14,7 @@ result_relocs_len: u8 = undefined,
|
||||
result_insts: [
|
||||
std.mem.max(usize, &.{
|
||||
1, // non-pseudo instructions
|
||||
3, // TLS local dynamic (LD) sequence in PIC mode
|
||||
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
|
||||
2, // cmovcc: cmovcc \ cmovcc
|
||||
3, // setcc: setcc \ setcc \ logicop
|
||||
2, // jcc: jcc \ jcc
|
||||
@@ -32,7 +32,7 @@ result_relocs: [
|
||||
2, // jcc: jcc \ jcc
|
||||
2, // test \ jcc \ probe \ sub \ jmp
|
||||
1, // probe \ sub \ jcc
|
||||
3, // TLS local dynamic (LD) sequence in PIC mode
|
||||
3, // (ELF only) TLS local dynamic (LD) sequence in PIC mode
|
||||
})
|
||||
]Reloc = undefined,
|
||||
|
||||
@@ -326,18 +326,6 @@ fn reloc(lower: *Lower, target: Reloc.Target) Immediate {
|
||||
return Immediate.s(0);
|
||||
}
|
||||
|
||||
fn needsZigGot(sym: bits.Symbol, ctx: *link.File) bool {
|
||||
const elf_file = ctx.cast(link.File.Elf).?;
|
||||
const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
|
||||
return elf_file.symbol(sym_index).flags.needs_zig_got;
|
||||
}
|
||||
|
||||
fn isTls(sym: bits.Symbol, ctx: *link.File) bool {
|
||||
const elf_file = ctx.cast(link.File.Elf).?;
|
||||
const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
|
||||
return elf_file.symbol(sym_index).flags.is_tls;
|
||||
}
|
||||
|
||||
fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand) Error!void {
|
||||
const is_obj_or_static_lib = switch (lower.output_mode) {
|
||||
.Exe => false,
|
||||
@@ -359,80 +347,101 @@ fn emit(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operand)
|
||||
assert(mem_op.sib.disp == 0);
|
||||
assert(mem_op.sib.scale_index.scale == 0);
|
||||
|
||||
if (isTls(sym, lower.bin_file)) {
|
||||
// TODO handle extern TLS vars, i.e., emit GD model
|
||||
if (lower.pic) {
|
||||
// Here, we currently assume local dynamic TLS vars, and so
|
||||
// we emit LD model.
|
||||
_ = lower.reloc(.{ .linker_tlsld = sym });
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .lea, &[_]Operand{
|
||||
.{ .reg = .rdi },
|
||||
.{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
if (lower.bin_file.cast(link.File.Elf)) |elf_file| {
|
||||
const sym_index = elf_file.zigObjectPtr().?.symbol(sym.sym_index);
|
||||
const elf_sym = elf_file.symbol(sym_index);
|
||||
|
||||
if (elf_sym.flags.is_tls) {
|
||||
// TODO handle extern TLS vars, i.e., emit GD model
|
||||
if (lower.pic) {
|
||||
// Here, we currently assume local dynamic TLS vars, and so
|
||||
// we emit LD model.
|
||||
_ = lower.reloc(.{ .linker_tlsld = sym });
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .lea, &[_]Operand{
|
||||
.{ .reg = .rdi },
|
||||
.{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
_ = lower.reloc(.{ .linker_extern_fn = .{
|
||||
.atom_index = sym.atom_index,
|
||||
.sym_index = try elf_file.getGlobalSymbol("__tls_get_addr", null),
|
||||
} });
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .call, &[_]Operand{
|
||||
.{ .imm = Immediate.s(0) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
_ = lower.reloc(.{ .linker_dtpoff = sym });
|
||||
emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .rax },
|
||||
.disp = std.math.minInt(i32),
|
||||
}) };
|
||||
} else {
|
||||
// Since we are linking statically, we emit LE model directly.
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .mov, &[_]Operand{
|
||||
.{ .reg = .rax },
|
||||
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .fs } }) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||
emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .rax },
|
||||
.disp = std.math.minInt(i32),
|
||||
}) };
|
||||
}
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .call, &[_]Operand{
|
||||
.{ .imm = Immediate.s(0) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
_ = lower.reloc(.{ .linker_dtpoff = sym });
|
||||
emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .rax },
|
||||
.disp = std.math.minInt(i32),
|
||||
}) };
|
||||
} else {
|
||||
// Since we are linking statically, we emit LE model directly.
|
||||
lower.result_insts[lower.result_insts_len] =
|
||||
try Instruction.new(.none, .mov, &[_]Operand{
|
||||
.{ .reg = .rax },
|
||||
.{ .mem = Memory.sib(.qword, .{ .base = .{ .reg = .fs } }) },
|
||||
});
|
||||
lower.result_insts_len += 1;
|
||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||
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 });
|
||||
break :op if (lower.pic) switch (mnemonic) {
|
||||
.lea => {
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
.mov => {
|
||||
if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
else => unreachable,
|
||||
} else switch (mnemonic) {
|
||||
.call => break :op if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) .{
|
||||
.imm = Immediate.s(0),
|
||||
} else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .ds },
|
||||
}) },
|
||||
.lea => {
|
||||
emit_mnemonic = .mov;
|
||||
break :op .{ .imm = Immediate.s(0) };
|
||||
},
|
||||
.mov => {
|
||||
if (is_obj_or_static_lib and needsZigGot(sym, lower.bin_file)) emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||
break :op if (lower.pic) switch (mnemonic) {
|
||||
.lea => {
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
.mov => {
|
||||
if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
else => unreachable,
|
||||
} else switch (mnemonic) {
|
||||
.call => break :op if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) .{
|
||||
.imm = Immediate.s(0),
|
||||
} else .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .ds },
|
||||
}) };
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
}) },
|
||||
.lea => {
|
||||
emit_mnemonic = .mov;
|
||||
break :op .{ .imm = Immediate.s(0) };
|
||||
},
|
||||
.mov => {
|
||||
if (is_obj_or_static_lib and elf_sym.flags.needs_zig_got) emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.sib(mem_op.sib.ptr_size, .{
|
||||
.base = .{ .reg = .ds },
|
||||
}) };
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
} else if (lower.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const macho_sym = macho_file.getSymbol(sym.sym_index);
|
||||
|
||||
if (macho_sym.flags.tlv) {
|
||||
@panic("TODO lower TLS access on macOS");
|
||||
}
|
||||
|
||||
_ = lower.reloc(.{ .linker_reloc = sym });
|
||||
break :op switch (mnemonic) {
|
||||
.lea => {
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
.mov => {
|
||||
if (is_obj_or_static_lib and macho_sym.flags.needs_zig_got) emit_mnemonic = .lea;
|
||||
break :op .{ .mem = Memory.rip(mem_op.sib.ptr_size, 0) };
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1045,7 +1045,12 @@ fn genUnnamedConst(
|
||||
const local = elf_file.symbol(local_sym_index);
|
||||
return GenResult.mcv(.{ .load_symbol = local.esym_index });
|
||||
},
|
||||
.macho, .coff => {
|
||||
.macho => {
|
||||
const macho_file = lf.cast(link.File.MachO).?;
|
||||
const local = macho_file.getSymbol(local_sym_index);
|
||||
return GenResult.mcv(.{ .load_symbol = local.nlist_idx });
|
||||
},
|
||||
.coff => {
|
||||
return GenResult.mcv(.{ .load_direct = local_sym_index });
|
||||
},
|
||||
.plan9 => {
|
||||
|
||||
@@ -4280,7 +4280,7 @@ const Md5 = std.crypto.hash.Md5;
|
||||
const Module = @import("../Module.zig");
|
||||
const InternPool = @import("../InternPool.zig");
|
||||
const RebaseSection = synthetic.RebaseSection;
|
||||
const Relocation = @import("MachO/Relocation.zig");
|
||||
pub const Relocation = @import("MachO/Relocation.zig");
|
||||
const StringTable = @import("StringTable.zig");
|
||||
const StubsSection = synthetic.StubsSection;
|
||||
const StubsHelperSection = synthetic.StubsHelperSection;
|
||||
|
||||
@@ -686,6 +686,10 @@ fn resolveRelocInner(
|
||||
}
|
||||
},
|
||||
|
||||
.zig_got_load => {
|
||||
@panic("TODO resolve __got_zig indirection reloc");
|
||||
},
|
||||
|
||||
.tlv => {
|
||||
assert(rel.tag == .@"extern");
|
||||
assert(rel.meta.length == 2);
|
||||
@@ -987,6 +991,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: *std.Arra
|
||||
.subtractor => .ARM64_RELOC_SUBTRACTOR,
|
||||
.unsigned => .ARM64_RELOC_UNSIGNED,
|
||||
|
||||
.zig_got_load,
|
||||
.signed,
|
||||
.signed1,
|
||||
.signed2,
|
||||
@@ -1030,6 +1035,7 @@ pub fn writeRelocs(self: Atom, macho_file: *MachO, code: []u8, buffer: *std.Arra
|
||||
.subtractor => .X86_64_RELOC_SUBTRACTOR,
|
||||
.unsigned => .X86_64_RELOC_UNSIGNED,
|
||||
|
||||
.zig_got_load,
|
||||
.page,
|
||||
.pageoff,
|
||||
.got_load_page,
|
||||
|
||||
@@ -99,6 +99,8 @@ pub const Type = enum {
|
||||
got_load,
|
||||
/// RIP-relative TLV load (X86_64_RELOC_TLV)
|
||||
tlv,
|
||||
/// Zig-specific __got_zig indirection
|
||||
zig_got_load,
|
||||
|
||||
// arm64
|
||||
/// PC-relative load (distance to page, ARM64_RELOC_PAGE21)
|
||||
|
||||
@@ -248,7 +248,7 @@ pub fn getDeclVAddr(
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 3,
|
||||
.symbolnum = @intCast(sym.nlist_idx),
|
||||
.symbolnum = 0,
|
||||
},
|
||||
});
|
||||
return vaddr;
|
||||
@@ -274,7 +274,7 @@ pub fn getAnonDeclVAddr(
|
||||
.pcrel = false,
|
||||
.has_subtractor = false,
|
||||
.length = 3,
|
||||
.symbolnum = @intCast(sym.nlist_idx),
|
||||
.symbolnum = 0,
|
||||
},
|
||||
});
|
||||
return vaddr;
|
||||
@@ -604,25 +604,26 @@ fn getDeclOutputSection(
|
||||
_ = self;
|
||||
const mod = macho_file.base.comp.module.?;
|
||||
const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
|
||||
_ = any_non_single_threaded;
|
||||
const sect_id: u8 = switch (decl.ty.zigTypeTag(mod)) {
|
||||
.Fn => macho_file.zig_text_section_index.?,
|
||||
else => blk: {
|
||||
if (decl.getOwnedVariable(mod)) |variable| {
|
||||
if (variable.is_threadlocal and any_non_single_threaded) {
|
||||
const is_all_zeroes = for (code) |byte| {
|
||||
if (byte != 0) break false;
|
||||
} else true;
|
||||
if (is_all_zeroes) break :blk macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
|
||||
"__DATA",
|
||||
"__thread_bss",
|
||||
.{ .flags = macho.S_THREAD_LOCAL_ZEROFILL },
|
||||
);
|
||||
break :blk macho_file.getSectionByName("__DATA", "__thread_data") orelse try macho_file.addSection(
|
||||
"__DATA",
|
||||
"__thread_data",
|
||||
.{ .flags = macho.S_THREAD_LOCAL_REGULAR },
|
||||
);
|
||||
}
|
||||
// if (variable.is_threadlocal and any_non_single_threaded) {
|
||||
// const is_all_zeroes = for (code) |byte| {
|
||||
// if (byte != 0) break false;
|
||||
// } else true;
|
||||
// if (is_all_zeroes) break :blk macho_file.getSectionByName("__DATA", "__thread_bss") orelse try macho_file.addSection(
|
||||
// "__DATA",
|
||||
// "__thread_bss",
|
||||
// .{ .flags = macho.S_THREAD_LOCAL_ZEROFILL },
|
||||
// );
|
||||
// break :blk macho_file.getSectionByName("__DATA", "__thread_data") orelse try macho_file.addSection(
|
||||
// "__DATA",
|
||||
// "__thread_data",
|
||||
// .{ .flags = macho.S_THREAD_LOCAL_REGULAR },
|
||||
// );
|
||||
// }
|
||||
|
||||
if (variable.is_const) break :blk macho_file.zig_const_section_index.?;
|
||||
if (Value.fromInterned(variable.init).isUndefDeep(mod)) {
|
||||
@@ -917,7 +918,7 @@ fn updateLazySymbol(
|
||||
|
||||
sym.value = 0;
|
||||
sym.flags.needs_zig_got = true;
|
||||
nlist.st_value = 0;
|
||||
nlist.n_value = 0;
|
||||
|
||||
if (!macho_file.base.isRelocatable()) {
|
||||
const gop = try sym.getOrCreateZigGotEntry(symbol_index, macho_file);
|
||||
|
||||
Reference in New Issue
Block a user