Skip to content

Commit

Permalink
Merge pull request #21065 from ziglang/elf-zig-got
Browse files Browse the repository at this point in the history
elf: replace .got.zig with a zig jump table
  • Loading branch information
kubkon authored Aug 16, 2024
2 parents f1eed99 + 73f385e commit 90989be
Show file tree
Hide file tree
Showing 27 changed files with 488 additions and 787 deletions.
2 changes: 1 addition & 1 deletion src/Builtin.zig
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ pub fn append(opts: @This(), buffer: *std.ArrayList(u8)) Allocator.Error!void {

if (opts.is_test) {
try buffer.appendSlice(
\\pub var test_functions: []const std.builtin.TestFn = undefined; // overwritten later
\\pub var test_functions: []const std.builtin.TestFn = &.{}; // overwritten later
\\
);
}
Expand Down
7 changes: 7 additions & 0 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3092,6 +3092,10 @@ pub fn totalErrorCount(comp: *Compilation) u32 {
if (zcu.intern_pool.global_error_set.getNamesFromMainThread().len > zcu.error_limit) {
total += 1;
}

for (zcu.failed_codegen.keys()) |_| {
total += 1;
}
}

// The "no entry point found" error only counts if there are no semantic analysis errors.
Expand Down Expand Up @@ -3237,6 +3241,9 @@ pub fn getAllErrorsAlloc(comp: *Compilation) !ErrorBundle {
}
}
}
for (zcu.failed_codegen.values()) |error_msg| {
try addModuleErrorMsg(zcu, &bundle, error_msg.*, &all_references);
}
for (zcu.failed_exports.values()) |value| {
try addModuleErrorMsg(zcu, &bundle, value.*, &all_references);
}
Expand Down
41 changes: 7 additions & 34 deletions src/arch/aarch64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4352,24 +4352,10 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
// on linking.
if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
.func => |func| {
if (self.bin_file.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;
const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
const sym = zo.symbol(sym_index);
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));
try self.genSetReg(Type.usize, .x30, .{ .memory = got_addr });
} else if (self.bin_file.cast(.macho)) |macho_file| {
_ = macho_file;
@panic("TODO airCall");
// const atom = try macho_file.getOrCreateAtomForNav(func.owner_nav);
// const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
// try self.genSetReg(Type.u64, .x30, .{
// .linker_load = .{
// .type = .got,
// .sym_index = sym_index,
// },
// });
if (self.bin_file.cast(.elf)) |_| {
return self.fail("TODO implement calling functions for Elf", .{});
} else if (self.bin_file.cast(.macho)) |_| {
return self.fail("TODO implement calling functions for MachO", .{});
} else if (self.bin_file.cast(.coff)) |coff_file| {
const atom = try coff_file.getOrCreateAtomForNav(func.owner_nav);
const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
Expand All @@ -4393,21 +4379,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
.@"extern" => |@"extern"| {
const nav_name = ip.getNav(@"extern".owner_nav).name.toSlice(ip);
const lib_name = @"extern".lib_name.toSlice(ip);
if (self.bin_file.cast(.macho)) |macho_file| {
_ = macho_file;
@panic("TODO airCall");
// const sym_index = try macho_file.getGlobalSymbol(nav_name, lib_name);
// const atom = try macho_file.getOrCreateAtomForNav(self.owner_nav);
// const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
// _ = try self.addInst(.{
// .tag = .call_extern,
// .data = .{
// .relocation = .{
// .atom_index = atom_index,
// .sym_index = sym_index,
// },
// },
// });
if (self.bin_file.cast(.macho)) |_| {
return self.fail("TODO implement calling extern functions for MachO", .{});
} else if (self.bin_file.cast(.coff)) |coff_file| {
const sym_index = try coff_file.getGlobalSymbol(nav_name, lib_name);
try self.genSetReg(Type.u64, .x30, .{
Expand Down Expand Up @@ -6234,7 +6207,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
.memory => |addr| .{ .memory = addr },
.load_got => |sym_index| .{ .linker_load = .{ .type = .got, .sym_index = sym_index } },
.load_direct => |sym_index| .{ .linker_load = .{ .type = .direct, .sym_index = sym_index } },
.load_symbol, .load_tlv => unreachable, // TODO
.load_symbol, .load_tlv, .lea_symbol => unreachable, // TODO
},
.fail => |msg| {
self.err_msg = msg;
Expand Down
20 changes: 3 additions & 17 deletions src/arch/arm/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4333,22 +4333,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
// Due to incremental compilation, how function calls are generated depends
// on linking.
if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
.func => |func| {
if (self.bin_file.cast(.elf)) |elf_file| {
const zo = elf_file.zigObjectPtr().?;
const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
const sym = zo.symbol(sym_index);
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
const got_addr: u32 = @intCast(sym.zigGotAddress(elf_file));
try self.genSetReg(Type.usize, .lr, .{ .memory = got_addr });
} else if (self.bin_file.cast(.macho)) |_| {
unreachable; // unsupported architecture for MachO
} else {
return self.fail("TODO implement call on {s} for {s}", .{
@tagName(self.bin_file.tag),
@tagName(self.target.cpu.arch),
});
}
.func => {
return self.fail("TODO implement calling functions", .{});
},
.@"extern" => {
return self.fail("TODO implement calling extern functions", .{});
Expand Down Expand Up @@ -6184,7 +6170,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
.mcv => |mcv| switch (mcv) {
.none => .none,
.undef => .undef,
.load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO
.load_got, .load_symbol, .load_direct, .load_tlv, .lea_symbol => unreachable, // TODO
.immediate => |imm| .{ .immediate = @truncate(imm) },
.memory => |addr| .{ .memory = addr },
},
Expand Down
11 changes: 6 additions & 5 deletions src/arch/riscv64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4937,7 +4937,7 @@ fn genCall(
if (func.mod.pic) {
return func.fail("TODO: genCall pic", .{});
} else {
try func.genSetReg(Type.u64, .ra, .{ .load_symbol = .{ .sym = sym_index } });
try func.genSetReg(Type.u64, .ra, .{ .lea_symbol = .{ .sym = sym_index } });
_ = try func.addInst(.{
.tag = .jalr,
.data = .{ .i_type = .{
Expand Down Expand Up @@ -6120,7 +6120,7 @@ fn airAsm(func: *Func, inst: Air.Inst.Index) !void {
arg_map.get(op_str["%[".len .. mod_index orelse op_str.len - "]".len]) orelse
return func.fail("no matching constraint: '{s}'", .{op_str})
]) {
.load_symbol => |sym_off| if (mem.eql(u8, modifier, "plt")) blk: {
.lea_symbol => |sym_off| if (mem.eql(u8, modifier, "plt")) blk: {
assert(sym_off.off == 0);
break :blk .{ .sym = sym_off };
} else return func.fail("invalid modifier: '{s}'", .{modifier}),
Expand Down Expand Up @@ -6388,7 +6388,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
ty,
src_mcv,
),
.load_tlv => {
.load_symbol, .load_tlv => {
const addr_reg, const addr_lock = try func.allocReg(.int);
defer func.register_manager.unlockReg(addr_lock);

Expand Down Expand Up @@ -6433,7 +6433,7 @@ fn genCopy(func: *Func, ty: Type, dst_mcv: MCValue, src_mcv: MCValue) !void {
part_disp += @intCast(dst_ty.abiSize(func.pt));
}
},
else => return func.fail("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }),
else => return std.debug.panic("TODO: genCopy to {s} from {s}", .{ @tagName(dst_mcv), @tagName(src_mcv) }),
}
}

Expand Down Expand Up @@ -6594,7 +6594,7 @@ fn genInlineMemset(
.tag = .beq,
.data = .{
.b_type = .{
.inst = @intCast(func.mir_instructions.len + 4), // points after the last inst
.inst = @intCast(func.mir_instructions.len + 3), // points after the last inst
.rs1 = count,
.rs2 = .zero,
},
Expand Down Expand Up @@ -8026,6 +8026,7 @@ fn genTypedValue(func: *Func, val: Value) InnerError!MCValue {
.mcv => |mcv| switch (mcv) {
.none => .none,
.undef => unreachable,
.lea_symbol => |sym_index| .{ .lea_symbol = .{ .sym = sym_index } },
.load_symbol => |sym_index| .{ .load_symbol = .{ .sym = sym_index } },
.load_tlv => |sym_index| .{ .lea_tlv = sym_index },
.immediate => |imm| .{ .immediate = imm },
Expand Down
22 changes: 5 additions & 17 deletions src/arch/riscv64/Emit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -43,31 +43,19 @@ pub fn emitMir(emit: *Emit) Error!void {
.fmt = std.meta.activeTag(lowered_inst),
}),
.load_symbol_reloc => |symbol| {
const is_obj_or_static_lib = switch (emit.lower.output_mode) {
.Exe => false,
.Obj => true,
.Lib => emit.lower.link_mode == .static,
};

const elf_file = emit.bin_file.cast(.elf).?;
const zo = elf_file.zigObjectPtr().?;

const atom_ptr = zo.symbol(symbol.atom_index).atom(elf_file).?;
const sym = zo.symbol(symbol.sym_index);

var hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
var lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);

if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
_ = try sym.getOrCreateZigGotEntry(symbol.sym_index, elf_file);

hi_r_type = Elf.R_ZIG_GOT_HI20;
lo_r_type = Elf.R_ZIG_GOT_LO12;
} else if (sym.flags.needs_got) {
hi_r_type = Elf.R_GOT_HI20_STATIC; // TODO: rework this #20887
lo_r_type = Elf.R_GOT_LO12_I_STATIC; // TODO: rework this #20887
if (sym.flags.is_extern_ptr and emit.lower.pic) {
return emit.fail("emit GOT relocation for symbol '{s}'", .{sym.name(elf_file)});
}

const hi_r_type: u32 = @intFromEnum(std.elf.R_RISCV.HI20);
const lo_r_type: u32 = @intFromEnum(std.elf.R_RISCV.LO12_I);

try atom_ptr.addReloc(elf_file, .{
.r_offset = start_offset,
.r_info = (@as(u64, @intCast(symbol.sym_index)) << 32) | hi_r_type,
Expand Down
32 changes: 3 additions & 29 deletions src/arch/sparc64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1349,34 +1349,8 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
// Due to incremental compilation, how function calls are generated depends
// on linking.
if (try self.air.value(callee, pt)) |func_value| switch (ip.indexToKey(func_value.toIntern())) {
.func => |func| {
const got_addr = if (self.bin_file.cast(.elf)) |elf_file| blk: {
const zo = elf_file.zigObjectPtr().?;
const sym_index = try zo.getOrCreateMetadataForNav(elf_file, func.owner_nav);
const sym = zo.symbol(sym_index);
_ = try sym.getOrCreateZigGotEntry(sym_index, elf_file);
break :blk @as(u32, @intCast(sym.zigGotAddress(elf_file)));
} else @panic("TODO SPARCv9 currently does not support non-ELF binaries");

try self.genSetReg(Type.usize, .o7, .{ .memory = got_addr });

_ = try self.addInst(.{
.tag = .jmpl,
.data = .{
.arithmetic_3op = .{
.is_imm = false,
.rd = .o7,
.rs1 = .o7,
.rs2_or_imm = .{ .rs2 = .g0 },
},
},
});

// TODO Find a way to fill this delay slot
_ = try self.addInst(.{
.tag = .nop,
.data = .{ .nop = {} },
});
.func => {
return self.fail("TODO implement calling functions", .{});
},
.@"extern" => {
return self.fail("TODO implement calling extern functions", .{});
Expand Down Expand Up @@ -4153,7 +4127,7 @@ fn genTypedValue(self: *Self, val: Value) InnerError!MCValue {
.mcv => |mcv| switch (mcv) {
.none => .none,
.undef => .undef,
.load_got, .load_symbol, .load_direct, .load_tlv => unreachable, // TODO
.load_got, .load_symbol, .load_direct, .load_tlv, .lea_symbol => unreachable, // TODO
.immediate => |imm| .{ .immediate = imm },
.memory => |addr| .{ .memory = addr },
},
Expand Down
Loading

0 comments on commit 90989be

Please sign in to comment.