authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-09 07:56:49+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2020-12-09 17:20:58+01:00
logeca0727417833b6c60cb2b30ba492ef816f4a4bc
tree1c6c89a45ae3c7fdd64e2568bfdae970a6848dff
parent21dae538caa5eac71b52be5da59d3a18c05b3a89

stage2+aarch64: use stp and ldp to navigate MachO jump table


1 files changed, 29 insertions(+), 26 deletions(-)

src/codegen.zig+29-26
...@@ -2730,13 +2730,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2730,13 +2730,10 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2730 // For MachO, the binary, with the exception of object files, has to be a PIE.2730 // For MachO, the binary, with the exception of object files, has to be a PIE.
2731 // Therefore we cannot load an absolute address.2731 // Therefore we cannot load an absolute address.
2732 // Instead, we need to make use of PC-relative addressing.2732 // Instead, we need to make use of PC-relative addressing.
2733 // TODO This needs to be optimised in the stack usage (perhaps use a shadow stack
2734 // like described here:
2735 // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/using-the-stack-in-aarch64-implementing-push-and-pop)
2736 // TODO As far as branching is concerned, instead of saving the return address
2737 // in a register, I'm thinking here of immitating x86_64, and having the address
2738 // passed on the stack.
2739 if (reg.id() == 0) { // x0 is special-cased2733 if (reg.id() == 0) { // x0 is special-cased
2734 // TODO This needs to be optimised in the stack usage (perhaps use a shadow stack
2735 // like described here:
2736 // https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/using-the-stack-in-aarch64-implementing-push-and-pop)
2740 // str x28, [sp, #-16]2737 // str x28, [sp, #-16]
2741 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x28, Register.sp, .{2738 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x28, Register.sp, .{
2742 .offset = Instruction.Offset.imm_pre_index(-16),2739 .offset = Instruction.Offset.imm_pre_index(-16),
...@@ -2755,21 +2752,25 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2755,21 +2752,25 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2755 // b [label]2752 // b [label]
2756 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());2753 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
2757 // mov r, x02754 // mov r, x0
2758 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(reg, .x0, Instruction.RegisterShift.none()).toU32());2755 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(
2756 reg,
2757 .x0,
2758 Instruction.RegisterShift.none(),
2759 ).toU32());
2759 // ldr x28, [sp], #162760 // ldr x28, [sp], #16
2760 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{2761 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{
2761 .rn = Register.sp,2762 .rn = Register.sp,
2762 .offset = Instruction.Offset.imm_post_index(16),2763 .offset = Instruction.Offset.imm_post_index(16),
2763 }).toU32());2764 }).toU32());
2764 } else {2765 } else {
2765 // str x28, [sp, #-16]2766 // stp x0, x28, [sp, #-16]
2766 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x28, Register.sp, .{2767 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.stp(
2767 .offset = Instruction.Offset.imm_pre_index(-16),2768 .x0,
2768 }).toU32());2769 .x28,
2769 // str x0, [sp, #-16]2770 Register.sp,
2770 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.str(.x0, Register.sp, .{2771 -2,
2771 .offset = Instruction.Offset.imm_pre_index(-16),2772 .SignedOffset,
2772 }).toU32());2773 ).toU32());
2773 // adr x28, #82774 // adr x28, #8
2774 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());2775 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.adr(.x28, 8).toU32());
2775 if (self.bin_file.cast(link.File.MachO)) |macho_file| {2776 if (self.bin_file.cast(link.File.MachO)) |macho_file| {
...@@ -2784,17 +2785,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -2784,17 +2785,19 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
2784 // b [label]2785 // b [label]
2785 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());2786 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.b(0).toU32());
2786 // mov r, x02787 // mov r, x0
2787 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(reg, .x0, Instruction.RegisterShift.none()).toU32());2788 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.orr(
2788 // ldr x0, [sp], #162789 reg,
2789 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x0, .{2790 .x0,
2790 .rn = Register.sp,2791 Instruction.RegisterShift.none(),
2791 .offset = Instruction.Offset.imm_post_index(16),2792 ).toU32());
2792 }).toU32());2793 // ldp x0, x28, [sp, #16]
2793 // ldr x28, [sp], #162794 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldp(
2794 mem.writeIntLittle(u32, try self.code.addManyAsArray(4), Instruction.ldr(.x28, .{2795 .x0,
2795 .rn = Register.sp,2796 .x28,
2796 .offset = Instruction.Offset.imm_post_index(16),2797 Register.sp,
2797 }).toU32());2798 2,
2799 .SignedOffset,
2800 ).toU32());
2798 }2801 }
2799 } else {2802 } else {
2800 // The value is in memory at a hard-coded address.2803 // The value is in memory at a hard-coded address.