authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-15 13:15:15+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-15 16:51:56+02:00
log25416d8121d14ec6a2a94943cfa4e2fb944e215b
treeb257177adba5bf20807c6f687e96d2da91bcdf82
parent0395b35cee8d4082cc40b0dcd0298f797f42309d

macho: when adding extern fn, check if already resolved

This way, we will generate valid relocation info in the codegen.

2 files changed, 31 insertions(+), 11 deletions(-)

src/codegen.zig+6-3
......@@ -2840,7 +2840,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28402840 }
28412841 } else if (func_value.castTag(.extern_fn)) |func_payload| {
28422842 const decl = func_payload.data;
2843 const where_index = try macho_file.addExternFn(mem.spanZ(decl.name));
2843 const resolv = try macho_file.addExternFn(mem.spanZ(decl.name));
28442844 const offset = blk: {
28452845 switch (arch) {
28462846 .x86_64 => {
......@@ -2861,8 +2861,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
28612861 // Add relocation to the decl.
28622862 try macho_file.active_decl.?.link.macho.relocs.append(self.bin_file.allocator, .{
28632863 .offset = offset,
2864 .where = .undef,
2865 .where_index = where_index,
2864 .where = switch (resolv.where) {
2865 .local => .local,
2866 .undef => .undef,
2867 },
2868 .where_index = resolv.where_index,
28662869 .payload = .{ .branch = .{
28672870 .arch = arch,
28682871 } },
src/link/MachO.zig+25-8
......@@ -4228,20 +4228,34 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, m
42284228 return vaddr;
42294229}
42304230
4231pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
4231const AddExternFnRes = struct {
4232 where: enum {
4233 local,
4234 undef,
4235 },
4236 where_index: u32,
4237};
4238
4239pub fn addExternFn(self: *MachO, name: []const u8) !AddExternFnRes {
42324240 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
42334241 defer self.base.allocator.free(sym_name);
4242 const n_strx = try self.makeString(sym_name);
42344243
4235 if (self.strtab_dir.getKeyAdapted(@as([]const u8, sym_name), StringIndexAdapter{
4236 .bytes = &self.strtab,
4237 })) |n_strx| {
4238 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;
4239 return resolv.where_index;
4244 if (self.symbol_resolver.get(n_strx)) |resolv| {
4245 return switch (resolv.where) {
4246 .global => AddExternFnRes{
4247 .where = .local,
4248 .where_index = resolv.local_sym_index,
4249 },
4250 .undef => AddExternFnRes{
4251 .where = .undef,
4252 .where_index = resolv.where_index,
4253 },
4254 };
42404255 }
42414256
42424257 log.debug("adding new extern function '{s}'", .{sym_name});
42434258 const sym_index = @intCast(u32, self.undefs.items.len);
4244 const n_strx = try self.makeString(sym_name);
42454259 try self.undefs.append(self.base.allocator, .{
42464260 .n_strx = n_strx,
42474261 .n_type = macho.N_UNDF,
......@@ -4255,7 +4269,10 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
42554269 });
42564270 try self.unresolved.putNoClobber(self.base.allocator, sym_index, .stub);
42574271
4258 return sym_index;
4272 return AddExternFnRes{
4273 .where = .undef,
4274 .where_index = sym_index,
4275 };
42594276}
42604277
42614278const NextSegmentAddressAndOffset = struct {