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 {...@@ -2840,7 +2840,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2840 }2840 }
2841 } else if (func_value.castTag(.extern_fn)) |func_payload| {2841 } else if (func_value.castTag(.extern_fn)) |func_payload| {
2842 const decl = func_payload.data;2842 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));
2844 const offset = blk: {2844 const offset = blk: {
2845 switch (arch) {2845 switch (arch) {
2846 .x86_64 => {2846 .x86_64 => {
...@@ -2861,8 +2861,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2861,8 +2861,11 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2861 // Add relocation to the decl.2861 // Add relocation to the decl.
2862 try macho_file.active_decl.?.link.macho.relocs.append(self.bin_file.allocator, .{2862 try macho_file.active_decl.?.link.macho.relocs.append(self.bin_file.allocator, .{
2863 .offset = offset,2863 .offset = offset,
2864 .where = .undef,2864 .where = switch (resolv.where) {
2865 .where_index = where_index,2865 .local => .local,
2866 .undef => .undef,
2867 },
2868 .where_index = resolv.where_index,
2866 .payload = .{ .branch = .{2869 .payload = .{ .branch = .{
2867 .arch = arch,2870 .arch = arch,
2868 } },2871 } },
src/link/MachO.zig+25-8
...@@ -4228,20 +4228,34 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, m...@@ -4228,20 +4228,34 @@ fn allocateAtom(self: *MachO, atom: *Atom, new_atom_size: u64, alignment: u64, m
4228 return vaddr;4228 return vaddr;
4229}4229}
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 {
4232 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});4240 const sym_name = try std.fmt.allocPrint(self.base.allocator, "_{s}", .{name});
4233 defer self.base.allocator.free(sym_name);4241 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{4244 if (self.symbol_resolver.get(n_strx)) |resolv| {
4236 .bytes = &self.strtab,4245 return switch (resolv.where) {
4237 })) |n_strx| {4246 .global => AddExternFnRes{
4238 const resolv = self.symbol_resolver.get(n_strx) orelse unreachable;4247 .where = .local,
4239 return resolv.where_index;4248 .where_index = resolv.local_sym_index,
4249 },
4250 .undef => AddExternFnRes{
4251 .where = .undef,
4252 .where_index = resolv.where_index,
4253 },
4254 };
4240 }4255 }
42414256
4242 log.debug("adding new extern function '{s}'", .{sym_name});4257 log.debug("adding new extern function '{s}'", .{sym_name});
4243 const sym_index = @intCast(u32, self.undefs.items.len);4258 const sym_index = @intCast(u32, self.undefs.items.len);
4244 const n_strx = try self.makeString(sym_name);
4245 try self.undefs.append(self.base.allocator, .{4259 try self.undefs.append(self.base.allocator, .{
4246 .n_strx = n_strx,4260 .n_strx = n_strx,
4247 .n_type = macho.N_UNDF,4261 .n_type = macho.N_UNDF,
...@@ -4255,7 +4269,10 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {...@@ -4255,7 +4269,10 @@ pub fn addExternFn(self: *MachO, name: []const u8) !u32 {
4255 });4269 });
4256 try self.unresolved.putNoClobber(self.base.allocator, sym_index, .stub);4270 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 };
4259}4276}
42604277
4261const NextSegmentAddressAndOffset = struct {4278const NextSegmentAddressAndOffset = struct {