authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2025-10-29 16:41:54-04:00
committergravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-10-30 09:31:30+00:00
log32779a7c7392d823c945ae0a13a65cf94a4044b8
tree3c7b27d5e3ebc31e94c2865e017707717ed30c8b
parent402c14f86a97f47ca429565fddb7ffca5c08d873
signaturelock-open Commit is signed but in an unrecognized format.

aarch64: fix macho external references


2 files changed, 67 insertions(+), 19 deletions(-)

src/codegen/aarch64/Mir.zig+59-17
...@@ -107,6 +107,7 @@ pub fn emit(...@@ -107,6 +107,7 @@ pub fn emit(
107 mir.body[nav_reloc.reloc.label],107 mir.body[nav_reloc.reloc.label],
108 body_end - Instruction.size * (1 + nav_reloc.reloc.label),108 body_end - Instruction.size * (1 + nav_reloc.reloc.label),
109 nav_reloc.reloc.addend,109 nav_reloc.reloc.addend,
110 if (ip.getNav(nav_reloc.nav).getExtern(ip)) |_| .got_load else .direct,
110 );111 );
111 for (mir.uav_relocs) |uav_reloc| try emitReloc(112 for (mir.uav_relocs) |uav_reloc| try emitReloc(
112 lf,113 lf,
...@@ -124,6 +125,7 @@ pub fn emit(...@@ -124,6 +125,7 @@ pub fn emit(
124 mir.body[uav_reloc.reloc.label],125 mir.body[uav_reloc.reloc.label],
125 body_end - Instruction.size * (1 + uav_reloc.reloc.label),126 body_end - Instruction.size * (1 + uav_reloc.reloc.label),
126 uav_reloc.reloc.addend,127 uav_reloc.reloc.addend,
128 .direct,
127 );129 );
128 for (mir.lazy_relocs) |lazy_reloc| try emitReloc(130 for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
129 lf,131 lf,
...@@ -140,6 +142,7 @@ pub fn emit(...@@ -140,6 +142,7 @@ pub fn emit(
140 mir.body[lazy_reloc.reloc.label],142 mir.body[lazy_reloc.reloc.label],
141 body_end - Instruction.size * (1 + lazy_reloc.reloc.label),143 body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
142 lazy_reloc.reloc.addend,144 lazy_reloc.reloc.addend,
145 .direct,
143 );146 );
144 for (mir.global_relocs) |global_reloc| try emitReloc(147 for (mir.global_relocs) |global_reloc| try emitReloc(
145 lf,148 lf,
...@@ -154,6 +157,7 @@ pub fn emit(...@@ -154,6 +157,7 @@ pub fn emit(
154 mir.body[global_reloc.reloc.label],157 mir.body[global_reloc.reloc.label],
155 body_end - Instruction.size * (1 + global_reloc.reloc.label),158 body_end - Instruction.size * (1 + global_reloc.reloc.label),
156 global_reloc.reloc.addend,159 global_reloc.reloc.addend,
160 .direct,
157 );161 );
158 const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);162 const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);
159 for (mir.literal_relocs) |literal_reloc| {163 for (mir.literal_relocs) |literal_reloc| {
...@@ -188,6 +192,7 @@ fn emitReloc(...@@ -188,6 +192,7 @@ fn emitReloc(
188 instruction: Instruction,192 instruction: Instruction,
189 offset: u32,193 offset: u32,
190 addend: u64,194 addend: u64,
195 kind: enum { direct, got_load },
191) !void {196) !void {
192 const gpa = zcu.gpa;197 const gpa = zcu.gpa;
193 switch (instruction.decode()) {198 switch (instruction.decode()) {
...@@ -198,11 +203,20 @@ fn emitReloc(...@@ -198,11 +203,20 @@ fn emitReloc(
198 const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {203 const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
199 else => unreachable,204 else => unreachable,
200 .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {205 .pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
201 .adr => .ADR_PREL_LO21,206 .adr => switch (kind) {
202 .adrp => .ADR_PREL_PG_HI21,207 .direct => .ADR_PREL_LO21,
208 .got_load => unreachable,
209 },
210 .adrp => switch (kind) {
211 .direct => .ADR_PREL_PG_HI21,
212 .got_load => .ADR_GOT_PAGE,
213 },
203 },214 },
204 .add_subtract_immediate => |add_subtract_immediate| switch (add_subtract_immediate.group.op) {215 .add_subtract_immediate => |add_subtract_immediate| switch (add_subtract_immediate.group.op) {
205 .add => .ADD_ABS_LO12_NC,216 .add => switch (kind) {
217 .direct => .ADD_ABS_LO12_NC,
218 .got_load => unreachable,
219 },
206 .sub => unreachable,220 .sub => unreachable,
207 },221 },
208 };222 };
...@@ -223,7 +237,10 @@ fn emitReloc(...@@ -223,7 +237,10 @@ fn emitReloc(
223 .offset = offset,237 .offset = offset,
224 .target = sym_index,238 .target = sym_index,
225 .addend = @bitCast(addend),239 .addend = @bitCast(addend),
226 .type = .page,240 .type = switch (kind) {
241 .direct => .page,
242 .got_load => .got_load_page,
243 },
227 .meta = .{244 .meta = .{
228 .pcrel = true,245 .pcrel = true,
229 .has_subtractor = false,246 .has_subtractor = false,
...@@ -238,7 +255,10 @@ fn emitReloc(...@@ -238,7 +255,10 @@ fn emitReloc(
238 .offset = offset,255 .offset = offset,
239 .target = sym_index,256 .target = sym_index,
240 .addend = @bitCast(addend),257 .addend = @bitCast(addend),
241 .type = .pageoff,258 .type = switch (kind) {
259 .direct => .pageoff,
260 .got_load => .got_load_pageoff,
261 },
242 .meta = .{262 .meta = .{
243 .pcrel = false,263 .pcrel = false,
244 .has_subtractor = false,264 .has_subtractor = false,
...@@ -285,20 +305,39 @@ fn emitReloc(...@@ -285,20 +305,39 @@ fn emitReloc(
285 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {305 const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
286 .integer => |integer| switch (integer.decode()) {306 .integer => |integer| switch (integer.decode()) {
287 .unallocated, .prfm => unreachable,307 .unallocated, .prfm => unreachable,
288 .strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,308 .strb, .ldrb, .ldrsb => switch (kind) {
289 .strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,309 .direct => .LDST8_ABS_LO12_NC,
290 .ldrsw => .LDST32_ABS_LO12_NC,310 .got_load => unreachable,
291 inline .str, .ldr => |encoded| switch (encoded.sf) {311 },
312 .strh, .ldrh, .ldrsh => switch (kind) {
313 .direct => .LDST16_ABS_LO12_NC,
314 .got_load => unreachable,
315 },
316 .ldrsw => switch (kind) {
317 .direct => .LDST32_ABS_LO12_NC,
318 .got_load => unreachable,
319 },
320 inline .str, .ldr => |encoded, mnemonic| switch (encoded.sf) {
292 .word => .LDST32_ABS_LO12_NC,321 .word => .LDST32_ABS_LO12_NC,
293 .doubleword => .LDST64_ABS_LO12_NC,322 .doubleword => switch (kind) {
323 .direct => .LDST64_ABS_LO12_NC,
324 .got_load => switch (mnemonic) {
325 else => comptime unreachable,
326 .str => unreachable,
327 .ldr => .LD64_GOT_LO12_NC,
328 },
329 },
294 },330 },
295 },331 },
296 .vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {332 .vector => |vector| switch (kind) {
297 .byte => .LDST8_ABS_LO12_NC,333 .direct => switch (vector.group.opc1.decode(vector.group.size)) {
298 .half => .LDST16_ABS_LO12_NC,334 .byte => .LDST8_ABS_LO12_NC,
299 .single => .LDST32_ABS_LO12_NC,335 .half => .LDST16_ABS_LO12_NC,
300 .double => .LDST64_ABS_LO12_NC,336 .single => .LDST32_ABS_LO12_NC,
301 .quad => .LDST128_ABS_LO12_NC,337 .double => .LDST64_ABS_LO12_NC,
338 .quad => .LDST128_ABS_LO12_NC,
339 },
340 .got_load => unreachable,
302 },341 },
303 };342 };
304 try atom.addReloc(gpa, .{343 try atom.addReloc(gpa, .{
...@@ -314,7 +353,10 @@ fn emitReloc(...@@ -314,7 +353,10 @@ fn emitReloc(
314 .offset = offset,353 .offset = offset,
315 .target = sym_index,354 .target = sym_index,
316 .addend = @bitCast(addend),355 .addend = @bitCast(addend),
317 .type = .pageoff,356 .type = switch (kind) {
357 .direct => .pageoff,
358 .got_load => .got_load_pageoff,
359 },
318 .meta = .{360 .meta = .{
319 .pcrel = false,361 .pcrel = false,
320 .has_subtractor = false,362 .has_subtractor = false,
src/codegen/aarch64/Select.zig+8-2
...@@ -7257,7 +7257,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,...@@ -7257,7 +7257,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
7257 .nav = ty_nav.nav,7257 .nav = ty_nav.nav,
7258 .reloc = .{ .label = @intCast(isel.instructions.items.len) },7258 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
7259 });7259 });
7260 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));7260 if (ip.getNav(ty_nav.nav).getExtern(ip)) |_|
7261 try isel.emit(.ldr(ptr_ra.x(), .{ .unsigned_offset = .{ .base = ptr_ra.x(), .offset = 0 } }))
7262 else
7263 try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
7261 try isel.nav_relocs.append(gpa, .{7264 try isel.nav_relocs.append(gpa, .{
7262 .nav = ty_nav.nav,7265 .nav = ty_nav.nav,
7263 .reloc = .{ .label = @intCast(isel.instructions.items.len) },7266 .reloc = .{ .label = @intCast(isel.instructions.items.len) },
...@@ -10971,7 +10974,10 @@ pub const Value = struct {...@@ -10971,7 +10974,10 @@ pub const Value = struct {
10971 .addend = ptr.byte_offset,10974 .addend = ptr.byte_offset,
10972 },10975 },
10973 });10976 });
10974 try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));10977 if (ip.getNav(nav).getExtern(ip)) |_|
10978 try isel.emit(.ldr(mat.ra.x(), .{ .unsigned_offset = .{ .base = mat.ra.x(), .offset = 0 } }))
10979 else
10980 try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));
10975 try isel.nav_relocs.append(zcu.gpa, .{10981 try isel.nav_relocs.append(zcu.gpa, .{
10976 .nav = nav,10982 .nav = nav,
10977 .reloc = .{10983 .reloc = .{