authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-01 18:18:04+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-04-13 10:56:03+02:00
log1b5bceec910778ced3c03b885bddd31f1aac3842
tree9cac2f009a1cb9efa315b7a3b86a75a1d7f86449
parent04659f5b82cadb60112f00466ce1ce5b24b562f1

zld: start work on reloc preprocessing


1 files changed, 57 insertions(+), 0 deletions(-)

src/link/MachO/Object.zig+57
...@@ -97,6 +97,13 @@ pub fn parse(self: *Object) !void {...@@ -97,6 +97,13 @@ pub fn parse(self: *Object) !void {
97 try self.readLoadCommands(reader);97 try self.readLoadCommands(reader);
98 if (self.symtab_cmd_index != null) try self.parseSymtab();98 if (self.symtab_cmd_index != null) try self.parseSymtab();
99 if (self.data_in_code_cmd_index != null) try self.readDataInCode();99 if (self.data_in_code_cmd_index != null) try self.readDataInCode();
100
101 {
102 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;
103 for (seg.sections.items) |_, sect_id| {
104 try self.parseRelocs(@intCast(u16, sect_id));
105 }
106 }
100}107}
101108
102pub fn readLoadCommands(self: *Object, reader: anytype) !void {109pub fn readLoadCommands(self: *Object, reader: anytype) !void {
...@@ -163,6 +170,56 @@ pub fn readLoadCommands(self: *Object, reader: anytype) !void {...@@ -163,6 +170,56 @@ pub fn readLoadCommands(self: *Object, reader: anytype) !void {
163 }170 }
164}171}
165172
173pub fn parseRelocs(self: *Object, sect_id: u16) !void {
174 const seg = self.load_commands.items[self.segment_cmd_index.?].Segment;
175 const sect = seg.sections.items[sect_id];
176
177 if (sect.nreloc == 0) return;
178
179 var raw_relocs = try self.allocator.alloc(u8, @sizeOf(macho.relocation_info) * sect.nreloc);
180 defer self.allocator.free(raw_relocs);
181 _ = try self.file.?.preadAll(raw_relocs, sect.reloff);
182 const relocs = mem.bytesAsSlice(macho.relocation_info, raw_relocs);
183
184 for (relocs) |reloc| {
185 const is_addend = is_addend: {
186 switch (self.arch.?) {
187 .x86_64 => {
188 const rel_type = @intToEnum(macho.reloc_type_x86_64, reloc.r_type);
189 log.warn("{s}", .{rel_type});
190
191 break :is_addend false;
192 },
193 .aarch64 => {
194 const rel_type = @intToEnum(macho.reloc_type_arm64, reloc.r_type);
195 log.warn("{s}", .{rel_type});
196
197 break :is_addend rel_type == .ARM64_RELOC_ADDEND;
198 },
199 else => unreachable,
200 }
201 };
202
203 if (!is_addend) {
204 if (reloc.r_extern == 1) {
205 const sym = self.symtab.items[reloc.r_symbolnum];
206 const sym_name = self.getString(sym.inner.n_strx);
207 log.warn(" | symbol = {s}", .{sym_name});
208 } else {
209 const target_sect = seg.sections.items[reloc.r_symbolnum - 1];
210 log.warn(" | section = {s},{s}", .{
211 parseName(&target_sect.segname),
212 parseName(&target_sect.sectname),
213 });
214 }
215 }
216
217 log.warn(" | offset = 0x{x}", .{reloc.r_address});
218 log.warn(" | PC = {}", .{reloc.r_pcrel == 1});
219 log.warn(" | length = {}", .{reloc.r_length});
220 }
221}
222
166pub fn parseSymtab(self: *Object) !void {223pub fn parseSymtab(self: *Object) !void {
167 const symtab_cmd = self.load_commands.items[self.symtab_cmd_index.?].Symtab;224 const symtab_cmd = self.load_commands.items[self.symtab_cmd_index.?].Symtab;
168225