authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-21 14:00:45+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-04-21 22:44:28+02:00
log14dfbbc21365131c7ac85f08f543058f43fca0c2
tree01029705c92e87c9abf59710ae25826c69b7a73f
parent9a181f367d51acc653379c173b7661f9c69e5ad4

macho: rebase lazy pointers and apply corrected base offset


1 files changed, 29 insertions(+), 20 deletions(-)

src/link/MachO.zig+29-20
...@@ -3000,6 +3000,28 @@ fn writeLinkeditSegmentData(self: *MachO) !void {...@@ -3000,6 +3000,28 @@ fn writeLinkeditSegmentData(self: *MachO) !void {
3000 seg.vmsize = mem.alignForwardGeneric(u64, seg.filesize, self.page_size);3000 seg.vmsize = mem.alignForwardGeneric(u64, seg.filesize, self.page_size);
3001}3001}
30023002
3003fn collectRebaseDataFromTableSection(self: *MachO, sect_id: u8, rebase: *Rebase, table: anytype) !void {
3004 const header = self.sections.items(.header)[sect_id];
3005 const segment_index = self.sections.items(.segment_index)[sect_id];
3006 const segment = self.segments.items[segment_index];
3007 const base_offset = header.addr - segment.vmaddr;
3008 const is_got = if (self.got_section_index) |index| index == sect_id else false;
3009
3010 try rebase.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len);
3011
3012 for (table.entries.items, 0..) |entry, i| {
3013 if (!table.lookup.contains(entry)) continue;
3014 const sym = self.getSymbol(entry);
3015 if (is_got and sym.undf()) continue;
3016 const offset = i * @sizeOf(u64);
3017 log.debug(" | rebase at {x}", .{base_offset + offset});
3018 rebase.entries.appendAssumeCapacity(.{
3019 .offset = base_offset + offset,
3020 .segment_id = segment_index,
3021 });
3022 }
3023}
3024
3003fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {3025fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
3004 const gpa = self.base.allocator;3026 const gpa = self.base.allocator;
3005 const slice = self.sections.slice();3027 const slice = self.sections.slice();
...@@ -3027,49 +3049,36 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {...@@ -3027,49 +3049,36 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
3027 }3049 }
3028 }3050 }
30293051
3030 // Gather GOT pointers3052 try self.collectRebaseDataFromTableSection(self.got_section_index.?, rebase, self.got_table);
3031 try rebase.entries.ensureUnusedCapacity(gpa, self.got_table.entries.items.len);3053 try self.collectRebaseDataFromTableSection(self.la_symbol_ptr_section_index.?, rebase, self.stub_table);
3032 const segment_index = self.sections.items(.segment_index)[self.got_section_index.?];
3033 for (self.got_table.entries.items, 0..) |entry, i| {
3034 if (!self.got_table.lookup.contains(entry)) continue;
3035 const sym = self.getSymbol(entry);
3036 if (sym.undf()) continue;
3037 const offset = i * @sizeOf(u64);
3038 log.debug(" | rebase at {x}", .{offset});
3039 rebase.entries.appendAssumeCapacity(.{
3040 .offset = offset,
3041 .segment_id = segment_index,
3042 });
3043 }
30443054
3045 try rebase.finalize(gpa);3055 try rebase.finalize(gpa);
3046}3056}
30473057
3048fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, table: anytype) !void {3058fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, table: anytype) !void {
3059 const header = self.sections.items(.header)[sect_id];
3049 const segment_index = self.sections.items(.segment_index)[sect_id];3060 const segment_index = self.sections.items(.segment_index)[sect_id];
3061 const segment = self.segments.items[segment_index];
3062 const base_offset = header.addr - segment.vmaddr;
30503063
3051 try bind.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len);3064 try bind.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len);
30523065
3053 for (table.entries.items, 0..) |entry, i| {3066 for (table.entries.items, 0..) |entry, i| {
3054 if (!table.lookup.contains(entry)) continue;3067 if (!table.lookup.contains(entry)) continue;
3055
3056 const bind_sym = self.getSymbol(entry);3068 const bind_sym = self.getSymbol(entry);
3057 if (!bind_sym.undf()) continue;3069 if (!bind_sym.undf()) continue;
3058
3059 const offset = i * @sizeOf(u64);3070 const offset = i * @sizeOf(u64);
3060
3061 log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{3071 log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{
3062 offset,3072 base_offset + offset,
3063 self.getSymbolName(entry),3073 self.getSymbolName(entry),
3064 @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),3074 @divTrunc(@bitCast(i16, bind_sym.n_desc), macho.N_SYMBOL_RESOLVER),
3065 });3075 });
3066 if (bind_sym.weakRef()) {3076 if (bind_sym.weakRef()) {
3067 log.debug(" | marking as weak ref ", .{});3077 log.debug(" | marking as weak ref ", .{});
3068 }3078 }
3069
3070 bind.entries.appendAssumeCapacity(.{3079 bind.entries.appendAssumeCapacity(.{
3071 .target = entry,3080 .target = entry,
3072 .offset = offset,3081 .offset = base_offset + offset,
3073 .segment_id = segment_index,3082 .segment_id = segment_index,
3074 .addend = 0,3083 .addend = 0,
3075 });3084 });