Commit 04e93dd265
Changed files (6)
src/link/MachO/Atom.zig
@@ -358,10 +358,7 @@ pub fn parseRelocTarget(zld: *Zld, ctx: struct {
return target;
}
-pub fn getRelocTargetAtomIndex(zld: *Zld, target: SymbolWithLoc, is_via_got: bool) ?Index {
- if (is_via_got) {
- return zld.getGotAtomIndexForSymbol(target).?; // panic means fatal error
- }
+pub fn getRelocTargetAtomIndex(zld: *Zld, target: SymbolWithLoc) ?Index {
if (zld.getStubsAtomIndexForSymbol(target)) |stubs_atom| return stubs_atom;
if (zld.getTlvPtrAtomIndexForSymbol(target)) |tlv_ptr_atom| return tlv_ptr_atom;
@@ -411,7 +408,7 @@ fn scanAtomRelocsArm64(zld: *Zld, atom_index: Index, relocs: []align(1) const ma
.ARM64_RELOC_POINTER_TO_GOT,
=> {
// TODO rewrite relocation
- try addGotEntry(zld, target);
+ try zld.addGotEntry(target);
},
.ARM64_RELOC_TLVP_LOAD_PAGE21,
.ARM64_RELOC_TLVP_LOAD_PAGEOFF12,
@@ -454,7 +451,7 @@ fn scanAtomRelocsX86(zld: *Zld, atom_index: Index, relocs: []align(1) const mach
},
.X86_64_RELOC_GOT, .X86_64_RELOC_GOT_LOAD => {
// TODO rewrite relocation
- try addGotEntry(zld, target);
+ try zld.addGotEntry(target);
},
.X86_64_RELOC_TLV => {
try addTlvPtrEntry(zld, target);
@@ -479,18 +476,6 @@ fn addTlvPtrEntry(zld: *Zld, target: SymbolWithLoc) !void {
try zld.tlv_ptr_table.putNoClobber(gpa, target, tlv_ptr_index);
}
-pub fn addGotEntry(zld: *Zld, target: SymbolWithLoc) !void {
- if (zld.got_table.contains(target)) return;
- const gpa = zld.gpa;
- const atom_index = try zld.createGotAtom();
- const got_index = @as(u32, @intCast(zld.got_entries.items.len));
- try zld.got_entries.append(gpa, .{
- .target = target,
- .atom_index = atom_index,
- });
- try zld.got_table.putNoClobber(gpa, target, got_index);
-}
-
pub fn addStub(zld: *Zld, target: SymbolWithLoc) !void {
const target_sym = zld.getSymbol(target);
if (!target_sym.undf()) return;
@@ -532,8 +517,8 @@ pub fn resolveRelocs(
};
}
-pub fn getRelocTargetAddress(zld: *Zld, target: SymbolWithLoc, is_via_got: bool, is_tlv: bool) !u64 {
- const target_atom_index = getRelocTargetAtomIndex(zld, target, is_via_got) orelse {
+pub fn getRelocTargetAddress(zld: *Zld, target: SymbolWithLoc, is_tlv: bool) !u64 {
+ const target_atom_index = getRelocTargetAtomIndex(zld, target) orelse {
// If there is no atom for target, we still need to check for special, atom-less
// symbols such as `___dso_handle`.
const target_name = zld.getSymbolName(target);
@@ -656,7 +641,10 @@ fn resolveRelocsArm64(
const header = zld.sections.items(.header)[source_sym.n_sect - 1];
break :is_tlv header.type() == macho.S_THREAD_LOCAL_VARIABLES;
};
- const target_addr = try getRelocTargetAddress(zld, target, is_via_got, is_tlv);
+ const target_addr = if (is_via_got)
+ zld.getGotEntryAddress(target).?
+ else
+ try getRelocTargetAddress(zld, target, is_tlv);
log.debug(" | source_addr = 0x{x}", .{source_addr});
@@ -670,7 +658,7 @@ fn resolveRelocsArm64(
zld.getSymbolName(atom.getSymbolWithLoc()),
atom.getFile(),
zld.getSymbolName(target),
- zld.getAtom(getRelocTargetAtomIndex(zld, target, is_via_got).?).getFile(),
+ zld.getAtom(getRelocTargetAtomIndex(zld, target).?).getFile(),
});
const displacement = if (Relocation.calcPcRelativeDisplacementArm64(
@@ -953,7 +941,10 @@ fn resolveRelocsX86(
log.debug(" | source_addr = 0x{x}", .{source_addr});
- const target_addr = try getRelocTargetAddress(zld, target, is_via_got, is_tlv);
+ const target_addr = if (is_via_got)
+ zld.getGotEntryAddress(target).?
+ else
+ try getRelocTargetAddress(zld, target, is_tlv);
switch (rel_type) {
.X86_64_RELOC_BRANCH => {
src/link/MachO/eh_frame.zig
@@ -267,7 +267,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
source_offset: u32,
) !void {
if (rec.getPersonalityPointerReloc(zld, object_id, source_offset)) |target| {
- try Atom.addGotEntry(zld, target);
+ try zld.addGotEntry(target);
}
}
@@ -357,14 +357,14 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
// Address of the __eh_frame in the source object file
},
.ARM64_RELOC_POINTER_TO_GOT => {
- const target_addr = try Atom.getRelocTargetAddress(zld, target, true, false);
+ const target_addr = zld.getGotEntryAddress(target).?;
const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse
return error.Overflow;
mem.writeIntLittle(i32, rec.data[rel_offset..][0..4], result);
},
.ARM64_RELOC_UNSIGNED => {
assert(rel.r_extern == 1);
- const target_addr = try Atom.getRelocTargetAddress(zld, target, false, false);
+ const target_addr = try Atom.getRelocTargetAddress(zld, target, false);
const result = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr));
mem.writeIntLittle(i64, rec.data[rel_offset..][0..8], @as(i64, @intCast(result)));
},
@@ -375,7 +375,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type));
switch (rel_type) {
.X86_64_RELOC_GOT => {
- const target_addr = try Atom.getRelocTargetAddress(zld, target, true, false);
+ const target_addr = zld.getGotEntryAddress(target).?;
const addend = mem.readIntLittle(i32, rec.data[rel_offset..][0..4]);
const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);
src/link/MachO/thunks.zig
@@ -318,7 +318,10 @@ fn isReachable(
const source_addr = source_sym.n_value + @as(u32, @intCast(rel.r_address - base_offset));
const is_via_got = Atom.relocRequiresGot(zld, rel);
- const target_addr = Atom.getRelocTargetAddress(zld, target, is_via_got, false) catch unreachable;
+ const target_addr = if (is_via_got)
+ zld.getGotEntryAddress(target).?
+ else
+ Atom.getRelocTargetAddress(zld, target, false) catch unreachable;
_ = Relocation.calcPcRelativeDisplacementArm64(source_addr, target_addr) catch
return false;
src/link/MachO/UnwindInfo.zig
@@ -226,7 +226,7 @@ pub fn scanRelocs(zld: *Zld) !void {
.code = mem.asBytes(&record),
.base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
});
- try Atom.addGotEntry(zld, target);
+ try zld.addGotEntry(target);
}
}
}
@@ -585,10 +585,8 @@ pub fn write(info: *UnwindInfo, zld: *Zld) !void {
log.debug("Personalities:", .{});
for (info.personalities[0..info.personalities_count], 0..) |target, i| {
- const atom_index = zld.getGotAtomIndexForSymbol(target).?;
- const atom = zld.getAtom(atom_index);
- const sym = zld.getSymbol(atom.getSymbolWithLoc());
- personalities[i] = @as(u32, @intCast(sym.n_value - seg.vmaddr));
+ const addr = zld.getGotEntryAddress(target).?;
+ personalities[i] = @as(u32, @intCast(addr - seg.vmaddr));
log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], zld.getSymbolName(target) });
}
src/link/MachO/zld.zig
@@ -35,6 +35,7 @@ const Section = MachO.Section;
const StringTable = @import("../strtab.zig").StringTable;
const SymbolWithLoc = MachO.SymbolWithLoc;
const SymbolResolver = MachO.SymbolResolver;
+const TableSection = @import("../table_section.zig").TableSection;
const Trie = @import("Trie.zig");
const UnwindInfo = @import("UnwindInfo.zig");
@@ -66,6 +67,8 @@ pub const Zld = struct {
segments: std.ArrayListUnmanaged(macho.segment_command_64) = .{},
sections: std.MultiArrayList(Section) = .{},
+ got_section_index: ?u8 = null,
+
locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{},
@@ -81,8 +84,7 @@ pub const Zld = struct {
tlv_ptr_entries: std.ArrayListUnmanaged(IndirectPointer) = .{},
tlv_ptr_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
- got_entries: std.ArrayListUnmanaged(IndirectPointer) = .{},
- got_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
+ got_table: TableSection(SymbolWithLoc) = .{},
stubs: std.ArrayListUnmanaged(IndirectPointer) = .{},
stubs_table: std.AutoHashMapUnmanaged(SymbolWithLoc, u32) = .{},
@@ -266,32 +268,6 @@ pub const Zld = struct {
return index;
}
- pub fn createGotAtom(self: *Zld) !AtomIndex {
- const sym_index = try self.allocateSymbol();
- const atom_index = try self.createEmptyAtom(sym_index, @sizeOf(u64), 3);
- const sym = self.getSymbolPtr(.{ .sym_index = sym_index });
- sym.n_type = macho.N_SECT;
-
- const sect_id = self.getSectionByName("__DATA_CONST", "__got") orelse
- try self.initSection("__DATA_CONST", "__got", .{
- .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
- });
- sym.n_sect = sect_id + 1;
-
- self.addAtomToSection(atom_index);
-
- return atom_index;
- }
-
- fn writeGotPointer(self: *Zld, got_index: u32, writer: anytype) !void {
- const target_addr = blk: {
- const entry = self.got_entries.items[got_index];
- const sym = entry.getTargetSymbol(self);
- break :blk sym.n_value;
- };
- try writer.writeIntLittle(u64, target_addr);
- }
-
pub fn createTlvPtrAtom(self: *Zld) !AtomIndex {
const sym_index = try self.allocateSymbol();
const atom_index = try self.createEmptyAtom(sym_index, @sizeOf(u64), 3);
@@ -311,16 +287,9 @@ pub const Zld = struct {
}
fn createDyldStubBinderGotAtom(self: *Zld) !void {
- const gpa = self.gpa;
const global_index = self.dyld_stub_binder_index orelse return;
const target = self.globals.items[global_index];
- const atom_index = try self.createGotAtom();
- const got_index = @as(u32, @intCast(self.got_entries.items.len));
- try self.got_entries.append(gpa, .{
- .target = target,
- .atom_index = atom_index,
- });
- try self.got_table.putNoClobber(gpa, target, got_index);
+ try self.addGotEntry(target);
}
fn createDyldPrivateAtom(self: *Zld) !void {
@@ -381,9 +350,7 @@ pub const Zld = struct {
};
const dyld_stub_binder_got_addr = blk: {
const sym_loc = self.globals.items[self.dyld_stub_binder_index.?];
- const index = self.got_table.get(sym_loc).?;
- const entry = self.got_entries.items[index];
- break :blk entry.getAtomSymbol(self).n_value;
+ break :blk self.getGotEntryAddress(sym_loc).?;
};
try stub_helpers.writeStubHelperPreambleCode(.{
.cpu_arch = cpu_arch,
@@ -876,7 +843,6 @@ pub const Zld = struct {
self.tlv_ptr_entries.deinit(gpa);
self.tlv_ptr_table.deinit(gpa);
- self.got_entries.deinit(gpa);
self.got_table.deinit(gpa);
self.stubs.deinit(gpa);
self.stubs_table.deinit(gpa);
@@ -993,6 +959,16 @@ pub const Zld = struct {
return global_index;
}
+ pub fn addGotEntry(zld: *Zld, target: SymbolWithLoc) !void {
+ if (zld.got_table.lookup.contains(target)) return;
+ _ = try zld.got_table.allocateEntry(zld.gpa, target);
+ if (zld.got_section_index == null) {
+ zld.got_section_index = try zld.initSection("__DATA_CONST", "__got", .{
+ .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
+ });
+ }
+ }
+
fn allocateSpecialSymbols(self: *Zld) !void {
for (&[_]?u32{
self.dso_handle_index,
@@ -1056,9 +1032,7 @@ pub const Zld = struct {
buffer.appendSliceAssumeCapacity(&[_]u8{0} ** @sizeOf(u64));
} else if (atom.getFile() == null) outer: {
switch (header.type()) {
- macho.S_NON_LAZY_SYMBOL_POINTERS => {
- try self.writeGotPointer(count, buffer.writer());
- },
+ macho.S_NON_LAZY_SYMBOL_POINTERS => unreachable,
macho.S_LAZY_SYMBOL_POINTERS => {
try self.writeLazyPointer(count, buffer.writer());
},
@@ -1113,41 +1087,70 @@ pub const Zld = struct {
}
}
+ fn writeGotEntries(self: *Zld) !void {
+ const sect_id = self.got_section_index orelse return;
+ const header = self.sections.items(.header)[sect_id];
+ var buffer = try std.ArrayList(u8).initCapacity(self.gpa, header.size);
+ defer buffer.deinit();
+ for (self.got_table.entries.items) |entry| {
+ const sym = self.getSymbol(entry);
+ buffer.writer().writeIntLittle(u64, sym.n_value) catch unreachable;
+ }
+ log.debug("writing .got contents at file offset 0x{x}", .{header.offset});
+ try self.file.pwriteAll(buffer.items, header.offset);
+ }
+
fn pruneAndSortSections(self: *Zld) !void {
- const gpa = self.gpa;
+ const Entry = struct {
+ index: u8,
- const SortSection = struct {
- pub fn lessThan(_: void, lhs: Section, rhs: Section) bool {
- return getSectionPrecedence(lhs.header) < getSectionPrecedence(rhs.header);
+ pub fn lessThan(zld: *Zld, lhs: @This(), rhs: @This()) bool {
+ const lhs_header = zld.sections.items(.header)[lhs.index];
+ const rhs_header = zld.sections.items(.header)[rhs.index];
+ return getSectionPrecedence(lhs_header) < getSectionPrecedence(rhs_header);
}
};
- const slice = self.sections.slice();
- var sections = std.ArrayList(Section).init(gpa);
- defer sections.deinit();
- try sections.ensureTotalCapacity(slice.len);
+ const gpa = self.gpa;
- {
- var i: u8 = 0;
- while (i < slice.len) : (i += 1) {
- const section = self.sections.get(i);
- if (section.header.size == 0) {
- log.debug("pruning section {s},{s} {?d}", .{
- section.header.segName(),
- section.header.sectName(),
- section.first_atom_index,
- });
- continue;
- }
- sections.appendAssumeCapacity(section);
+ var entries = try std.ArrayList(Entry).initCapacity(gpa, self.sections.slice().len);
+ defer entries.deinit();
+
+ for (0..self.sections.slice().len) |index| {
+ const section = self.sections.get(index);
+ if (section.header.size == 0) {
+ log.debug("pruning section {s},{s} {?d}", .{
+ section.header.segName(),
+ section.header.sectName(),
+ section.first_atom_index,
+ });
+ continue;
}
+ entries.appendAssumeCapacity(.{ .index = @intCast(index) });
+ }
+
+ mem.sort(Entry, entries.items, self, Entry.lessThan);
+
+ var slice = self.sections.toOwnedSlice();
+ defer slice.deinit(gpa);
+
+ const backlinks = try gpa.alloc(u8, slice.len);
+ defer gpa.free(backlinks);
+ for (entries.items, 0..) |entry, i| {
+ backlinks[entry.index] = @as(u8, @intCast(i));
}
- mem.sort(Section, sections.items, {}, SortSection.lessThan);
+ try self.sections.ensureTotalCapacity(gpa, entries.items.len);
+ for (entries.items) |entry| {
+ self.sections.appendAssumeCapacity(slice.get(entry.index));
+ }
- self.sections.shrinkRetainingCapacity(0);
- for (sections.items) |out| {
- self.sections.appendAssumeCapacity(out);
+ for (&[_]*?u8{
+ &self.got_section_index,
+ }) |maybe_index| {
+ if (maybe_index.*) |*index| {
+ index.* = backlinks[index.*];
+ }
}
}
@@ -1227,6 +1230,12 @@ pub const Zld = struct {
} else break;
}
}
+
+ if (self.got_section_index) |sect_id| {
+ const header = &self.sections.items(.header)[sect_id];
+ header.size = self.got_table.count() * @sizeOf(u64);
+ header.@"align" = 3;
+ }
}
fn allocateSegments(self: *Zld) !void {
@@ -1448,40 +1457,12 @@ pub const Zld = struct {
seg.vmsize = mem.alignForward(u64, seg.filesize, MachO.getPageSize(self.options.target.cpu.arch));
}
- fn collectRebaseDataFromContainer(
- self: *Zld,
- sect_id: u8,
- rebase: *Rebase,
- container: anytype,
- ) !void {
- const slice = self.sections.slice();
- const segment_index = slice.items(.segment_index)[sect_id];
- const seg = self.getSegment(sect_id);
-
- try rebase.entries.ensureUnusedCapacity(self.gpa, container.items.len);
-
- for (container.items) |entry| {
- const target_sym = entry.getTargetSymbol(self);
- if (target_sym.undf()) continue;
-
- const atom_sym = entry.getAtomSymbol(self);
- const base_offset = atom_sym.n_value - seg.vmaddr;
-
- log.debug(" | rebase at {x}", .{base_offset});
-
- rebase.entries.appendAssumeCapacity(.{
- .offset = base_offset,
- .segment_id = segment_index,
- });
- }
- }
-
fn collectRebaseData(self: *Zld, rebase: *Rebase) !void {
log.debug("collecting rebase data", .{});
// First, unpack GOT entries
- if (self.getSectionByName("__DATA_CONST", "__got")) |sect_id| {
- try self.collectRebaseDataFromContainer(sect_id, rebase, self.got_entries);
+ if (self.got_section_index) |sect_id| {
+ try MachO.collectRebaseDataFromTableSection(self.gpa, self, sect_id, rebase, self.got_table);
}
const slice = self.sections.slice();
@@ -1543,7 +1524,11 @@ pub const Zld = struct {
};
if (should_rebase) {
- log.debug(" ATOM({d}, %{d}, '{s}')", .{ atom_index, atom.sym_index, self.getSymbolName(atom.getSymbolWithLoc()) });
+ log.debug(" ATOM({d}, %{d}, '{s}')", .{
+ atom_index,
+ atom.sym_index,
+ self.getSymbolName(atom.getSymbolWithLoc()),
+ });
const code = Atom.getAtomCode(self, atom_index);
const relocs = Atom.getAtomRelocs(self, atom_index);
@@ -1639,8 +1624,8 @@ pub const Zld = struct {
log.debug("collecting bind data", .{});
// First, unpack GOT section
- if (self.getSectionByName("__DATA_CONST", "__got")) |sect_id| {
- try self.collectBindDataFromContainer(sect_id, bind, self.got_entries);
+ if (self.got_section_index) |sect_id| {
+ try MachO.collectBindDataFromTableSection(self.gpa, self, sect_id, bind, self.got_table);
}
// Next, unpack TLV pointers section
@@ -2237,7 +2222,7 @@ pub const Zld = struct {
fn writeDysymtab(self: *Zld, ctx: SymtabCtx) !void {
const gpa = self.gpa;
const nstubs = @as(u32, @intCast(self.stubs.items.len));
- const ngot_entries = @as(u32, @intCast(self.got_entries.items.len));
+ const ngot_entries = @as(u32, @intCast(self.got_table.lookup.count()));
const nindirectsyms = nstubs * 2 + ngot_entries;
const iextdefsym = ctx.nlocalsym;
const iundefsym = iextdefsym + ctx.nextdefsym;
@@ -2266,13 +2251,14 @@ pub const Zld = struct {
}
}
- if (self.getSectionByName("__DATA_CONST", "__got")) |sect_id| {
+ if (self.got_section_index) |sect_id| {
const got = &self.sections.items(.header)[sect_id];
got.reserved1 = nstubs;
- for (self.got_entries.items) |entry| {
- const target_sym = entry.getTargetSymbol(self);
+ for (self.got_table.entries.items) |entry| {
+ if (!self.got_table.lookup.contains(entry)) continue;
+ const target_sym = self.getSymbol(entry);
if (target_sym.undf()) {
- try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry.target).?);
+ try writer.writeIntLittle(u32, iundefsym + ctx.imports_table.get(entry).?);
} else {
try writer.writeIntLittle(u32, macho.INDIRECT_SYMBOL_LOCAL);
}
@@ -2496,12 +2482,10 @@ pub const Zld = struct {
}
}
- /// Returns GOT atom that references `sym_with_loc` if one exists.
- /// Returns null otherwise.
- pub fn getGotAtomIndexForSymbol(self: *Zld, sym_with_loc: SymbolWithLoc) ?AtomIndex {
- const index = self.got_table.get(sym_with_loc) orelse return null;
- const entry = self.got_entries.items[index];
- return entry.atom_index;
+ pub fn getGotEntryAddress(self: *Zld, sym_with_loc: SymbolWithLoc) ?u64 {
+ const index = self.got_table.lookup.get(sym_with_loc) orelse return null;
+ const header = self.sections.items(.header)[self.got_section_index.?];
+ return header.addr + @sizeOf(u64) * index;
}
/// Returns stubs atom that references `sym_with_loc` if one exists.
@@ -2849,26 +2833,7 @@ pub const Zld = struct {
}
scoped_log.debug("GOT entries:", .{});
- for (self.got_entries.items, 0..) |entry, i| {
- const atom_sym = entry.getAtomSymbol(self);
- const target_sym = entry.getTargetSymbol(self);
- const target_sym_name = entry.getTargetSymbolName(self);
- if (target_sym.undf()) {
- scoped_log.debug(" {d}@{x} => import('{s}')", .{
- i,
- atom_sym.n_value,
- target_sym_name,
- });
- } else {
- scoped_log.debug(" {d}@{x} => local(%{d}) in object({?}) {s}", .{
- i,
- atom_sym.n_value,
- entry.target.sym_index,
- entry.target.file,
- logSymAttributes(target_sym, buf[0..4]),
- });
- }
- }
+ scoped_log.debug("{}", .{self.got_table});
scoped_log.debug("__thread_ptrs entries:", .{});
for (self.tlv_ptr_entries.items, 0..) |entry, i| {
@@ -3470,6 +3435,7 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
}
try zld.writeAtoms();
+ try zld.writeGotEntries();
try eh_frame.write(&zld, &unwind_info);
try unwind_info.write(&zld);
try zld.writeLinkeditSegmentData();
src/link/MachO.zig
@@ -3222,18 +3222,24 @@ fn writeLinkeditSegmentData(self: *MachO) !void {
seg.vmsize = mem.alignForward(u64, seg.filesize, 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];
+pub fn collectRebaseDataFromTableSection(
+ gpa: Allocator,
+ ctx: anytype,
+ sect_id: u8,
+ rebase: *Rebase,
+ table: anytype,
+) !void {
+ const header = ctx.sections.items(.header)[sect_id];
+ const segment_index = ctx.sections.items(.segment_index)[sect_id];
+ const segment = ctx.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;
+ const is_got = if (ctx.got_section_index) |index| index == sect_id else false;
- try rebase.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len);
+ try rebase.entries.ensureUnusedCapacity(gpa, table.entries.items.len);
for (table.entries.items, 0..) |entry, i| {
if (!table.lookup.contains(entry)) continue;
- const sym = self.getSymbol(entry);
+ const sym = ctx.getSymbol(entry);
if (is_got and sym.undf()) continue;
const offset = i * @sizeOf(u64);
log.debug(" | rebase at {x}", .{base_offset + offset});
@@ -3271,28 +3277,34 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
}
}
- 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 collectRebaseDataFromTableSection(gpa, self, self.got_section_index.?, rebase, self.got_table);
+ try collectRebaseDataFromTableSection(gpa, self, 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];
+pub fn collectBindDataFromTableSection(
+ gpa: Allocator,
+ ctx: anytype,
+ sect_id: u8,
+ bind: anytype,
+ table: anytype,
+) !void {
+ const header = ctx.sections.items(.header)[sect_id];
+ const segment_index = ctx.sections.items(.segment_index)[sect_id];
+ const segment = ctx.segments.items[segment_index];
const base_offset = header.addr - segment.vmaddr;
- try bind.entries.ensureUnusedCapacity(self.base.allocator, table.entries.items.len);
+ try bind.entries.ensureUnusedCapacity(gpa, table.entries.items.len);
for (table.entries.items, 0..) |entry, i| {
if (!table.lookup.contains(entry)) continue;
- const bind_sym = self.getSymbol(entry);
+ const bind_sym = ctx.getSymbol(entry);
if (!bind_sym.undf()) continue;
const offset = i * @sizeOf(u64);
log.debug(" | bind at {x}, import('{s}') in dylib({d})", .{
base_offset + offset,
- self.getSymbolName(entry),
+ ctx.getSymbolName(entry),
@divTrunc(@as(i16, @bitCast(bind_sym.n_desc)), macho.N_SYMBOL_RESOLVER),
});
if (bind_sym.weakRef()) {
@@ -3349,12 +3361,12 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
}
// Gather GOT pointers
- try self.collectBindDataFromTableSection(self.got_section_index.?, bind, self.got_table);
+ try collectBindDataFromTableSection(gpa, self, self.got_section_index.?, bind, self.got_table);
try bind.finalize(gpa, self);
}
fn collectLazyBindData(self: *MachO, bind: anytype) !void {
- try self.collectBindDataFromTableSection(self.la_symbol_ptr_section_index.?, bind, self.stub_table);
+ try collectBindDataFromTableSection(self.base.allocator, self, self.la_symbol_ptr_section_index.?, bind, self.stub_table);
try bind.finalize(self.base.allocator, self);
}