| ... | @@ -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 | } |
| 3002 | | 3002 | |
| | 3003 | fn 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 | |
| 3003 | fn collectRebaseData(self: *MachO, rebase: *Rebase) !void { | 3025 | fn 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 | } |
| 3029 | | 3051 | |
| 3030 | // Gather GOT pointers | 3052 | 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 | } | | |
| 3044 | | 3054 | |
| 3045 | try rebase.finalize(gpa); | 3055 | try rebase.finalize(gpa); |
| 3046 | } | 3056 | } |
| 3047 | | 3057 | |
| 3048 | fn collectBindDataFromTableSection(self: *MachO, sect_id: u8, bind: anytype, table: anytype) !void { | 3058 | fn 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; |
| 3050 | | 3063 | |
| 3051 | try bind.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len); | 3064 | try bind.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len); |
| 3052 | | 3065 | |
| 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 | }); |