| ... | @@ -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 temp | 807 | // 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, disp | 2066 | .where_index = self.dyld_private_sym_index.?, |
| 2062 | // mem.writeIntLittle(u32, code[0..4], aarch64.Instruction.adr(.x17, displacement).toU32()); | 2067 | .payload = .{ |
| 2063 | // // nop | 2068 | .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 | // // nop | 2075 | 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, disp | 2077 | .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, label | 2104 | .addend = 0, |
| 2100 | // mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.ldr(.x16, .{ | 2105 | }, |
| 2101 | // .literal = literal, | 2106 | }, |
| 2102 | // }).toU32()); | 2107 | }); |
| 2103 | // // nop | 2108 | // 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 | // // nop | 2117 | .where = .undef, |
| 2113 | // mem.writeIntLittle(u32, code[12..16], aarch64.Instruction.nop().toU32()); | 2118 | .where_index = self.dyld_stub_binder_index.?, |
| 2114 | // // ldr x16, label | 2119 | .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; |