aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/Object.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/link/MachO/Object.zig')
-rw-r--r--src/link/MachO/Object.zig254
1 files changed, 138 insertions, 116 deletions
diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig
index a668b932d9..fe99df22bd 100644
--- a/src/link/MachO/Object.zig
+++ b/src/link/MachO/Object.zig
@@ -11,10 +11,10 @@ sections: std.MultiArrayList(Section) = .{},
symtab: std.MultiArrayList(Nlist) = .{},
strtab: std.ArrayListUnmanaged(u8) = .{},
-symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
+symbols: std.ArrayListUnmanaged(Symbol) = .{},
symbols_extra: std.ArrayListUnmanaged(u32) = .{},
globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{},
-atoms: std.ArrayListUnmanaged(Atom.Index) = .{},
+atoms: std.ArrayListUnmanaged(Atom) = .{},
atoms_indexes: std.ArrayListUnmanaged(Atom.Index) = .{},
atoms_extra: std.ArrayListUnmanaged(u32) = .{},
@@ -228,7 +228,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
// Parse DWARF __TEXT,__eh_frame section
if (self.eh_frame_sect_index) |index| {
- try self.initEhFrameRecords(index, macho_file);
+ try self.initEhFrameRecords(gpa, index, handle, macho_file);
}
// Parse Apple's __LD,__compact_unwind section
@@ -261,7 +261,7 @@ pub fn parse(self: *Object, macho_file: *MachO) !void {
try self.parseDebugInfo(macho_file);
- for (self.atoms.items) |atom_index| {
+ for (self.getAtoms()) |atom_index| {
const atom = self.getAtom(atom_index) orelse continue;
const isec = atom.getInputSection(macho_file);
if (mem.eql(u8, isec.sectName(), "__eh_frame") or
@@ -606,7 +606,7 @@ fn initPointerLiterals(self: *Object, allocator: Allocator, macho_file: *MachO)
}
}
-pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO) !void {
+pub fn resolveLiterals(self: *Object, lp: *MachO.LiteralPool, macho_file: *MachO) !void {
const tracy = trace(@src());
defer tracy.end();
@@ -646,7 +646,7 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
} else {
const lp_sym = lp.getSymbol(res.index, macho_file);
const lp_atom = lp_sym.getAtom(macho_file).?;
- lp_atom.alignment = @max(lp_atom.alignment, atom.alignment);
+ lp_atom.alignment = lp_atom.alignment.max(atom.alignment);
atom.flags.alive = false;
}
atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);
@@ -684,7 +684,7 @@ pub fn resolveLiterals(self: Object, lp: *MachO.LiteralPool, macho_file: *MachO)
} else {
const lp_sym = lp.getSymbol(res.index, macho_file);
const lp_atom = lp_sym.getAtom(macho_file).?;
- lp_atom.alignment = @max(lp_atom.alignment, atom.alignment);
+ lp_atom.alignment = lp_atom.alignment.max(atom.alignment);
atom.flags.alive = false;
}
atom.addExtra(.{ .literal_pool_index = res.index }, macho_file);
@@ -823,7 +823,7 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {
const index = self.addSymbolAssumeCapacity();
const symbol = &self.symbols.items[index];
symbol.value = nlist.n_value;
- symbol.name = .{ .pos = nlist.n_strx, .len = @intCast(self.getNStrx(nlist.n_strx).len + 1) };
+ symbol.name = nlist.n_strx;
symbol.nlist_idx = @intCast(i);
symbol.extra = self.addSymbolExtraAssumeCapacity(.{});
@@ -838,7 +838,9 @@ fn initSymbols(self: *Object, allocator: Allocator, macho_file: *MachO) !void {
symbol.flags.tentative = nlist.tentative();
symbol.flags.no_dead_strip = symbol.flags.no_dead_strip or nlist.noDeadStrip();
symbol.flags.dyn_ref = nlist.n_desc & macho.REFERENCED_DYNAMICALLY != 0;
- symbol.flags.interposable = nlist.ext() and (nlist.sect() or nlist.abs()) and macho_file.options.dylib and macho_file.options.namespace == .flat and !nlist.pext();
+ symbol.flags.interposable = nlist.ext() and (nlist.sect() or nlist.abs()) and macho_file.base.isDynLib() and !nlist.pext();
+ // TODO
+ // symbol.flags.interposable = nlist.ext() and (nlist.sect() or nlist.abs()) and macho_file.base.isDynLib() and macho_file.options.namespace == .flat and !nlist.pext();
if (nlist.sect() and
self.sections.items(.header)[nlist.n_sect - 1].type() == macho.S_THREAD_LOCAL_VARIABLES)
@@ -869,7 +871,7 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
fn find(fs: @This(), addr: u64) ?Symbol.Index {
// TODO binary search since we have the list sorted
for (fs.entries) |nlist| {
- if (nlist.nlist.n_value == addr) return fs.ctx.symbols.items[nlist.idx];
+ if (nlist.nlist.n_value == addr) return @intCast(nlist.idx);
}
return null;
}
@@ -920,17 +922,17 @@ fn initSymbolStabs(self: *Object, allocator: Allocator, nlists: anytype, macho_f
switch (nlist.n_type) {
macho.N_BNSYM => {
stab.is_func = true;
- stab.symbol = sym_lookup.find(nlist.n_value);
+ stab.index = sym_lookup.find(nlist.n_value);
// TODO validate
i += 3;
},
macho.N_GSYM => {
stab.is_func = false;
- stab.symbol = sym_lookup.find(addr_lookup.get(self.getString(nlist.n_strx)).?);
+ stab.index = sym_lookup.find(addr_lookup.get(self.getString(nlist.n_strx)).?);
},
macho.N_STSYM => {
stab.is_func = false;
- stab.symbol = sym_lookup.find(nlist.n_value);
+ stab.index = sym_lookup.find(nlist.n_value);
},
else => {
try macho_file.reportParseError2(self.index, "unhandled symbol stab type 0x{x}", .{
@@ -1103,9 +1105,9 @@ fn initUnwindRecords(self: *Object, allocator: Allocator, sect_id: u8, file: Fil
ctx: *const Object,
fn find(fs: @This(), addr: u64) ?Symbol.Index {
- for (fs.ctx.symbols.items, 0..) |sym_index, i| {
+ for (0..fs.ctx.symbols.items.len) |i| {
const nlist = fs.ctx.symtab.items(.nlist)[i];
- if (nlist.ext() and nlist.n_value == addr) return sym_index;
+ if (nlist.ext() and nlist.n_value == addr) return @intCast(i);
}
return null;
}
@@ -1274,7 +1276,7 @@ fn parseUnwindRecords(self: *Object, allocator: Allocator, cpu_arch: std.Target.
// Create a null record
const rec_index = try self.addUnwindRecord(allocator);
const rec = self.getUnwindRecord(rec_index);
- const atom = macho_file.getAtom(meta.atom).?;
+ const atom = self.getAtom(meta.atom).?;
try self.unwind_records_indexes.append(allocator, rec_index);
rec.length = @intCast(meta.size);
rec.atom = meta.atom;
@@ -1468,17 +1470,17 @@ fn findCompileUnit(self: *Object, args: struct {
};
}
-pub fn resolveSymbols(self: *Object, macho_file: *MachO) void {
+pub fn resolveSymbols(self: *Object, macho_file: *MachO) !void {
const tracy = trace(@src());
defer tracy.end();
- const gpa = macho_file.base.allocator;
+ const gpa = macho_file.base.comp.gpa;
for (self.symtab.items(.nlist), self.symtab.items(.atom), self.globals.items, 0..) |nlist, atom_index, *global, i| {
if (!nlist.ext()) continue;
if (nlist.sect()) {
const atom = self.getAtom(atom_index).?;
- if (!atom.alive.load(.seq_cst)) continue;
+ if (!atom.flags.alive) continue;
}
const gop = try macho_file.resolver.getOrPut(gpa, .{
@@ -1643,7 +1645,7 @@ pub fn claimUnresolved(self: *Object, macho_file: *MachO) void {
if (self.getSymbolRef(@intCast(i), macho_file).getFile(macho_file) != null) continue;
- const is_import = switch (macho_file.options.undefined_treatment) {
+ const is_import = switch (macho_file.undefined_treatment) {
.@"error" => false,
.warn, .suppress => nlist.weakRef(),
.dynamic_lookup => true,
@@ -1682,8 +1684,8 @@ pub fn claimUnresolvedRelocatable(self: *Object, macho_file: *MachO) void {
}
}
-fn addSection(self: *Object, allocator: Allocator, segname: []const u8, sectname: []const u8) !u32 {
- const n_sect = @as(u32, @intCast(try self.sections.addOne(allocator)));
+fn addSection(self: *Object, allocator: Allocator, segname: []const u8, sectname: []const u8) !u8 {
+ const n_sect = @as(u8, @intCast(try self.sections.addOne(allocator)));
self.sections.set(n_sect, .{
.header = .{
.sectname = MachO.makeStaticString(sectname),
@@ -1799,7 +1801,7 @@ pub fn writeAr(self: Object, ar_format: Archive.Format, macho_file: *MachO, writ
try writer.writeAll(data);
}
-pub fn calcSymtabSize(self: *Object, macho_file: *MachO) !void {
+pub fn calcSymtabSize(self: *Object, macho_file: *MachO) void {
const tracy = trace(@src());
defer tracy.end();
@@ -1821,27 +1823,27 @@ pub fn calcSymtabSize(self: *Object, macho_file: *MachO) !void {
continue;
sym.flags.output_symtab = true;
if (sym.isLocal()) {
- try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file);
+ sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file);
self.output_symtab_ctx.nlocals += 1;
} else if (sym.flags.@"export") {
- try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file);
+ sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file);
self.output_symtab_ctx.nexports += 1;
} else {
assert(sym.flags.import);
- try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file);
+ sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file);
self.output_symtab_ctx.nimports += 1;
}
self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1));
}
if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo())
- try self.calcStabsSize(macho_file);
+ self.calcStabsSize(macho_file);
}
-pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void {
+pub fn calcStabsSize(self: *Object, macho_file: *MachO) void {
if (self.compile_unit) |cu| {
- const comp_dir = cu.getCompDir(self);
- const tu_name = cu.getTuName(self);
+ const comp_dir = cu.getCompDir(self.*);
+ const tu_name = cu.getTuName(self.*);
self.output_symtab_ctx.nstabs += 4; // N_SO, N_SO, N_OSO, N_SO
self.output_symtab_ctx.strsize += @as(u32, @intCast(comp_dir.len + 1)); // comp_dir
@@ -1876,12 +1878,12 @@ pub fn calcStabsSize(self: *Object, macho_file: *MachO) error{Overflow}!void {
for (self.stab_files.items) |sf| {
self.output_symtab_ctx.nstabs += 4; // N_SO, N_SO, N_OSO, N_SO
- self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getCompDir(self).len + 1)); // comp_dir
- self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getTuName(self).len + 1)); // tu_name
- self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getOsoPath(self).len + 1)); // path
+ self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getCompDir(self.*).len + 1)); // comp_dir
+ self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getTuName(self.*).len + 1)); // tu_name
+ self.output_symtab_ctx.strsize += @as(u32, @intCast(sf.getOsoPath(self.*).len + 1)); // path
for (sf.stabs.items) |stab| {
- const sym = stab.getSymbol(macho_file) orelse continue;
+ const sym = stab.getSymbol(self.*) orelse continue;
const file = sym.getFile(macho_file).?;
if (file.getIndex() != self.index) continue;
if (!sym.flags.output_symtab) continue;
@@ -2065,7 +2067,7 @@ pub fn writeCompactUnwindRelocatable(self: *Object, macho_file: *MachO) !void {
}
}
-pub fn writeSymtab(self: Object, macho_file: *MachO) void {
+pub fn writeSymtab(self: Object, macho_file: *MachO, ctx: anytype) void {
const tracy = trace(@src());
defer tracy.end();
@@ -2075,21 +2077,21 @@ pub fn writeSymtab(self: Object, macho_file: *MachO) void {
const file = ref.getFile(macho_file) orelse continue;
if (file.getIndex() != self.index) continue;
const idx = sym.getOutputSymtabIndex(macho_file) orelse continue;
- const out_sym = &macho_file.symtab.items[idx];
+ const out_sym = &ctx.symtab.items[idx];
out_sym.n_strx = n_strx;
sym.setOutputSym(macho_file, out_sym);
const name = sym.getName(macho_file);
- @memcpy(macho_file.strtab.items[n_strx..][0..name.len], name);
+ @memcpy(ctx.strtab.items[n_strx..][0..name.len], name);
n_strx += @intCast(name.len);
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
}
if (macho_file.base.comp.config.debug_format != .strip and self.hasDebugInfo())
- try self.writeStabs(n_strx, macho_file);
+ self.writeStabs(n_strx, macho_file, ctx);
}
-pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
+pub fn writeStabs(self: Object, stroff: u32, macho_file: *MachO, ctx: anytype) void {
const writeFuncStab = struct {
inline fn writeFuncStab(
n_strx: u32,
@@ -2097,7 +2099,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
n_value: u64,
size: u64,
index: u32,
- context: *MachO,
+ context: anytype,
) void {
context.symtab.items[index] = .{
.n_strx = 0,
@@ -2139,7 +2141,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
// Open scope
// N_SO comp_dir
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = n_strx,
.n_type = macho.N_SO,
.n_sect = 0,
@@ -2147,9 +2149,9 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
.n_value = 0,
};
index += 1;
- @memcpy(macho_file.strtab.items[n_strx..][0..comp_dir.len], comp_dir);
+ @memcpy(ctx.strtab.items[n_strx..][0..comp_dir.len], comp_dir);
n_strx += @intCast(comp_dir.len);
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
// N_SO tu_name
macho_file.symtab.items[index] = .{
@@ -2160,12 +2162,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
.n_value = 0,
};
index += 1;
- @memcpy(macho_file.strtab.items[n_strx..][0..tu_name.len], tu_name);
+ @memcpy(ctx.strtab.items[n_strx..][0..tu_name.len], tu_name);
n_strx += @intCast(tu_name.len);
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
// N_OSO path
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = n_strx,
.n_type = macho.N_OSO,
.n_sect = 0,
@@ -2174,20 +2176,20 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
};
index += 1;
if (self.in_archive) |ar| {
- @memcpy(macho_file.strtab.items[n_strx..][0..ar.path.len], ar.path);
+ @memcpy(ctx.strtab.items[n_strx..][0..ar.path.len], ar.path);
n_strx += @intCast(ar.path.len);
- macho_file.strtab.items[n_strx] = '(';
+ ctx.strtab.items[n_strx] = '(';
n_strx += 1;
- @memcpy(macho_file.strtab.items[n_strx..][0..self.path.len], self.path);
+ @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path);
n_strx += @intCast(self.path.len);
- macho_file.strtab.items[n_strx] = ')';
+ ctx.strtab.items[n_strx] = ')';
n_strx += 1;
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
} else {
- @memcpy(macho_file.strtab.items[n_strx..][0..self.path.len], self.path);
+ @memcpy(ctx.strtab.items[n_strx..][0..self.path.len], self.path);
n_strx += @intCast(self.path.len);
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
}
@@ -2203,17 +2205,17 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
const sect = macho_file.sections.items(.header)[sym.getOutputSectionIndex(macho_file)];
const sym_n_strx = n_strx: {
const symtab_index = sym.getOutputSymtabIndex(macho_file).?;
- const osym = macho_file.symtab.items[symtab_index];
+ const osym = ctx.symtab.items[symtab_index];
break :n_strx osym.n_strx;
};
const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.getOutputSectionIndex(macho_file) + 1) else 0;
const sym_n_value = sym.getAddress(.{}, macho_file);
const sym_size = sym.getSize(macho_file);
if (sect.isCode()) {
- writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file);
+ writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx);
index += 4;
} else if (sym.visibility == .global) {
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = sym_n_strx,
.n_type = macho.N_GSYM,
.n_sect = sym_n_sect,
@@ -2222,7 +2224,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
};
index += 1;
} else {
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = sym_n_strx,
.n_type = macho.N_STSYM,
.n_sect = sym_n_sect,
@@ -2235,7 +2237,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
// Close scope
// N_SO
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = 0,
.n_type = macho.N_SO,
.n_sect = 0,
@@ -2246,13 +2248,13 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
assert(self.hasSymbolStabs());
for (self.stab_files.items) |sf| {
- const comp_dir = sf.getCombDir(self);
+ const comp_dir = sf.getCompDir(self);
const tu_name = sf.getTuName(self);
const oso_path = sf.getOsoPath(self);
// Open scope
// N_SO comp_dir
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = n_strx,
.n_type = macho.N_SO,
.n_sect = 0,
@@ -2260,12 +2262,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
.n_value = 0,
};
index += 1;
- @memcpy(macho_file.strtab.items[n_strx..][0..comp_dir.len], comp_dir);
+ @memcpy(ctx.strtab.items[n_strx..][0..comp_dir.len], comp_dir);
n_strx += @intCast(comp_dir.len);
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
// N_SO tu_name
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = n_strx,
.n_type = macho.N_SO,
.n_sect = 0,
@@ -2273,12 +2275,12 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
.n_value = 0,
};
index += 1;
- @memcpy(macho_file.strtab.items[n_strx..][0..tu_name.len], tu_name);
+ @memcpy(ctx.strtab.items[n_strx..][0..tu_name.len], tu_name);
n_strx += @intCast(tu_name.len);
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
// N_OSO path
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = n_strx,
.n_type = macho.N_OSO,
.n_sect = 0,
@@ -2286,29 +2288,29 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
.n_value = sf.getOsoModTime(self),
};
index += 1;
- @memcpy(macho_file.strtab.items[n_strx..][0..oso_path.len], oso_path);
+ @memcpy(ctx.strtab.items[n_strx..][0..oso_path.len], oso_path);
n_strx += @intCast(oso_path.len);
- macho_file.strtab.items[n_strx] = 0;
+ ctx.strtab.items[n_strx] = 0;
n_strx += 1;
for (sf.stabs.items) |stab| {
- const sym = stab.getSymbol(macho_file) orelse continue;
+ const sym = stab.getSymbol(self) orelse continue;
const file = sym.getFile(macho_file).?;
if (file.getIndex() != self.index) continue;
if (!sym.flags.output_symtab) continue;
const sym_n_strx = n_strx: {
const symtab_index = sym.getOutputSymtabIndex(macho_file).?;
- const osym = macho_file.symtab.items[symtab_index];
+ const osym = ctx.symtab.items[symtab_index];
break :n_strx osym.n_strx;
};
const sym_n_sect: u8 = if (!sym.flags.abs) @intCast(sym.getOutputSectionIndex(macho_file) + 1) else 0;
const sym_n_value = sym.getAddress(.{}, macho_file);
const sym_size = sym.getSize(macho_file);
if (stab.is_func) {
- writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, macho_file);
+ writeFuncStab(sym_n_strx, sym_n_sect, sym_n_value, sym_size, index, ctx);
index += 4;
} else if (sym.visibility == .global) {
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = sym_n_strx,
.n_type = macho.N_GSYM,
.n_sect = sym_n_sect,
@@ -2317,7 +2319,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
};
index += 1;
} else {
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = sym_n_strx,
.n_type = macho.N_STSYM,
.n_sect = sym_n_sect,
@@ -2330,7 +2332,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
// Close scope
// N_SO
- macho_file.symtab.items[index] = .{
+ ctx.symtab.items[index] = .{
.n_strx = 0,
.n_type = macho.N_SO,
.n_sect = 0,
@@ -2343,7 +2345,7 @@ pub fn writeStabs(self: *const Object, stroff: u32, macho_file: *MachO) void {
}
pub fn getAtomRelocs(self: *const Object, atom: Atom, macho_file: *MachO) []const Relocation {
- const extra = atom.getExtra(macho_file).?;
+ const extra = atom.getExtra(macho_file);
const relocs = self.sections.items(.relocs)[atom.n_sect];
return relocs.items[extra.rel_index..][0..extra.rel_count];
}
@@ -2402,7 +2404,7 @@ pub fn asFile(self: *Object) File {
}
const AddAtomArgs = struct {
- name: MachO.String,
+ name: u32,
n_sect: u8,
off: u64,
size: u64,
@@ -2420,7 +2422,7 @@ fn addAtom(self: *Object, allocator: Allocator, args: AddAtomArgs) !Atom.Index {
.size = args.size,
.off = args.off,
.extra = try self.addAtomExtra(allocator, .{}),
- .alignment = args.alignment,
+ .alignment = Atom.Alignment.fromLog2Units(args.alignment),
};
return atom_index;
}
@@ -2693,12 +2695,12 @@ fn formatSymtab(
}
for (object.stab_files.items) |sf| {
try writer.print(" stabs({s},{s},{s})\n", .{
- sf.getCompDir(object),
- sf.getTuName(object),
- sf.getOsoPath(object),
+ sf.getCompDir(object.*),
+ sf.getTuName(object.*),
+ sf.getOsoPath(object.*),
});
for (sf.stabs.items) |stab| {
- try writer.print(" {}", .{stab.fmt(object)});
+ try writer.print(" {}", .{stab.fmt(object.*)});
}
}
}
@@ -2744,33 +2746,33 @@ const StabFile = struct {
comp_dir: u32,
stabs: std.ArrayListUnmanaged(Stab) = .{},
- fn getCompDir(sf: StabFile, object: *const Object) [:0]const u8 {
+ fn getCompDir(sf: StabFile, object: Object) [:0]const u8 {
const nlist = object.symtab.items(.nlist)[sf.comp_dir];
return object.getString(nlist.n_strx);
}
- fn getTuName(sf: StabFile, object: *const Object) [:0]const u8 {
+ fn getTuName(sf: StabFile, object: Object) [:0]const u8 {
const nlist = object.symtab.items(.nlist)[sf.comp_dir + 1];
return object.getString(nlist.n_strx);
}
- fn getOsoPath(sf: StabFile, object: *const Object) [:0]const u8 {
+ fn getOsoPath(sf: StabFile, object: Object) [:0]const u8 {
const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];
return object.getString(nlist.n_strx);
}
- fn getOsoModTime(sf: StabFile, object: *const Object) u64 {
+ fn getOsoModTime(sf: StabFile, object: Object) u64 {
const nlist = object.symtab.items(.nlist)[sf.comp_dir + 2];
return nlist.n_value;
}
const Stab = struct {
is_func: bool = true,
- symbol: ?Symbol.Index = null,
+ index: ?Symbol.Index = null,
- fn getSymbol(stab: Stab, object: *const Object) ?*Symbol {
+ fn getSymbol(stab: Stab, object: Object) ?Symbol {
const index = stab.index orelse return null;
- return &object.symbols.items[index];
+ return object.symbols.items[index];
}
pub fn format(
@@ -2786,9 +2788,9 @@ const StabFile = struct {
@compileError("do not format stabs directly");
}
- const StabFormatContext = struct { Stab, *const Object };
+ const StabFormatContext = struct { Stab, Object };
- pub fn fmt(stab: Stab, object: *const Object) std.fmt.Formatter(format2) {
+ pub fn fmt(stab: Stab, object: Object) std.fmt.Formatter(format2) {
return .{ .data = .{ stab, object } };
}
@@ -2817,11 +2819,11 @@ const CompileUnit = struct {
comp_dir: u32,
tu_name: u32,
- fn getCompDir(cu: CompileUnit, object: *const Object) [:0]const u8 {
+ fn getCompDir(cu: CompileUnit, object: Object) [:0]const u8 {
return object.getString(cu.comp_dir);
}
- fn getTuName(cu: CompileUnit, object: *const Object) [:0]const u8 {
+ fn getTuName(cu: CompileUnit, object: Object) [:0]const u8 {
return object.getString(cu.tu_name);
}
};
@@ -2840,15 +2842,14 @@ const CompactUnwindCtx = struct {
const x86_64 = struct {
fn parseRelocs(
- self: *const Object,
- n_sect: u8,
+ self: *Object,
sect: macho.section_64,
out: *std.ArrayListUnmanaged(Relocation),
+ handle: File.Handle,
macho_file: *MachO,
) !void {
const gpa = macho_file.base.comp.gpa;
- const handle = macho_file.getFileHandle(self.file_handle);
const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
defer gpa.free(relocs_buffer);
{
@@ -2857,8 +2858,12 @@ const x86_64 = struct {
}
const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];
- const code = try self.getSectionData(@intCast(n_sect), macho_file);
+ const code = try gpa.alloc(u8, sect.size);
defer gpa.free(code);
+ {
+ const amt = try handle.preadAll(code, sect.offset + self.offset);
+ if (amt != code.len) return error.InputOutput;
+ }
try out.ensureTotalCapacityPrecise(gpa, relocs.len);
@@ -2880,8 +2885,9 @@ const x86_64 = struct {
.X86_64_RELOC_SIGNED_4 => 4,
else => 0,
};
+ var is_extern = rel.r_extern == 1;
- const target = if (rel.r_extern == 0) blk: {
+ const target = if (!is_extern) blk: {
const nsect = rel.r_symbolnum - 1;
const taddr: i64 = if (rel.r_pcrel == 1)
@as(i64, @intCast(sect.addr)) + rel.r_address + addend + 4
@@ -2893,9 +2899,15 @@ const x86_64 = struct {
});
return error.MalformedObject;
};
- addend = taddr - @as(i64, @intCast(macho_file.getAtom(target).?.getInputAddress(macho_file)));
+ const target_atom = self.getAtom(target).?;
+ addend = taddr - @as(i64, @intCast(target_atom.getInputAddress(macho_file)));
+ const isec = target_atom.getInputSection(macho_file);
+ if (isCstringLiteral(isec) or isFixedSizeLiteral(isec) or isPtrLiteral(isec)) {
+ is_extern = true;
+ break :blk target_atom.getExtra(macho_file).literal_symbol_index;
+ }
break :blk target;
- } else self.symbols.items[rel.r_symbolnum];
+ } else rel.r_symbolnum;
const has_subtractor = if (i > 0 and
@as(macho.reloc_type_x86_64, @enumFromInt(relocs[i - 1].r_type)) == .X86_64_RELOC_SUBTRACTOR)
@@ -2909,7 +2921,7 @@ const x86_64 = struct {
break :blk true;
} else false;
- const @"type": Relocation.Type = validateRelocType(rel, rel_type) catch |err| {
+ const @"type": Relocation.Type = validateRelocType(rel, rel_type, is_extern) catch |err| {
switch (err) {
error.Pcrel => try macho_file.reportParseError2(
self.index,
@@ -2936,7 +2948,7 @@ const x86_64 = struct {
};
out.appendAssumeCapacity(.{
- .tag = if (rel.r_extern == 1) .@"extern" else .local,
+ .tag = if (is_extern) .@"extern" else .local,
.offset = @as(u32, @intCast(rel.r_address)),
.target = target,
.addend = addend,
@@ -2951,7 +2963,7 @@ const x86_64 = struct {
}
}
- fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_x86_64) !Relocation.Type {
+ fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_x86_64, is_extern: bool) !Relocation.Type {
switch (rel_type) {
.X86_64_RELOC_UNSIGNED => {
if (rel.r_pcrel == 1) return error.Pcrel;
@@ -2971,7 +2983,7 @@ const x86_64 = struct {
=> {
if (rel.r_pcrel == 0) return error.NonPcrel;
if (rel.r_length != 2) return error.InvalidLength;
- if (rel.r_extern == 0) return error.NonExtern;
+ if (!is_extern) return error.NonExtern;
return switch (rel_type) {
.X86_64_RELOC_BRANCH => .branch,
.X86_64_RELOC_GOT_LOAD => .got_load,
@@ -3002,15 +3014,14 @@ const x86_64 = struct {
const aarch64 = struct {
fn parseRelocs(
- self: *const Object,
- n_sect: u8,
+ self: *Object,
sect: macho.section_64,
out: *std.ArrayListUnmanaged(Relocation),
+ handle: File.Handle,
macho_file: *MachO,
) !void {
const gpa = macho_file.base.comp.gpa;
- const handle = macho_file.getFileHandle(self.file_handle);
const relocs_buffer = try gpa.alloc(u8, sect.nreloc * @sizeOf(macho.relocation_info));
defer gpa.free(relocs_buffer);
{
@@ -3019,8 +3030,12 @@ const aarch64 = struct {
}
const relocs = @as([*]align(1) const macho.relocation_info, @ptrCast(relocs_buffer.ptr))[0..sect.nreloc];
- const code = try self.getSectionData(@intCast(n_sect), macho_file);
+ const code = try gpa.alloc(u8, sect.size);
defer gpa.free(code);
+ {
+ const amt = try handle.preadAll(code, sect.offset + self.offset);
+ if (amt != code.len) return error.InputOutput;
+ }
try out.ensureTotalCapacityPrecise(gpa, relocs.len);
@@ -3066,8 +3081,9 @@ const aarch64 = struct {
}
const rel_type: macho.reloc_type_arm64 = @enumFromInt(rel.r_type);
+ var is_extern = rel.r_extern == 1;
- const target = if (rel.r_extern == 0) blk: {
+ const target = if (!is_extern) blk: {
const nsect = rel.r_symbolnum - 1;
const taddr: i64 = if (rel.r_pcrel == 1)
@as(i64, @intCast(sect.addr)) + rel.r_address + addend
@@ -3079,9 +3095,15 @@ const aarch64 = struct {
});
return error.MalformedObject;
};
- addend = taddr - @as(i64, @intCast(macho_file.getAtom(target).?.getInputAddress(macho_file)));
+ const target_atom = self.getAtom(target).?;
+ addend = taddr - @as(i64, @intCast(target_atom.getInputAddress(macho_file)));
+ const isec = target_atom.getInputSection(macho_file);
+ if (isCstringLiteral(isec) or isFixedSizeLiteral(isec) or isPtrLiteral(isec)) {
+ is_extern = true;
+ break :blk target_atom.getExtra(macho_file).literal_symbol_index;
+ }
break :blk target;
- } else self.symbols.items[rel.r_symbolnum];
+ } else rel.r_symbolnum;
const has_subtractor = if (i > 0 and
@as(macho.reloc_type_arm64, @enumFromInt(relocs[i - 1].r_type)) == .ARM64_RELOC_SUBTRACTOR)
@@ -3095,7 +3117,7 @@ const aarch64 = struct {
break :blk true;
} else false;
- const @"type": Relocation.Type = validateRelocType(rel, rel_type) catch |err| {
+ const @"type": Relocation.Type = validateRelocType(rel, rel_type, is_extern) catch |err| {
switch (err) {
error.Pcrel => try macho_file.reportParseError2(
self.index,
@@ -3122,7 +3144,7 @@ const aarch64 = struct {
};
out.appendAssumeCapacity(.{
- .tag = if (rel.r_extern == 1) .@"extern" else .local,
+ .tag = if (is_extern) .@"extern" else .local,
.offset = @as(u32, @intCast(rel.r_address)),
.target = target,
.addend = addend,
@@ -3137,7 +3159,7 @@ const aarch64 = struct {
}
}
- fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_arm64) !Relocation.Type {
+ fn validateRelocType(rel: macho.relocation_info, rel_type: macho.reloc_type_arm64, is_extern: bool) !Relocation.Type {
switch (rel_type) {
.ARM64_RELOC_UNSIGNED => {
if (rel.r_pcrel == 1) return error.Pcrel;
@@ -3158,7 +3180,7 @@ const aarch64 = struct {
=> {
if (rel.r_pcrel == 0) return error.NonPcrel;
if (rel.r_length != 2) return error.InvalidLength;
- if (rel.r_extern == 0) return error.NonExtern;
+ if (!is_extern) return error.NonExtern;
return switch (rel_type) {
.ARM64_RELOC_BRANCH26 => .branch,
.ARM64_RELOC_PAGE21 => .page,
@@ -3175,7 +3197,7 @@ const aarch64 = struct {
=> {
if (rel.r_pcrel == 1) return error.Pcrel;
if (rel.r_length != 2) return error.InvalidLength;
- if (rel.r_extern == 0) return error.NonExtern;
+ if (!is_extern) return error.NonExtern;
return switch (rel_type) {
.ARM64_RELOC_PAGEOFF12 => .pageoff,
.ARM64_RELOC_GOT_LOAD_PAGEOFF12 => .got_load_pageoff,