Skip to content

Commit 32779a7

Browse files
jacobly0mlugg
authored andcommitted
aarch64: fix macho external references
1 parent 402c14f commit 32779a7

File tree

2 files changed

+67
-19
lines changed

2 files changed

+67
-19
lines changed

src/codegen/aarch64/Mir.zig

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ pub fn emit(
107107
mir.body[nav_reloc.reloc.label],
108108
body_end - Instruction.size * (1 + nav_reloc.reloc.label),
109109
nav_reloc.reloc.addend,
110+
if (ip.getNav(nav_reloc.nav).getExtern(ip)) |_| .got_load else .direct,
110111
);
111112
for (mir.uav_relocs) |uav_reloc| try emitReloc(
112113
lf,
@@ -124,6 +125,7 @@ pub fn emit(
124125
mir.body[uav_reloc.reloc.label],
125126
body_end - Instruction.size * (1 + uav_reloc.reloc.label),
126127
uav_reloc.reloc.addend,
128+
.direct,
127129
);
128130
for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
129131
lf,
@@ -140,6 +142,7 @@ pub fn emit(
140142
mir.body[lazy_reloc.reloc.label],
141143
body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
142144
lazy_reloc.reloc.addend,
145+
.direct,
143146
);
144147
for (mir.global_relocs) |global_reloc| try emitReloc(
145148
lf,
@@ -154,6 +157,7 @@ pub fn emit(
154157
mir.body[global_reloc.reloc.label],
155158
body_end - Instruction.size * (1 + global_reloc.reloc.label),
156159
global_reloc.reloc.addend,
160+
.direct,
157161
);
158162
const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);
159163
for (mir.literal_relocs) |literal_reloc| {
@@ -188,6 +192,7 @@ fn emitReloc(
188192
instruction: Instruction,
189193
offset: u32,
190194
addend: u64,
195+
kind: enum { direct, got_load },
191196
) !void {
192197
const gpa = zcu.gpa;
193198
switch (instruction.decode()) {
@@ -198,11 +203,20 @@ fn emitReloc(
198203
const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
199204
else => unreachable,
200205
.pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
201-
.adr => .ADR_PREL_LO21,
202-
.adrp => .ADR_PREL_PG_HI21,
206+
.adr => switch (kind) {
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+
},
203214
},
204215
.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+
},
206220
.sub => unreachable,
207221
},
208222
};
@@ -223,7 +237,10 @@ fn emitReloc(
223237
.offset = offset,
224238
.target = sym_index,
225239
.addend = @bitCast(addend),
226-
.type = .page,
240+
.type = switch (kind) {
241+
.direct => .page,
242+
.got_load => .got_load_page,
243+
},
227244
.meta = .{
228245
.pcrel = true,
229246
.has_subtractor = false,
@@ -238,7 +255,10 @@ fn emitReloc(
238255
.offset = offset,
239256
.target = sym_index,
240257
.addend = @bitCast(addend),
241-
.type = .pageoff,
258+
.type = switch (kind) {
259+
.direct => .pageoff,
260+
.got_load => .got_load_pageoff,
261+
},
242262
.meta = .{
243263
.pcrel = false,
244264
.has_subtractor = false,
@@ -285,20 +305,39 @@ fn emitReloc(
285305
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
286306
.integer => |integer| switch (integer.decode()) {
287307
.unallocated, .prfm => unreachable,
288-
.strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,
289-
.strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,
290-
.ldrsw => .LDST32_ABS_LO12_NC,
291-
inline .str, .ldr => |encoded| switch (encoded.sf) {
308+
.strb, .ldrb, .ldrsb => switch (kind) {
309+
.direct => .LDST8_ABS_LO12_NC,
310+
.got_load => unreachable,
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) {
292321
.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+
},
294330
},
295331
},
296-
.vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {
297-
.byte => .LDST8_ABS_LO12_NC,
298-
.half => .LDST16_ABS_LO12_NC,
299-
.single => .LDST32_ABS_LO12_NC,
300-
.double => .LDST64_ABS_LO12_NC,
301-
.quad => .LDST128_ABS_LO12_NC,
332+
.vector => |vector| switch (kind) {
333+
.direct => switch (vector.group.opc1.decode(vector.group.size)) {
334+
.byte => .LDST8_ABS_LO12_NC,
335+
.half => .LDST16_ABS_LO12_NC,
336+
.single => .LDST32_ABS_LO12_NC,
337+
.double => .LDST64_ABS_LO12_NC,
338+
.quad => .LDST128_ABS_LO12_NC,
339+
},
340+
.got_load => unreachable,
302341
},
303342
};
304343
try atom.addReloc(gpa, .{
@@ -314,7 +353,10 @@ fn emitReloc(
314353
.offset = offset,
315354
.target = sym_index,
316355
.addend = @bitCast(addend),
317-
.type = .pageoff,
356+
.type = switch (kind) {
357+
.direct => .pageoff,
358+
.got_load => .got_load_pageoff,
359+
},
318360
.meta = .{
319361
.pcrel = false,
320362
.has_subtractor = false,

src/codegen/aarch64/Select.zig

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7257,7 +7257,10 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
72577257
.nav = ty_nav.nav,
72587258
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
72597259
});
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 }));
72617264
try isel.nav_relocs.append(gpa, .{
72627265
.nav = ty_nav.nav,
72637266
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
@@ -10971,7 +10974,10 @@ pub const Value = struct {
1097110974
.addend = ptr.byte_offset,
1097210975
},
1097310976
});
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 }));
1097510981
try isel.nav_relocs.append(zcu.gpa, .{
1097610982
.nav = nav,
1097710983
.reloc = .{

0 commit comments

Comments
 (0)