authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-21 18:55:15+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-21 18:55:15+02:00
logd61d85abd2b998fea438e7317568537f927fa6a1
tree2aa6ebc065b5a2efa52b76f83668b8094c8d9773
parentd63d8ae1c00c240ac20836f1b54bff0093edcb61

macho: implement aarch64 prong of createStubHelperAtom


1 files changed, 78 insertions(+), 91 deletions(-)

src/link/MachO.zig+78-91
...@@ -807,7 +807,11 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {...@@ -807,7 +807,11 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {
807 // TODO just a temp807 // TODO just a temp
808 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;808 const seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
809 const sect = seg.sections.items[self.stub_helper_section_index.?];809 const sect = seg.sections.items[self.stub_helper_section_index.?];
810 self.stub_helper_stubs_start_off = sect.offset + 15;810 self.stub_helper_stubs_start_off = sect.offset + switch (self.base.options.target.cpu.arch) {
811 .x86_64 => @intCast(u64, 15),
812 .aarch64 => @intCast(u64, 6 * @sizeOf(u32)),
813 else => unreachable,
814 };
811 }815 }
812 try self.flushZld();816 try self.flushZld();
813 } else {817 } else {
...@@ -2018,11 +2022,12 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {...@@ -2018,11 +2022,12 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
2018 const atom = try self.createEmptyAtom(match, local_sym_index, size, alignment);2022 const atom = try self.createEmptyAtom(match, local_sym_index, size, alignment);
2019 switch (arch) {2023 switch (arch) {
2020 .x86_64 => {2024 .x86_64 => {
2025 try atom.relocs.ensureUnusedCapacity(self.base.allocator, 2);
2021 // lea %r11, [rip + disp]2026 // lea %r11, [rip + disp]
2022 atom.code.items[0] = 0x4c;2027 atom.code.items[0] = 0x4c;
2023 atom.code.items[1] = 0x8d;2028 atom.code.items[1] = 0x8d;
2024 atom.code.items[2] = 0x1d;2029 atom.code.items[2] = 0x1d;
2025 try atom.relocs.append(self.base.allocator, .{2030 atom.relocs.appendAssumeCapacity(.{
2026 .offset = 3,2031 .offset = 3,
2027 .where = .local,2032 .where = .local,
2028 .where_index = self.dyld_private_sym_index.?,2033 .where_index = self.dyld_private_sym_index.?,
...@@ -2039,7 +2044,7 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {...@@ -2039,7 +2044,7 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
2039 // jmp [rip + disp]2044 // jmp [rip + disp]
2040 atom.code.items[9] = 0xff;2045 atom.code.items[9] = 0xff;
2041 atom.code.items[10] = 0x25;2046 atom.code.items[10] = 0x25;
2042 try atom.relocs.append(self.base.allocator, .{2047 atom.relocs.appendAssumeCapacity(.{
2043 .offset = 11,2048 .offset = 11,
2044 .where = .undef,2049 .where = .undef,
2045 .where_index = self.dyld_stub_binder_index.?,2050 .where_index = self.dyld_stub_binder_index.?,
...@@ -2051,94 +2056,76 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {...@@ -2051,94 +2056,76 @@ fn createStubHelperPreambleAtom(self: *MachO) !void {
2051 },2056 },
2052 });2057 });
2053 },2058 },
2054 // .aarch64 => {2059 .aarch64 => {
2055 // var code: [6 * @sizeOf(u32)]u8 = undefined;2060 try atom.relocs.ensureUnusedCapacity(self.base.allocator, 4);
2056 // data_blk_outer: {2061 // adrp x17, 0
2057 // const this_addr = stub_helper.addr;2062 mem.writeIntLittle(u32, atom.code.items[0..][0..4], aarch64.Instruction.adrp(.x17, 0).toU32());
2058 // const target_addr = data.addr + data.size - @sizeOf(u64);2063 atom.relocs.appendAssumeCapacity(.{
2059 // data_blk: {2064 .offset = 0,
2060 // const displacement = math.cast(i21, target_addr - this_addr) catch break :data_blk;2065 .where = .local,
2061 // // adr x17, disp2066 .where_index = self.dyld_private_sym_index.?,
2062 // mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x17, displacement).toU32());2067 .payload = .{
2063 // // nop2068 .page = .{
2064 // mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.nop().toU32());2069 .kind = .page,
2065 // break :data_blk_outer;2070 .addend = 0,
2066 // }2071 },
2067 // data_blk: {2072 },
2068 // const new_this_addr = this_addr + @sizeOf(u32);2073 });
2069 // const displacement = math.cast(i21, target_addr - new_this_addr) catch break :data_blk;2074 // add x17, x17, 0
2070 // // nop2075 mem.writeIntLittle(u32, atom.code.items[4..][0..4], aarch64.Instruction.add(.x17, .x17, 0, false).toU32());
2071 // mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.nop().toU32());2076 atom.relocs.appendAssumeCapacity(.{
2072 // // adr x17, disp2077 .offset = 4,
2073 // mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.adr(.x17, displacement).toU32());2078 .where = .local,
2074 // break :data_blk_outer;2079 .where_index = self.dyld_private_sym_index.?,
2075 // }2080 .payload = .{
2076 // // Jump is too big, replace adr with adrp and add.2081 .page_off = .{
2077 // const this_page = @intCast(i32, this_addr >> 12);2082 .kind = .page,
2078 // const target_page = @intCast(i32, target_addr >> 12);2083 .addend = 0,
2079 // const pages = @intCast(i21, target_page - this_page);2084 .op_kind = .arithmetic,
2080 // mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adrp(.x17, pages).toU32());2085 },
2081 // const narrowed = @truncate(u12, target_addr);2086 },
2082 // mem.writeIntLittle(u32, code[4..8], aarch64.Instruction.add(.x17, .x17, narrowed, false).toU32());2087 });
2083 // }2088 // stp x16, x17, [sp, #-16]!
2084 // // stp x16, x17, [sp, #-16]!2089 mem.writeIntLittle(u32, atom.code.items[8..][0..4], aarch64.Instruction.stp(
2085 // code[8] = 0xf0;2090 .x16,
2086 // code[9] = 0x47;2091 .x17,
2087 // code[10] = 0xbf;2092 aarch64.Register.sp,
2088 // code[11] = 0xa9;2093 aarch64.Instruction.LoadStorePairOffset.pre_index(-16),
2089 // binder_blk_outer: {2094 ).toU32());
2090 // const got_index = self.got_entries_map.get(.{2095 // adrp x16, 0
2091 // .where = .undef,2096 mem.writeIntLittle(u32, atom.code.items[12..][0..4], aarch64.Instruction.adrp(.x16, 0).toU32());
2092 // .where_index = self.dyld_stub_binder_index.?,2097 atom.relocs.appendAssumeCapacity(.{
2093 // }) orelse unreachable;2098 .offset = 12,
2094 // const this_addr = stub_helper.addr + 3 * @sizeOf(u32);2099 .where = .undef,
2095 // const target_addr = got.addr + got_index * @sizeOf(u64);2100 .where_index = self.dyld_stub_binder_index.?,
2096 // binder_blk: {2101 .payload = .{
2097 // const displacement = math.divExact(u64, target_addr - this_addr, 4) catch break :binder_blk;2102 .page = .{
2098 // const literal = math.cast(u18, displacement) catch break :binder_blk;2103 .kind = .got,
2099 // // ldr x16, label2104 .addend = 0,
2100 // mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.ldr(.x16, .{2105 },
2101 // .literal = literal,2106 },
2102 // }).toU32());2107 });
2103 // // nop2108 // ldr x16, [x16, 0]
2104 // mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.nop().toU32());2109 mem.writeIntLittle(u32, atom.code.items[16..][0..4], aarch64.Instruction.ldr(.x16, .{
2105 // break :binder_blk_outer;2110 .register = .{
2106 // }2111 .rn = .x16,
2107 // binder_blk: {2112 .offset = aarch64.Instruction.LoadStoreOffset.imm(0),
2108 // const new_this_addr = this_addr + @sizeOf(u32);2113 },
2109 // const displacement = math.divExact(u64, target_addr - new_this_addr, 4) catch break :binder_blk;2114 }).toU32());
2110 // const literal = math.cast(u18, displacement) catch break :binder_blk;2115 atom.relocs.appendAssumeCapacity(.{
2111 // // Pad with nop to please division.2116 .offset = 16,
2112 // // nop2117 .where = .undef,
2113 // mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.nop().toU32());2118 .where_index = self.dyld_stub_binder_index.?,
2114 // // ldr x16, label2119 .payload = .{
2115 // mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.ldr(.x16, .{2120 .page_off = .{
2116 // .literal = literal,2121 .kind = .got,
2117 // }).toU32());2122 .addend = 0,
2118 // break :binder_blk_outer;2123 },
2119 // }2124 },
2120 // // Use adrp followed by ldr(immediate).2125 });
2121 // const this_page = @intCast(i32, this_addr >> 12);2126 // br x16
2122 // const target_page = @intCast(i32, target_addr >> 12);2127 mem.writeIntLittle(u32, atom.code.items[20..][0..4], aarch64.Instruction.br(.x16).toU32());
2123 // const pages = @intCast(i21, target_page - this_page);2128 },
2124 // mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.adrp(.x16, pages).toU32());
2125 // const narrowed = @truncate(u12, target_addr);
2126 // const offset = try math.divExact(u12, narrowed, 8);
2127 // mem.writeIntLittle(u32, code[16..20], aarch64.Instruction.ldr(.x16, .{
2128 // .register = .{
2129 // .rn = .x16,
2130 // .offset = aarch64.Instruction.LoadStoreOffset.imm(offset),
2131 // },
2132 // }).toU32());
2133 // }
2134 // // br x16
2135 // code[20] = 0x00;
2136 // code[21] = 0x02;
2137 // code[22] = 0x1f;
2138 // code[23] = 0xd6;
2139 // try self.base.file.?.pwriteAll(&code, stub_helper.offset);
2140 // break :blk stub_helper.offset + 6 * @sizeOf(u32);
2141 // },
2142 else => unreachable,2129 else => unreachable,
2143 }2130 }
2144 self.stub_preamble_sym_index = local_sym_index;2131 self.stub_preamble_sym_index = local_sym_index;