mirror of
https://github.com/ziglang/zig.git
synced 2026-02-12 20:37:54 +00:00
macho: when adding extern fn, check if already resolved
This way, we will generate valid relocation info in the codegen.
This commit is contained in:
parent
0395b35cee
commit
25416d8121
@ -2840,7 +2840,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
}
|
||||
} else if (func_value.castTag(.extern_fn)) |func_payload| {
|
||||
const decl = func_payload.data;
|
||||
const where_index = try macho_file.addExternFn(mem.spanZ(decl.name));
|
||||
const resolv = try macho_file.addExternFn(mem.spanZ(decl.name));
|
||||
const offset = blk: {
|
||||
switch (arch) {
|
||||
.x86_64 => {
|
||||
@ -2861,8 +2861,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
|
||||
// Add relocation to the decl.
|
||||
try macho_file.active_decl.?.link.macho.relocs.append(self.bin_file.allocator, .{
|
||||
.offset = offset,
|
||||
.where = .undef,
|
||||
.where_index = where_index,
|
||||
.where = switch (resolv.where) {
|
||||
.local => .local,
|
||||
.undef => .undef,
|
||||
},
|
||||
.where_index = resolv.where_index,
|
||||
.payload = .{ .branch = .{
|
||||
.arch = arch,
|
||||
} },
|
||||
|
||||
@ -4228,20 +4228,34 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, m
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
|
||||
const AddExternFnRes = struct {
|
||||
where: enum {
|
||||
local,
|
||||
undef,
|
||||
},
|
||||
where_index: u32,
|
||||
};
|
||||
|
||||
pub fn addExternFn(self: *MachO, name: []const u8) !AddExternFnRes {
|
||||
const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
|
||||
defer self.base.allocator.free(sym_name);
|
||||
const n_strx = try self.makeString(sym_name);
|
||||
|
||||
if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
|
||||
.bytes = &self.strtab,
|
||||
})) |n_strx| {
|
||||
const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
|
||||
return resolv.where_index;
|
||||
if (self.symbol_resolver.get(n_strx)) |resolv| {
|
||||
return switch (resolv.where) {
|
||||
.global => AddExternFnRes{
|
||||
.where = .local,
|
||||
.where_index = resolv.local_sym_index,
|
||||
},
|
||||
.undef => AddExternFnRes{
|
||||
.where = .undef,
|
||||
.where_index = resolv.where_index,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
log.debug("adding new extern function '{s}'", .{sym_name});
|
||||
const sym_index = @intCast(u32, self.undefs.items.len);
|
||||
const n_strx = try self.makeString(sym_name);
|
||||
try self.undefs.append(self.base.allocator, .{
|
||||
.n_strx = n_strx,
|
||||
.n_type = macho.N_UNDF,
|
||||
@ -4255,7 +4269,10 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
|
||||
});
|
||||
try self.unresolved.putNoClobber(self.base.allocator, sym_index, .stub);
|
||||
|
||||
return sym_index;
|
||||
return AddExternFnRes{
|
||||
.where = .undef,
|
||||
.where_index = sym_index,
|
||||
};
|
||||
}
|
||||
|
||||
const NextSegmentAddressAndOffset = struct {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user