aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-04-21 14:00:45 +0200
committerJakub Konka <kubkon@jakubkonka.com>2023-04-21 22:44:28 +0200
commit14dfbbc21365131c7ac85f08f543058f43fca0c2 (patch)
tree01029705c92e87c9abf59710ae25826c69b7a73f /src
parent9a181f367d51acc653379c173b7661f9c69e5ad4 (diff)
downloadzig-14dfbbc21365131c7ac85f08f543058f43fca0c2.tar.gz
zig-14dfbbc21365131c7ac85f08f543058f43fca0c2.zip
macho: rebase lazy pointers and apply corrected base offset
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig49
1 files changed, 29 insertions, 20 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 8975f38570..47954f8871 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -3000,6 +3000,28 @@ fn writeLinkeditSegmentData(self: *MachO) !void {
seg.vmsize = mem.alignForwardGeneric(u64, seg.filesize, self.page_size);
}
+fn collectRebaseDataFromTableSection(self: *MachO, sect_id: u8, rebase: *Rebase, table: anytype) !void {
+ const header = self.sections.items(.header)[sect_id];
+ const segment_index = self.sections.items(.segment_index)[sect_id];
+ const segment = self.segments.items[segment_index];
+ const base_offset = header.addr - segment.vmaddr;
+ const is_got = if (self.got_section_index) |index| index == sect_id else false;
+
+ try rebase.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len);
+
+ for (table.entries.items, 0..) |entry, i| {
+ if (!table.lookup.contains(entry)) continue;
+ const sym = self.getSymbol(entry);
+ if (is_got and sym.undf()) continue;
+ const offset = i * @sizeOf(u64);
+ log.debug(" | rebase at {x}", .{base_offset + offset});
+ rebase.entries.appendAssumeCapacity(.{
+ .offset = base_offset + offset,
+ .segment_id = segment_index,
+ });
+ }
+}
+
fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
const gpa = self.base.allocator;
const slice = self.sections.slice();
@@ -3027,49 +3049,36 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
}
}
- // Gather GOT pointers
- try rebase.entries.ensureUnusedCapacity(gpa, self.got_table.entries.items.len);
- const segment_index = self.sections.items(.segment_index)[self.got_section_index.?];
- for (self.got_table.entries.items, 0..) |entry, i| {
- if (!self.got_table.lookup.contains(entry)) continue;
- const sym = self.getSymbol(entry);
- if (sym.undf()) continue;
- const offset = i * @sizeOf(u64);
- log.debug(" | rebase at {x}", .{offset});
- rebase.entries.appendAssumeCapacity(.{
- .offset = offset,
- .segment_id = segment_index,
- });
- }
+ try self.collectRebaseDataFromTableSection(self.got_section_index.?, rebase, self.got_table);
+ try self.collectRebaseDataFromTableSection(self.la_symbol_ptr_section_index.?, rebase, self.stub_table);
try rebase.finalize(gpa);
}
fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, table: anytype) !void {
+ const header = self.sections.items(.header)[sect_id];
const segment_index = self.sections.items(.segment_index)[sect_id];
+ const segment = self.segments.items[segment_index];
+ const base_offset = header.addr - segment.vmaddr;
try bind.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len);
for (table.entries.items, 0..) |entry, i| {
if (!table.lookup.contains(entry)) continue;
-
const bind_sym = self.getSymbol(entry);
if (!bind_sym.undf()) continue;
-
const offset = i * @sizeOf(u64);
-
log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{
- offset,
+ base_offset + offset,
self.getSymbolName(entry),
@divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),
});
if (bind_sym.weakRef()) {
log.debug(" | marking as weak ref ", .{});
}
-
bind.entries.appendAssumeCapacity(.{
.target = entry,
- .offset = offset,
+ .offset = base_offset + offset,
.segment_id = segment_index,
.addend = 0,
});