macho: unify Section concept across drivers

This commit is contained in:
Jakub Konka 2023-08-21 22:17:34 +02:00
parent 05c9d6c00b
commit e1e0ccb0c7
5 changed files with 27 additions and 46 deletions

View File

@ -69,12 +69,10 @@ pub const Mode = enum {
zld,
};
const Section = struct {
pub const Section = struct {
header: macho.section_64,
segment_index: u8,
// TODO is null here necessary, or can we do away with tracking via section
// size in incremental context?
first_atom_index: ?Atom.Index = null,
last_atom_index: ?Atom.Index = null,
/// A list of atoms that have surplus capacity. This list can have false

View File

@ -55,7 +55,7 @@ source_section_index_lookup: []Entry = undefined,
/// Can be undefined as set together with in_symtab.
strtab_lookup: []u32 = undefined,
/// Can be undefined as set together with in_symtab.
atom_by_index_table: []AtomIndex = undefined,
atom_by_index_table: []?AtomIndex = undefined,
/// Can be undefined as set together with in_symtab.
globals_lookup: []i64 = undefined,
/// Can be undefined as set together with in_symtab.
@ -156,7 +156,7 @@ pub fn parse(self: *Object, allocator: Allocator) !void {
self.reverse_symtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len);
self.strtab_lookup = try allocator.alloc(u32, self.in_symtab.?.len);
self.globals_lookup = try allocator.alloc(i64, self.in_symtab.?.len);
self.atom_by_index_table = try allocator.alloc(AtomIndex, self.in_symtab.?.len + nsects);
self.atom_by_index_table = try allocator.alloc(?AtomIndex, self.in_symtab.?.len + nsects);
self.relocs_lookup = try allocator.alloc(Entry, self.in_symtab.?.len + nsects);
// This is wasteful but we need to be able to lookup source symbol address after stripping and
// allocating of sections.
@ -174,7 +174,7 @@ pub fn parse(self: *Object, allocator: Allocator) !void {
}
@memset(self.globals_lookup, -1);
@memset(self.atom_by_index_table, 0);
@memset(self.atom_by_index_table, null);
@memset(self.source_section_index_lookup, .{});
@memset(self.relocs_lookup, .{});
@ -1060,9 +1060,7 @@ pub fn getGlobal(self: Object, sym_index: u32) ?u32 {
}
pub fn getAtomIndexForSymbol(self: Object, sym_index: u32) ?AtomIndex {
const atom_index = self.atom_by_index_table[sym_index];
if (atom_index == 0) return null;
return atom_index;
return self.atom_by_index_table[sym_index];
}
pub fn hasUnwindRecords(self: Object) bool {

View File

@ -466,8 +466,8 @@ fn prune(zld: *Zld, alive: AtomTable) void {
section.last_atom_index = prev_index;
} else {
assert(section.header.size == 0);
section.first_atom_index = 0;
section.last_atom_index = 0;
section.first_atom_index = null;
section.last_atom_index = null;
}
}

View File

@ -75,7 +75,7 @@ pub fn createThunks(zld: *Zld, sect_id: u8) !void {
if (header.size == 0) return;
const gpa = zld.gpa;
const first_atom_index = zld.sections.items(.first_atom_index)[sect_id];
const first_atom_index = zld.sections.items(.first_atom_index)[sect_id].?;
header.size = 0;
header.@"align" = 0;

View File

@ -31,6 +31,7 @@ const MachO = @import("../MachO.zig");
const Md5 = std.crypto.hash.Md5;
const LibStub = @import("../tapi.zig").LibStub;
const Object = @import("Object.zig");
const Section = MachO.Section;
const StringTable = @import("../strtab.zig").StringTable;
const SymbolWithLoc = MachO.SymbolWithLoc;
const SymbolResolver = MachO.SymbolResolver;
@ -231,7 +232,7 @@ pub const Zld = struct {
const sym = self.getSymbol(atom.getSymbolWithLoc());
var section = self.sections.get(sym.n_sect - 1);
if (section.header.size > 0) {
const last_atom = self.getAtomPtr(section.last_atom_index);
const last_atom = self.getAtomPtr(section.last_atom_index.?);
last_atom.next_index = atom_index;
atom.prev_index = section.last_atom_index;
} else {
@ -445,7 +446,7 @@ pub const Zld = struct {
fn writeLazyPointer(self: *Zld, stub_helper_index: u32, writer: anytype) !void {
const target_addr = blk: {
const sect_id = self.getSectionByName("__TEXT", "__stub_helper").?;
var atom_index = self.sections.items(.first_atom_index)[sect_id];
var atom_index = self.sections.items(.first_atom_index)[sect_id].?;
var count: u32 = 0;
while (count < stub_helper_index + 1) : (count += 1) {
const atom = self.getAtom(atom_index);
@ -497,7 +498,7 @@ pub const Zld = struct {
const target_addr = blk: {
// TODO: cache this at stub atom creation; they always go in pairs anyhow
const la_sect_id = self.getSectionByName("__DATA", "__la_symbol_ptr").?;
var la_atom_index = self.sections.items(.first_atom_index)[la_sect_id];
var la_atom_index = self.sections.items(.first_atom_index)[la_sect_id].?;
var count: u32 = 0;
while (count < stub_index) : (count += 1) {
const la_atom = self.getAtom(la_atom_index);
@ -1012,11 +1013,10 @@ pub const Zld = struct {
for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| {
const header = slice.items(.header)[sect_id];
var atom_index = first_atom_index;
if (atom_index == 0) continue;
if (header.isZerofill()) continue;
var atom_index = first_atom_index orelse continue;
var buffer = std.ArrayList(u8).init(gpa);
defer buffer.deinit();
try buffer.ensureTotalCapacity(math.cast(usize, header.size) orelse return error.Overflow);
@ -1129,7 +1129,7 @@ pub const Zld = struct {
while (i < slice.len) : (i += 1) {
const section = self.sections.get(i);
if (section.header.size == 0) {
log.debug("pruning section {s},{s} {d}", .{
log.debug("pruning section {s},{s} {?d}", .{
section.header.segName(),
section.header.sectName(),
section.first_atom_index,
@ -1156,8 +1156,7 @@ pub const Zld = struct {
if (header.isCode() and !(header.type() == macho.S_SYMBOL_STUBS) and !mem.eql(u8, header.sectName(), "__stub_helper")) continue;
}
var atom_index = slice.items(.first_atom_index)[sect_id];
if (atom_index == 0) continue;
var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
header.size = 0;
header.@"align" = 0;
@ -1195,8 +1194,7 @@ pub const Zld = struct {
// We need to do this since our unwind info synthesiser relies on
// traversing the symbols when synthesising unwind info and DWARF CFI records.
for (slice.items(.first_atom_index)) |first_atom_index| {
if (first_atom_index == 0) continue;
var atom_index = first_atom_index;
var atom_index = first_atom_index orelse continue;
while (true) {
const atom = self.getAtom(atom_index);
@ -1278,8 +1276,9 @@ pub const Zld = struct {
@as(u32, @intCast(segment.fileoff + start_aligned));
header.addr = segment.vmaddr + start_aligned;
var atom_index = slice.items(.first_atom_index)[indexes.start + sect_id];
if (atom_index > 0) {
if (slice.items(.first_atom_index)[indexes.start + sect_id]) |first_atom_index| {
var atom_index = first_atom_index;
log.debug("allocating local symbols in sect({d}, '{s},{s}')", .{
n_sect,
header.segName(),
@ -1362,8 +1361,6 @@ pub const Zld = struct {
.reserved1 = opts.reserved1,
.reserved2 = opts.reserved2,
},
.first_atom_index = 0,
.last_atom_index = 0,
});
return index;
}
@ -1491,7 +1488,7 @@ pub const Zld = struct {
if (self.getSectionByName("__DATA", "__la_symbol_ptr")) |sect_id| {
const segment_index = slice.items(.segment_index)[sect_id];
const seg = self.getSegment(sect_id);
var atom_index = slice.items(.first_atom_index)[sect_id];
var atom_index = slice.items(.first_atom_index)[sect_id].?;
try rebase.entries.ensureUnusedCapacity(self.gpa, self.stubs.items.len);
@ -1531,8 +1528,7 @@ pub const Zld = struct {
log.debug("{s},{s}", .{ header.segName(), header.sectName() });
const cpu_arch = self.options.target.cpu.arch;
var atom_index = slice.items(.first_atom_index)[sect_id];
if (atom_index == 0) continue;
var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
while (true) {
const atom = self.getAtom(atom_index);
@ -1668,8 +1664,7 @@ pub const Zld = struct {
if (segment.maxprot & macho.PROT.WRITE == 0) continue;
const cpu_arch = self.options.target.cpu.arch;
var atom_index = slice.items(.first_atom_index)[sect_id];
if (atom_index == 0) continue;
var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
log.debug("{s},{s}", .{ header.segName(), header.sectName() });
@ -1757,7 +1752,7 @@ pub const Zld = struct {
const slice = self.sections.slice();
const segment_index = slice.items(.segment_index)[sect_id];
const seg = self.getSegment(sect_id);
var atom_index = slice.items(.first_atom_index)[sect_id];
var atom_index = slice.items(.first_atom_index)[sect_id].?;
// TODO: we actually don't need to store lazy pointer atoms as they are synthetically generated by the linker
try lazy_bind.entries.ensureUnusedCapacity(self.gpa, self.stubs.items.len);
@ -1920,7 +1915,7 @@ pub const Zld = struct {
const section = self.sections.get(stub_helper_section_index);
const stub_offset = stub_helpers.calcStubOffsetInStubHelper(self.options.target.cpu.arch);
const header = section.header;
var atom_index = section.first_atom_index;
var atom_index = section.first_atom_index.?;
atom_index = self.getAtom(atom_index).next_index.?; // skip preamble
var index: usize = 0;
@ -2923,9 +2918,7 @@ pub const Zld = struct {
log.debug("atoms:", .{});
const slice = self.sections.slice();
for (slice.items(.first_atom_index), 0..) |first_atom_index, sect_id| {
var atom_index = first_atom_index;
if (atom_index == 0) continue;
var atom_index = first_atom_index orelse continue;
const header = slice.items(.header)[sect_id];
log.debug("{s},{s}", .{ header.segName(), header.sectName() });
@ -2990,13 +2983,6 @@ pub const Zld = struct {
pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1)));
const Section = struct {
header: macho.section_64,
segment_index: u8,
first_atom_index: AtomIndex,
last_atom_index: AtomIndex,
};
pub const AtomIndex = u32;
const IndirectPointer = struct {
@ -3183,7 +3169,6 @@ pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progr
};
defer zld.deinit();
try zld.atoms.append(gpa, Atom.empty); // AtomIndex at 0 is reserved as null atom
try zld.strtab.buffer.append(gpa, 0);
// Positional arguments to the linker such as object files and static archives.