aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2023-08-21 22:17:34 +0200
committerJakub Konka <kubkon@jakubkonka.com>2023-08-29 11:39:34 +0200
commite1e0ccb0c7ac32024aeb079a6cb57e237f941473 (patch)
tree1c64dcaf809555250eda5e606257935935b70053 /src
parent05c9d6c00babc4ccc7949b3eb0224f70719d12a5 (diff)
downloadzig-e1e0ccb0c7ac32024aeb079a6cb57e237f941473.tar.gz
zig-e1e0ccb0c7ac32024aeb079a6cb57e237f941473.zip
macho: unify Section concept across drivers
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig6
-rw-r--r--src/link/MachO/Object.zig10
-rw-r--r--src/link/MachO/dead_strip.zig4
-rw-r--r--src/link/MachO/thunks.zig2
-rw-r--r--src/link/MachO/zld.zig51
5 files changed, 27 insertions, 46 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index 2b765ab6b9..05b6bcef5a 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -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
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig
index 5e67a334c0..e407b83017 100644
--- a/src/link/MachO/Object.zig
+++ b/src/link/MachO/Object.zig
@@ -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 {
diff --git a/src/link/MachO/dead_strip.zig b/src/link/MachO/dead_strip.zig
index 282e3a21c7..b2031590ed 100644
--- a/src/link/MachO/dead_strip.zig
+++ b/src/link/MachO/dead_strip.zig
@@ -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;
}
}
diff --git a/src/link/MachO/thunks.zig b/src/link/MachO/thunks.zig
index 66ae57e970..e5ef305077 100644
--- a/src/link/MachO/thunks.zig
+++ b/src/link/MachO/thunks.zig
@@ -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;
diff --git a/src/link/MachO/zld.zig b/src/link/MachO/zld.zig
index 9e2271bccf..d82e80a20a 100644
--- a/src/link/MachO/zld.zig
+++ b/src/link/MachO/zld.zig
@@ -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.