mirror of
https://github.com/ziglang/zig.git
synced 2025-12-22 06:03:16 +00:00
aarch64: fix macho external references
This commit is contained in:
parent
402c14f86a
commit
32779a7c73
@ -107,6 +107,7 @@ pub fn emit(
|
|||||||
mir.body[nav_reloc.reloc.label],
|
mir.body[nav_reloc.reloc.label],
|
||||||
body_end - Instruction.size * (1 + nav_reloc.reloc.label),
|
body_end - Instruction.size * (1 + nav_reloc.reloc.label),
|
||||||
nav_reloc.reloc.addend,
|
nav_reloc.reloc.addend,
|
||||||
|
if (ip.getNav(nav_reloc.nav).getExtern(ip)) |_| .got_load else .direct,
|
||||||
);
|
);
|
||||||
for (mir.uav_relocs) |uav_reloc| try emitReloc(
|
for (mir.uav_relocs) |uav_reloc| try emitReloc(
|
||||||
lf,
|
lf,
|
||||||
@ -124,6 +125,7 @@ pub fn emit(
|
|||||||
mir.body[uav_reloc.reloc.label],
|
mir.body[uav_reloc.reloc.label],
|
||||||
body_end - Instruction.size * (1 + uav_reloc.reloc.label),
|
body_end - Instruction.size * (1 + uav_reloc.reloc.label),
|
||||||
uav_reloc.reloc.addend,
|
uav_reloc.reloc.addend,
|
||||||
|
.direct,
|
||||||
);
|
);
|
||||||
for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
|
for (mir.lazy_relocs) |lazy_reloc| try emitReloc(
|
||||||
lf,
|
lf,
|
||||||
@ -140,6 +142,7 @@ pub fn emit(
|
|||||||
mir.body[lazy_reloc.reloc.label],
|
mir.body[lazy_reloc.reloc.label],
|
||||||
body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
|
body_end - Instruction.size * (1 + lazy_reloc.reloc.label),
|
||||||
lazy_reloc.reloc.addend,
|
lazy_reloc.reloc.addend,
|
||||||
|
.direct,
|
||||||
);
|
);
|
||||||
for (mir.global_relocs) |global_reloc| try emitReloc(
|
for (mir.global_relocs) |global_reloc| try emitReloc(
|
||||||
lf,
|
lf,
|
||||||
@ -154,6 +157,7 @@ pub fn emit(
|
|||||||
mir.body[global_reloc.reloc.label],
|
mir.body[global_reloc.reloc.label],
|
||||||
body_end - Instruction.size * (1 + global_reloc.reloc.label),
|
body_end - Instruction.size * (1 + global_reloc.reloc.label),
|
||||||
global_reloc.reloc.addend,
|
global_reloc.reloc.addend,
|
||||||
|
.direct,
|
||||||
);
|
);
|
||||||
const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);
|
const literal_reloc_offset: i19 = @intCast(mir.epilogue.len + literals_align_gap);
|
||||||
for (mir.literal_relocs) |literal_reloc| {
|
for (mir.literal_relocs) |literal_reloc| {
|
||||||
@ -188,6 +192,7 @@ fn emitReloc(
|
|||||||
instruction: Instruction,
|
instruction: Instruction,
|
||||||
offset: u32,
|
offset: u32,
|
||||||
addend: u64,
|
addend: u64,
|
||||||
|
kind: enum { direct, got_load },
|
||||||
) !void {
|
) !void {
|
||||||
const gpa = zcu.gpa;
|
const gpa = zcu.gpa;
|
||||||
switch (instruction.decode()) {
|
switch (instruction.decode()) {
|
||||||
@ -198,11 +203,20 @@ fn emitReloc(
|
|||||||
const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
|
const r_type: std.elf.R_AARCH64 = switch (decoded.decode()) {
|
||||||
else => unreachable,
|
else => unreachable,
|
||||||
.pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
|
.pc_relative_addressing => |pc_relative_addressing| switch (pc_relative_addressing.group.op) {
|
||||||
.adr => .ADR_PREL_LO21,
|
.adr => switch (kind) {
|
||||||
.adrp => .ADR_PREL_PG_HI21,
|
.direct => .ADR_PREL_LO21,
|
||||||
|
.got_load => unreachable,
|
||||||
|
},
|
||||||
|
.adrp => switch (kind) {
|
||||||
|
.direct => .ADR_PREL_PG_HI21,
|
||||||
|
.got_load => .ADR_GOT_PAGE,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.add_subtract_immediate => |add_subtract_immediate| switch (add_subtract_immediate.group.op) {
|
.add_subtract_immediate => |add_subtract_immediate| switch (add_subtract_immediate.group.op) {
|
||||||
.add => .ADD_ABS_LO12_NC,
|
.add => switch (kind) {
|
||||||
|
.direct => .ADD_ABS_LO12_NC,
|
||||||
|
.got_load => unreachable,
|
||||||
|
},
|
||||||
.sub => unreachable,
|
.sub => unreachable,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -223,7 +237,10 @@ fn emitReloc(
|
|||||||
.offset = offset,
|
.offset = offset,
|
||||||
.target = sym_index,
|
.target = sym_index,
|
||||||
.addend = @bitCast(addend),
|
.addend = @bitCast(addend),
|
||||||
.type = .page,
|
.type = switch (kind) {
|
||||||
|
.direct => .page,
|
||||||
|
.got_load => .got_load_page,
|
||||||
|
},
|
||||||
.meta = .{
|
.meta = .{
|
||||||
.pcrel = true,
|
.pcrel = true,
|
||||||
.has_subtractor = false,
|
.has_subtractor = false,
|
||||||
@ -238,7 +255,10 @@ fn emitReloc(
|
|||||||
.offset = offset,
|
.offset = offset,
|
||||||
.target = sym_index,
|
.target = sym_index,
|
||||||
.addend = @bitCast(addend),
|
.addend = @bitCast(addend),
|
||||||
.type = .pageoff,
|
.type = switch (kind) {
|
||||||
|
.direct => .pageoff,
|
||||||
|
.got_load => .got_load_pageoff,
|
||||||
|
},
|
||||||
.meta = .{
|
.meta = .{
|
||||||
.pcrel = false,
|
.pcrel = false,
|
||||||
.has_subtractor = false,
|
.has_subtractor = false,
|
||||||
@ -285,21 +305,40 @@ fn emitReloc(
|
|||||||
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
|
const r_type: std.elf.R_AARCH64 = switch (decoded.decode().register_unsigned_immediate.decode()) {
|
||||||
.integer => |integer| switch (integer.decode()) {
|
.integer => |integer| switch (integer.decode()) {
|
||||||
.unallocated, .prfm => unreachable,
|
.unallocated, .prfm => unreachable,
|
||||||
.strb, .ldrb, .ldrsb => .LDST8_ABS_LO12_NC,
|
.strb, .ldrb, .ldrsb => switch (kind) {
|
||||||
.strh, .ldrh, .ldrsh => .LDST16_ABS_LO12_NC,
|
.direct => .LDST8_ABS_LO12_NC,
|
||||||
.ldrsw => .LDST32_ABS_LO12_NC,
|
.got_load => unreachable,
|
||||||
inline .str, .ldr => |encoded| switch (encoded.sf) {
|
},
|
||||||
|
.strh, .ldrh, .ldrsh => switch (kind) {
|
||||||
|
.direct => .LDST16_ABS_LO12_NC,
|
||||||
|
.got_load => unreachable,
|
||||||
|
},
|
||||||
|
.ldrsw => switch (kind) {
|
||||||
|
.direct => .LDST32_ABS_LO12_NC,
|
||||||
|
.got_load => unreachable,
|
||||||
|
},
|
||||||
|
inline .str, .ldr => |encoded, mnemonic| switch (encoded.sf) {
|
||||||
.word => .LDST32_ABS_LO12_NC,
|
.word => .LDST32_ABS_LO12_NC,
|
||||||
.doubleword => .LDST64_ABS_LO12_NC,
|
.doubleword => switch (kind) {
|
||||||
|
.direct => .LDST64_ABS_LO12_NC,
|
||||||
|
.got_load => switch (mnemonic) {
|
||||||
|
else => comptime unreachable,
|
||||||
|
.str => unreachable,
|
||||||
|
.ldr => .LD64_GOT_LO12_NC,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.vector => |vector| switch (vector.group.opc1.decode(vector.group.size)) {
|
},
|
||||||
|
},
|
||||||
|
.vector => |vector| switch (kind) {
|
||||||
|
.direct => switch (vector.group.opc1.decode(vector.group.size)) {
|
||||||
.byte => .LDST8_ABS_LO12_NC,
|
.byte => .LDST8_ABS_LO12_NC,
|
||||||
.half => .LDST16_ABS_LO12_NC,
|
.half => .LDST16_ABS_LO12_NC,
|
||||||
.single => .LDST32_ABS_LO12_NC,
|
.single => .LDST32_ABS_LO12_NC,
|
||||||
.double => .LDST64_ABS_LO12_NC,
|
.double => .LDST64_ABS_LO12_NC,
|
||||||
.quad => .LDST128_ABS_LO12_NC,
|
.quad => .LDST128_ABS_LO12_NC,
|
||||||
},
|
},
|
||||||
|
.got_load => unreachable,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
try atom.addReloc(gpa, .{
|
try atom.addReloc(gpa, .{
|
||||||
.r_offset = offset,
|
.r_offset = offset,
|
||||||
@ -314,7 +353,10 @@ fn emitReloc(
|
|||||||
.offset = offset,
|
.offset = offset,
|
||||||
.target = sym_index,
|
.target = sym_index,
|
||||||
.addend = @bitCast(addend),
|
.addend = @bitCast(addend),
|
||||||
.type = .pageoff,
|
.type = switch (kind) {
|
||||||
|
.direct => .pageoff,
|
||||||
|
.got_load => .got_load_pageoff,
|
||||||
|
},
|
||||||
.meta = .{
|
.meta = .{
|
||||||
.pcrel = false,
|
.pcrel = false,
|
||||||
.has_subtractor = false,
|
.has_subtractor = false,
|
||||||
|
|||||||
@ -7257,6 +7257,9 @@ pub fn body(isel: *Select, air_body: []const Air.Inst.Index) error{ OutOfMemory,
|
|||||||
.nav = ty_nav.nav,
|
.nav = ty_nav.nav,
|
||||||
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
|
.reloc = .{ .label = @intCast(isel.instructions.items.len) },
|
||||||
});
|
});
|
||||||
|
if (ip.getNav(ty_nav.nav).getExtern(ip)) |_|
|
||||||
|
try isel.emit(.ldr(ptr_ra.x(), .{ .unsigned_offset = .{ .base = ptr_ra.x(), .offset = 0 } }))
|
||||||
|
else
|
||||||
try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
|
try isel.emit(.add(ptr_ra.x(), ptr_ra.x(), .{ .immediate = 0 }));
|
||||||
try isel.nav_relocs.append(gpa, .{
|
try isel.nav_relocs.append(gpa, .{
|
||||||
.nav = ty_nav.nav,
|
.nav = ty_nav.nav,
|
||||||
@ -10971,6 +10974,9 @@ pub const Value = struct {
|
|||||||
.addend = ptr.byte_offset,
|
.addend = ptr.byte_offset,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
if (ip.getNav(nav).getExtern(ip)) |_|
|
||||||
|
try isel.emit(.ldr(mat.ra.x(), .{ .unsigned_offset = .{ .base = mat.ra.x(), .offset = 0 } }))
|
||||||
|
else
|
||||||
try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));
|
try isel.emit(.add(mat.ra.x(), mat.ra.x(), .{ .immediate = 0 }));
|
||||||
try isel.nav_relocs.append(zcu.gpa, .{
|
try isel.nav_relocs.append(zcu.gpa, .{
|
||||||
.nav = nav,
|
.nav = nav,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user