| ... | @@ -1130,23 +1130,24 @@ pub const PltGotSection = struct { | ... | @@ -1130,23 +1130,24 @@ pub const PltGotSection = struct { |
| 1130 | try plt_got.symbols.append(gpa, sym_index); | 1130 | try plt_got.symbols.append(gpa, sym_index); |
| 1131 | } | 1131 | } |
| 1132 | | 1132 | |
| 1133 | pub fn size(plt_got: PltGotSection) usize { | 1133 | pub fn size(plt_got: PltGotSection, elf_file: *Elf) usize { |
| 1134 | return plt_got.symbols.items.len * 16; | 1134 | return plt_got.symbols.items.len * entrySize(elf_file.getTarget().cpu.arch); |
| | 1135 | } |
| | 1136 | |
| | 1137 | pub fn entrySize(cpu_arch: std.Target.Cpu.Arch) usize { |
| | 1138 | return switch (cpu_arch) { |
| | 1139 | .x86_64 => 16, |
| | 1140 | .aarch64 => 4 * @sizeOf(u32), |
| | 1141 | else => @panic("TODO implement PltGotSection.entrySize for this arch"), |
| | 1142 | }; |
| 1135 | } | 1143 | } |
| 1136 | | 1144 | |
| 1137 | pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void { | 1145 | pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void { |
| 1138 | for (plt_got.symbols.items) |sym_index| { | 1146 | const cpu_arch = elf_file.getTarget().cpu.arch; |
| 1139 | const sym = elf_file.symbol(sym_index); | 1147 | switch (cpu_arch) { |
| 1140 | const target_addr = sym.gotAddress(elf_file); | 1148 | .x86_64 => try x86_64.write(plt_got, elf_file, writer), |
| 1141 | const source_addr = sym.pltGotAddress(elf_file); | 1149 | .aarch64 => try aarch64.write(plt_got, elf_file, writer), |
| 1142 | const disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 6)) - 4; | 1150 | else => return error.UnsupportedCpuArch, |
| 1143 | var entry = [_]u8{ | | |
| 1144 | 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 | | |
| 1145 | 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip] -> .got[N] | | |
| 1146 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, | | |
| 1147 | }; | | |
| 1148 | mem.writeInt(i32, entry[6..][0..4], @as(i32, @intCast(disp)), .little); | | |
| 1149 | try writer.writeAll(&entry); | | |
| 1150 | } | 1151 | } |
| 1151 | } | 1152 | } |
| 1152 | | 1153 | |
| ... | @@ -1175,6 +1176,50 @@ pub const PltGotSection = struct { | ... | @@ -1175,6 +1176,50 @@ pub const PltGotSection = struct { |
| 1175 | }; | 1176 | }; |
| 1176 | } | 1177 | } |
| 1177 | } | 1178 | } |
| | 1179 | |
| | 1180 | const x86_64 = struct { |
| | 1181 | pub fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void { |
| | 1182 | for (plt_got.symbols.items) |sym_index| { |
| | 1183 | const sym = elf_file.symbol(sym_index); |
| | 1184 | const target_addr = sym.gotAddress(elf_file); |
| | 1185 | const source_addr = sym.pltGotAddress(elf_file); |
| | 1186 | const disp = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr + 6)) - 4; |
| | 1187 | var entry = [_]u8{ |
| | 1188 | 0xf3, 0x0f, 0x1e, 0xfa, // endbr64 |
| | 1189 | 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [rip] -> .got[N] |
| | 1190 | 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, |
| | 1191 | }; |
| | 1192 | mem.writeInt(i32, entry[6..][0..4], @as(i32, @intCast(disp)), .little); |
| | 1193 | try writer.writeAll(&entry); |
| | 1194 | } |
| | 1195 | } |
| | 1196 | }; |
| | 1197 | |
| | 1198 | const aarch64 = struct { |
| | 1199 | fn write(plt_got: PltGotSection, elf_file: *Elf, writer: anytype) !void { |
| | 1200 | for (plt_got.symbols.items) |sym_index| { |
| | 1201 | const sym = elf_file.symbol(sym_index); |
| | 1202 | const target_addr = sym.gotAddress(elf_file); |
| | 1203 | const source_addr = sym.pltGotAddress(elf_file); |
| | 1204 | const pages = try aarch64_util.calcNumberOfPages(source_addr, target_addr); |
| | 1205 | const off = try aarch64_util.calcPageOffset(.load_store_64, target_addr); |
| | 1206 | const insts = &[_]Instruction{ |
| | 1207 | Instruction.adrp(.x16, pages), |
| | 1208 | Instruction.ldr(.x17, .x16, Instruction.LoadStoreOffset.imm(off)), |
| | 1209 | Instruction.br(.x17), |
| | 1210 | Instruction.nop(), |
| | 1211 | }; |
| | 1212 | comptime assert(insts.len == 4); |
| | 1213 | for (insts) |inst| { |
| | 1214 | try writer.writeInt(u32, inst.toU32(), .little); |
| | 1215 | } |
| | 1216 | } |
| | 1217 | } |
| | 1218 | |
| | 1219 | const aarch64_util = @import("../aarch64.zig"); |
| | 1220 | const Instruction = aarch64_util.Instruction; |
| | 1221 | const Register = aarch64_util.Register; |
| | 1222 | }; |
| 1178 | }; | 1223 | }; |
| 1179 | | 1224 | |
| 1180 | pub const CopyRelSection = struct { | 1225 | pub const CopyRelSection = struct { |