mirror of
https://github.com/ziglang/zig.git
synced 2026-01-30 03:03:46 +00:00
macho: fix compile errors
This commit is contained in:
parent
5b4c0cc1f9
commit
174de37cef
@ -12362,8 +12362,9 @@ fn genCall(self: *Self, info: union(enum) {
|
||||
try self.genSetReg(.rax, Type.usize, .{ .lea_got = sym_index }, .{});
|
||||
try self.asmRegister(.{ ._, .call }, .rax);
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const sym_index = try macho_file.getZigObject().?.getOrCreateMetadataForDecl(macho_file, func.owner_decl);
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const sym_index = try zo.getOrCreateMetadataForDecl(macho_file, func.owner_decl);
|
||||
const sym = zo.symbols.items[sym_index];
|
||||
try self.genSetReg(
|
||||
.rax,
|
||||
Type.usize,
|
||||
@ -15396,9 +15397,10 @@ fn genLazySymbolRef(
|
||||
else => unreachable,
|
||||
}
|
||||
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
|
||||
const sym_index = macho_file.getZigObject().?.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const sym_index = zo.getOrCreateMetadataForLazySymbol(macho_file, pt, lazy_sym) catch |err|
|
||||
return self.fail("{s} creating lazy symbol", .{@errorName(err)});
|
||||
const sym = macho_file.getSymbol(sym_index);
|
||||
const sym = zo.symbols.items[sym_index];
|
||||
switch (tag) {
|
||||
.lea, .call => try self.genSetReg(
|
||||
reg,
|
||||
|
||||
@ -162,7 +162,7 @@ pub fn emitMir(emit: *Emit) Error!void {
|
||||
};
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const atom = zo.symbols.items[data.atom_index].getAtom(macho_file).?;
|
||||
const sym = zo.symbols.items[data.sym_index];
|
||||
const sym = &zo.symbols.items[data.sym_index];
|
||||
if (sym.flags.needs_zig_got and !is_obj_or_static_lib) {
|
||||
_ = try sym.getOrCreateZigGotEntry(data.sym_index, macho_file);
|
||||
}
|
||||
|
||||
@ -529,7 +529,7 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
|
||||
dylib.ordinal = @intCast(ord);
|
||||
}
|
||||
|
||||
try self.claimUnresolved();
|
||||
self.claimUnresolved();
|
||||
|
||||
self.scanRelocs() catch |err| switch (err) {
|
||||
error.HasUndefinedSymbols => return error.FlushFailure,
|
||||
@ -603,7 +603,12 @@ pub fn flushModule(self: *MachO, arena: Allocator, tid: Zcu.PerThread.Id, prog_n
|
||||
|
||||
if (has_resolve_error) return error.FlushFailure;
|
||||
}
|
||||
try self.writeSectionsAndUpdateLinkeditSizes();
|
||||
self.writeSectionsAndUpdateLinkeditSizes() catch |err| {
|
||||
switch (err) {
|
||||
error.ResolveFailed => return error.FlushFailure,
|
||||
else => |e| return e,
|
||||
}
|
||||
};
|
||||
|
||||
try self.writeSectionsToFile();
|
||||
try self.allocateLinkeditSegment();
|
||||
@ -1450,12 +1455,12 @@ pub fn dedupLiterals(self: *MachO) !void {
|
||||
}
|
||||
}
|
||||
|
||||
fn claimUnresolved(self: *MachO) error{OutOfMemory}!void {
|
||||
fn claimUnresolved(self: *MachO) void {
|
||||
if (self.getZigObject()) |zo| {
|
||||
try zo.asFile().claimUnresolved(self);
|
||||
zo.claimUnresolved(self);
|
||||
}
|
||||
for (self.objects.items) |index| {
|
||||
try self.getFile(index).?.claimUnresolved(self);
|
||||
self.getFile(index).?.object.claimUnresolved(self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2402,7 +2407,7 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
|
||||
}
|
||||
|
||||
if (self.la_symbol_ptr_sect_index) |_| {
|
||||
try self.updatelazyBindSize();
|
||||
try self.updateLazyBindSize();
|
||||
}
|
||||
|
||||
try self.rebase.updateSize(self);
|
||||
@ -2412,16 +2417,16 @@ fn writeSectionsAndUpdateLinkeditSizes(self: *MachO) !void {
|
||||
try self.data_in_code.updateSize(self);
|
||||
|
||||
if (self.getZigObject()) |zo| {
|
||||
zo.asFile().writeSymtab(self);
|
||||
zo.asFile().writeSymtab(self, self);
|
||||
}
|
||||
for (self.objects.items) |index| {
|
||||
self.getFile(index).?.writeSymtab(self);
|
||||
self.getFile(index).?.writeSymtab(self, self);
|
||||
}
|
||||
for (self.dylibs.items) |index| {
|
||||
self.getFile(index).?.writeSymtab(self);
|
||||
self.getFile(index).?.writeSymtab(self, self);
|
||||
}
|
||||
if (self.getInternalObject()) |obj| {
|
||||
obj.asFile().writeSymtab(self);
|
||||
obj.asFile().writeSymtab(self, self);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2484,7 +2489,7 @@ fn writeSectionsToFile(self: *MachO) !void {
|
||||
|
||||
const slice = self.sections.slice();
|
||||
for (slice.items(.header), slice.items(.out)) |header, out| {
|
||||
try self.base.file.pwriteAll(out.items, header.offset);
|
||||
try self.base.file.?.pwriteAll(out.items, header.offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2501,7 +2506,7 @@ fn writeDyldInfo(self: *MachO) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const gpa = self.base.allocator;
|
||||
const gpa = self.base.comp.gpa;
|
||||
const base_off = self.getLinkeditSegment().fileoff;
|
||||
const cmd = self.dyld_info_cmd;
|
||||
var needed_size: u32 = 0;
|
||||
@ -2527,14 +2532,14 @@ fn writeDyldInfo(self: *MachO) !void {
|
||||
try self.lazy_bind.write(writer);
|
||||
try stream.seekTo(cmd.export_off - base_off);
|
||||
try self.export_trie.write(writer);
|
||||
try self.base.file.pwriteAll(buffer, cmd.rebase_off);
|
||||
try self.base.file.?.pwriteAll(buffer, cmd.rebase_off);
|
||||
}
|
||||
|
||||
pub fn writeDataInCode(self: *MachO) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
const cmd = self.data_in_code_cmd;
|
||||
try self.base.file.pwriteAll(mem.sliceAsBytes(self.data_in_code.entries.items), cmd.dataoff);
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.data_in_code.entries.items), cmd.dataoff);
|
||||
}
|
||||
|
||||
fn writeIndsymtab(self: *MachO) !void {
|
||||
@ -2546,15 +2551,15 @@ fn writeIndsymtab(self: *MachO) !void {
|
||||
var buffer = try std.ArrayList(u8).initCapacity(gpa, needed_size);
|
||||
defer buffer.deinit();
|
||||
try self.indsymtab.write(self, buffer.writer());
|
||||
try self.base.file.pwriteAll(buffer.items, cmd.indirectsymoff);
|
||||
try self.base.file.?.pwriteAll(buffer.items, cmd.indirectsymoff);
|
||||
}
|
||||
|
||||
pub fn writeSymtabToFile(self: *MachO) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
const cmd = self.symtab_cmd;
|
||||
try self.base.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
|
||||
try self.base.file.pwriteAll(self.strtab.items, cmd.stroff);
|
||||
try self.base.file.?.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
|
||||
try self.base.file.?.pwriteAll(self.strtab.items, cmd.stroff);
|
||||
}
|
||||
|
||||
fn writeUnwindInfo(self: *MachO) !void {
|
||||
@ -2687,18 +2692,20 @@ fn writeLoadCommands(self: *MachO) !struct { usize, usize, u64 } {
|
||||
try load_commands.writeDylinkerLC(writer);
|
||||
ncmds += 1;
|
||||
|
||||
if (self.entry_index) |global_index| {
|
||||
const sym = self.getSymbol(global_index);
|
||||
const seg = self.getTextSegment();
|
||||
const entryoff: u32 = if (sym.getFile(self) == null)
|
||||
0
|
||||
else
|
||||
@as(u32, @intCast(sym.getAddress(.{ .stubs = true }, self) - seg.vmaddr));
|
||||
try writer.writeStruct(macho.entry_point_command{
|
||||
.entryoff = entryoff,
|
||||
.stacksize = self.base.stack_size,
|
||||
});
|
||||
ncmds += 1;
|
||||
if (self.getInternalObject()) |obj| {
|
||||
if (obj.getEntryRef(self)) |ref| {
|
||||
const sym = ref.getSymbol(self).?;
|
||||
const seg = self.getTextSegment();
|
||||
const entryoff: u32 = if (sym.getFile(self) == null)
|
||||
0
|
||||
else
|
||||
@as(u32, @intCast(sym.getAddress(.{ .stubs = true }, self) - seg.vmaddr));
|
||||
try writer.writeStruct(macho.entry_point_command{
|
||||
.entryoff = entryoff,
|
||||
.stacksize = self.base.stack_size,
|
||||
});
|
||||
ncmds += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (self.base.isDynLib()) {
|
||||
|
||||
@ -213,7 +213,8 @@ pub fn initOutputSection(sect: macho.section_64, macho_file: *MachO) !u8 {
|
||||
/// File offset relocation happens transparently, so it is not included in
|
||||
/// this calculation.
|
||||
pub fn capacity(self: Atom, macho_file: *MachO) u64 {
|
||||
const next_addr = if (macho_file.getAtom(self.next_index)) |next|
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const next_addr = if (zo.getAtom(self.next_index)) |next|
|
||||
next.getAddress(macho_file)
|
||||
else
|
||||
std.math.maxInt(u32);
|
||||
@ -222,7 +223,8 @@ pub fn capacity(self: Atom, macho_file: *MachO) u64 {
|
||||
|
||||
pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
|
||||
// No need to keep a free list node for the last block.
|
||||
const next = macho_file.getAtom(self.next_index) orelse return false;
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const next = zo.getAtom(self.next_index) orelse return false;
|
||||
const cap = next.getAddress(macho_file) - self.getAddress(macho_file);
|
||||
const ideal_cap = MachO.padToIdeal(self.size);
|
||||
if (cap <= ideal_cap) return false;
|
||||
@ -231,6 +233,7 @@ pub fn freeListEligible(self: Atom, macho_file: *MachO) bool {
|
||||
}
|
||||
|
||||
pub fn allocate(self: *Atom, macho_file: *MachO) !void {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const sect = &macho_file.sections.items(.header)[self.out_n_sect];
|
||||
const free_list = &macho_file.sections.items(.free_list)[self.out_n_sect];
|
||||
const last_atom_index = &macho_file.sections.items(.last_atom_index)[self.out_n_sect];
|
||||
@ -250,7 +253,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
|
||||
var i: usize = free_list.items.len;
|
||||
while (i < free_list.items.len) {
|
||||
const big_atom_index = free_list.items[i];
|
||||
const big_atom = macho_file.getAtom(big_atom_index).?;
|
||||
const big_atom = zo.getAtom(big_atom_index).?;
|
||||
// We now have a pointer to a live atom that has too much capacity.
|
||||
// Is it enough that we could fit this new atom?
|
||||
const cap = big_atom.capacity(macho_file);
|
||||
@ -282,7 +285,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
|
||||
free_list_removal = i;
|
||||
}
|
||||
break :blk new_start_vaddr;
|
||||
} else if (macho_file.getAtom(last_atom_index.*)) |last| {
|
||||
} else if (zo.getAtom(last_atom_index.*)) |last| {
|
||||
const ideal_capacity = MachO.padToIdeal(last.size);
|
||||
const ideal_capacity_end_vaddr = last.value + ideal_capacity;
|
||||
const new_start_vaddr = self.alignment.forward(ideal_capacity_end_vaddr);
|
||||
@ -302,7 +305,7 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
|
||||
});
|
||||
|
||||
const expand_section = if (atom_placement) |placement_index|
|
||||
macho_file.getAtom(placement_index).?.next_index == 0
|
||||
zo.getAtom(placement_index).?.next_index == 0
|
||||
else
|
||||
true;
|
||||
if (expand_section) {
|
||||
@ -327,15 +330,15 @@ pub fn allocate(self: *Atom, macho_file: *MachO) !void {
|
||||
// This function can also reallocate an atom.
|
||||
// In this case we need to "unplug" it from its previous location before
|
||||
// plugging it in to its new location.
|
||||
if (macho_file.getAtom(self.prev_index)) |prev| {
|
||||
if (zo.getAtom(self.prev_index)) |prev| {
|
||||
prev.next_index = self.next_index;
|
||||
}
|
||||
if (macho_file.getAtom(self.next_index)) |next| {
|
||||
if (zo.getAtom(self.next_index)) |next| {
|
||||
next.prev_index = self.prev_index;
|
||||
}
|
||||
|
||||
if (atom_placement) |big_atom_index| {
|
||||
const big_atom = macho_file.getAtom(big_atom_index).?;
|
||||
const big_atom = zo.getAtom(big_atom_index).?;
|
||||
self.prev_index = big_atom_index;
|
||||
self.next_index = big_atom.next_index;
|
||||
big_atom.next_index = self.atom_index;
|
||||
@ -365,6 +368,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
|
||||
|
||||
const comp = macho_file.base.comp;
|
||||
const gpa = comp.gpa;
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const free_list = &macho_file.sections.items(.free_list)[self.out_n_sect];
|
||||
const last_atom_index = &macho_file.sections.items(.last_atom_index)[self.out_n_sect];
|
||||
var already_have_free_list_node = false;
|
||||
@ -383,9 +387,9 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
|
||||
}
|
||||
}
|
||||
|
||||
if (macho_file.getAtom(last_atom_index.*)) |last_atom| {
|
||||
if (zo.getAtom(last_atom_index.*)) |last_atom| {
|
||||
if (last_atom.atom_index == self.atom_index) {
|
||||
if (macho_file.getAtom(self.prev_index)) |_| {
|
||||
if (zo.getAtom(self.prev_index)) |_| {
|
||||
// TODO shrink the section size here
|
||||
last_atom_index.* = self.prev_index;
|
||||
} else {
|
||||
@ -394,7 +398,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
|
||||
}
|
||||
}
|
||||
|
||||
if (macho_file.getAtom(self.prev_index)) |prev| {
|
||||
if (zo.getAtom(self.prev_index)) |prev| {
|
||||
prev.next_index = self.next_index;
|
||||
if (!already_have_free_list_node and prev.*.freeListEligible(macho_file)) {
|
||||
// The free list is heuristics, it doesn't have to be perfect, so we can
|
||||
@ -405,7 +409,7 @@ pub fn free(self: *Atom, macho_file: *MachO) void {
|
||||
self.prev_index = 0;
|
||||
}
|
||||
|
||||
if (macho_file.getAtom(self.next_index)) |next| {
|
||||
if (zo.getAtom(self.next_index)) |next| {
|
||||
next.prev_index = self.prev_index;
|
||||
} else {
|
||||
self.next_index = 0;
|
||||
@ -423,7 +427,7 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const file = self.getFile(macho_file);
|
||||
assert(file == .zig_object);
|
||||
var extra = self.getExtra(macho_file).?;
|
||||
var extra = self.getExtra(macho_file);
|
||||
const rels = &file.zig_object.relocs.items[extra.rel_index];
|
||||
try rels.append(gpa, reloc);
|
||||
extra.rel_count += 1;
|
||||
@ -432,7 +436,7 @@ pub fn addReloc(self: *Atom, macho_file: *MachO, reloc: Relocation) !void {
|
||||
|
||||
pub fn freeRelocs(self: *Atom, macho_file: *MachO) void {
|
||||
self.getFile(macho_file).zig_object.freeAtomRelocs(self.*, macho_file);
|
||||
var extra = self.getExtra(macho_file).?;
|
||||
var extra = self.getExtra(macho_file);
|
||||
extra.rel_count = 0;
|
||||
self.setExtra(extra, macho_file);
|
||||
}
|
||||
@ -630,7 +634,7 @@ fn resolveRelocInner(
|
||||
const TLS = @as(i64, @intCast(macho_file.getTlsAddress()));
|
||||
const SUB = if (subtractor) |sub| @as(i64, @intCast(sub.getTargetAddress(self, macho_file))) else 0;
|
||||
// Address of the __got_zig table entry if any.
|
||||
const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(self, macho_file)));
|
||||
const ZIG_GOT = @as(i64, @intCast(rel.getZigGotTargetAddress(macho_file)));
|
||||
|
||||
const divExact = struct {
|
||||
fn divExact(atom: Atom, r: Relocation, num: u12, den: u12, ctx: *MachO) !u12 {
|
||||
|
||||
@ -175,8 +175,9 @@ fn findFreeSpace(self: *DebugSymbols, object_size: u64, min_alignment: u64) u64
|
||||
}
|
||||
|
||||
pub fn flushModule(self: *DebugSymbols, macho_file: *MachO) !void {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
for (self.relocs.items) |*reloc| {
|
||||
const sym = macho_file.getSymbol(reloc.target);
|
||||
const sym = zo.symbols.items[reloc.target];
|
||||
const sym_name = sym.getName(macho_file);
|
||||
const addr = switch (reloc.type) {
|
||||
.direct_load => sym.getAddress(.{}, macho_file),
|
||||
@ -382,23 +383,22 @@ pub fn writeSymtab(self: *DebugSymbols, off: u32, macho_file: *MachO) !u32 {
|
||||
cmd.symoff = off;
|
||||
|
||||
try self.symtab.resize(gpa, cmd.nsyms);
|
||||
try self.strtab.ensureUnusedCapacity(gpa, cmd.strsize - 1);
|
||||
try self.strtab.resize(gpa, cmd.strsize);
|
||||
self.strtab.items[0] = 0;
|
||||
|
||||
if (macho_file.getZigObject()) |zo| {
|
||||
zo.writeSymtab(macho_file, self);
|
||||
}
|
||||
for (macho_file.objects.items) |index| {
|
||||
try macho_file.getFile(index).?.writeSymtab(macho_file, self);
|
||||
macho_file.getFile(index).?.writeSymtab(macho_file, self);
|
||||
}
|
||||
for (macho_file.dylibs.items) |index| {
|
||||
try macho_file.getFile(index).?.writeSymtab(macho_file, self);
|
||||
macho_file.getFile(index).?.writeSymtab(macho_file, self);
|
||||
}
|
||||
if (macho_file.getInternalObject()) |internal| {
|
||||
internal.writeSymtab(macho_file, self);
|
||||
}
|
||||
|
||||
assert(self.strtab.items.len == cmd.strsize);
|
||||
|
||||
try self.file.pwriteAll(mem.sliceAsBytes(self.symtab.items), cmd.symoff);
|
||||
|
||||
return off + cmd.nsyms * @sizeOf(macho.nlist_64);
|
||||
|
||||
@ -6,7 +6,7 @@ strtab: std.ArrayListUnmanaged(u8) = .{},
|
||||
id: ?Id = null,
|
||||
ordinal: u16 = 0,
|
||||
|
||||
symbols: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
symbols: std.ArrayListUnmanaged(Symbol) = .{},
|
||||
symbols_extra: std.ArrayListUnmanaged(u32) = .{},
|
||||
globals: std.ArrayListUnmanaged(MachO.SymbolResolver.Index) = .{},
|
||||
dependents: std.ArrayListUnmanaged(Id) = .{},
|
||||
@ -516,7 +516,7 @@ pub fn initSymbols(self: *Dylib, macho_file: *MachO) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolveSymbols(self: *Dylib, macho_file: *MachO) void {
|
||||
pub fn resolveSymbols(self: *Dylib, macho_file: *MachO) !void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
@ -584,7 +584,7 @@ pub fn calcSymtabSize(self: *Dylib, macho_file: *MachO) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(self: Dylib, macho_file: *MachO) void {
|
||||
pub fn writeSymtab(self: Dylib, macho_file: *MachO, ctx: anytype) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
@ -594,13 +594,13 @@ pub fn writeSymtab(self: Dylib, 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;
|
||||
}
|
||||
}
|
||||
@ -718,10 +718,16 @@ fn formatSymtab(
|
||||
_ = unused_fmt_string;
|
||||
_ = options;
|
||||
const dylib = ctx.dylib;
|
||||
const macho_file = ctx.macho_file;
|
||||
try writer.writeAll(" globals\n");
|
||||
for (dylib.symbols.items) |index| {
|
||||
const global = ctx.macho_file.getSymbol(index);
|
||||
try writer.print(" {}\n", .{global.fmt(ctx.macho_file)});
|
||||
for (dylib.symbols.items, 0..) |sym, i| {
|
||||
const ref = dylib.getSymbolRef(@intCast(i), macho_file);
|
||||
if (ref.getFile(macho_file) == null) {
|
||||
// TODO any better way of handling this?
|
||||
try writer.print(" {s} : unclaimed\n", .{sym.getName(macho_file)});
|
||||
} else {
|
||||
try writer.print(" {}\n", .{ref.getSymbol(macho_file).?.fmt(macho_file)});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ objc_selrefs: [@sizeOf(u64)]u8 = [_]u8{0} ** @sizeOf(u64),
|
||||
force_undefined: std.ArrayListUnmanaged(Symbol.Index) = .{},
|
||||
entry_index: ?Symbol.Index = null,
|
||||
dyld_stub_binder_index: ?Symbol.Index = null,
|
||||
dyld_private: ?Symbol.Index = null,
|
||||
dyld_private_index: ?Symbol.Index = null,
|
||||
objc_msg_send_index: ?Symbol.Index = null,
|
||||
mh_execute_header_index: ?Symbol.Index = null,
|
||||
mh_dylib_header_index: ?Symbol.Index = null,
|
||||
@ -206,7 +206,7 @@ pub fn resolveBoundarySymbols(self: *InternalObject, macho_file: *MachO) !void {
|
||||
const nlist_idx: u32 = @intCast(self.symtab.items.len);
|
||||
const nlist = self.symtab.addOneAssumeCapacity();
|
||||
nlist.* = .{
|
||||
.n_strx = name_off.pos,
|
||||
.n_strx = name_off,
|
||||
.n_type = macho.N_SECT,
|
||||
.n_sect = 0,
|
||||
.n_desc = 0,
|
||||
@ -273,7 +273,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
|
||||
const nlist_idx: u32 = @intCast(self.symtab.items.len);
|
||||
const nlist = try self.symtab.addOne(gpa);
|
||||
nlist.* = .{
|
||||
.n_strx = name_str.pos,
|
||||
.n_strx = name_str,
|
||||
.n_type = macho.N_SECT,
|
||||
.n_sect = @intCast(n_sect + 1),
|
||||
.n_desc = 0,
|
||||
@ -286,12 +286,12 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
|
||||
}
|
||||
|
||||
fn addObjcSelrefsSection(self: *InternalObject, methname_sym_index: Symbol.Index, macho_file: *MachO) !Symbol.Index {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const atom_index = try self.addAtom(gpa);
|
||||
try self.atoms_indexes.append(gpa, atom_index);
|
||||
const atom = self.getAtom(atom_index).?;
|
||||
atom.size = @sizeOf(u64);
|
||||
atom.alignment = 3;
|
||||
atom.alignment = .@"8";
|
||||
|
||||
const n_sect = try self.addSection(gpa, "__DATA", "__objc_selrefs");
|
||||
const sect = &self.sections.items(.header)[n_sect];
|
||||
@ -389,7 +389,7 @@ pub fn resolveObjcMsgSendSymbols(self: *InternalObject, macho_file: *MachO) !voi
|
||||
};
|
||||
sym.nlist_idx = nlist_idx;
|
||||
sym.extra = try self.addSymbolExtra(gpa, .{ .objc_selrefs = selrefs_index });
|
||||
sym.setSectionFlags(.{ .objc_stubs = true });
|
||||
sym.flags.objc_stubs = true;
|
||||
|
||||
const idx = ref.getFile(macho_file).?.object.globals.items[ref.index];
|
||||
try self.globals.append(gpa, idx);
|
||||
@ -417,7 +417,7 @@ pub fn resolveLiterals(self: *InternalObject, lp: *MachO.LiteralPool, macho_file
|
||||
const target = rel.getTargetSymbol(atom.*, macho_file).getAtom(macho_file).?;
|
||||
try buffer.ensureUnusedCapacity(target.size);
|
||||
buffer.resize(target.size) catch unreachable;
|
||||
@memcpy(buffer.items, self.getSectionData(target.n_sect));
|
||||
@memcpy(buffer.items, try self.getSectionData(target.n_sect));
|
||||
const res = try lp.insert(gpa, header.type(), buffer.items);
|
||||
buffer.clearRetainingCapacity();
|
||||
if (!res.found_existing) {
|
||||
@ -425,7 +425,7 @@ pub fn resolveLiterals(self: *InternalObject, lp: *MachO.LiteralPool, macho_file
|
||||
} 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);
|
||||
@ -438,7 +438,7 @@ pub fn dedupLiterals(self: *InternalObject, lp: MachO.LiteralPool, macho_file: *
|
||||
|
||||
for (self.getAtoms()) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
if (!atom.alive.load(.seq_cst)) continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
|
||||
const relocs = blk: {
|
||||
const extra = atom.getExtra(macho_file);
|
||||
@ -463,7 +463,7 @@ pub fn dedupLiterals(self: *InternalObject, lp: MachO.LiteralPool, macho_file: *
|
||||
}
|
||||
|
||||
for (self.symbols.items) |*sym| {
|
||||
if (!sym.getSectionFlags().objc_stubs) continue;
|
||||
if (!sym.flags.objc_stubs) continue;
|
||||
const extra = sym.getExtra(macho_file);
|
||||
const file = sym.getFile(macho_file).?;
|
||||
if (file.getIndex() != self.index) continue;
|
||||
@ -495,14 +495,14 @@ pub fn scanRelocs(self: *InternalObject, macho_file: *MachO) void {
|
||||
if (self.getDyldStubBinderRef(macho_file)) |ref| {
|
||||
if (ref.getFile(macho_file) != null) {
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
sym.flags.got = true;
|
||||
sym.flags.needs_got = true;
|
||||
}
|
||||
}
|
||||
if (self.getObjcMsgSendRef(macho_file)) |ref| {
|
||||
if (ref.getFile(macho_file) != null) {
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
// TODO is it always needed, or only if we are synthesising fast stubs
|
||||
sym.flags.got = true;
|
||||
sym.flags.needs_got = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -569,30 +569,30 @@ pub fn writeAtoms(self: *InternalObject, macho_file: *MachO) !void {
|
||||
|
||||
for (self.getAtoms()) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
if (!atom.alive.load(.seq_cst)) continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
const sect = atom.getInputSection(macho_file);
|
||||
if (sect.isZerofill()) continue;
|
||||
const off = atom.value;
|
||||
const buffer = macho_file.sections.items(.out)[atom.out_n_sect].items[off..][0..atom.size];
|
||||
@memcpy(buffer, self.getSectionData(atom.n_sect));
|
||||
@memcpy(buffer, try self.getSectionData(atom.n_sect));
|
||||
try atom.resolveRelocs(macho_file, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(self: InternalObject, macho_file: *MachO) void {
|
||||
pub fn writeSymtab(self: InternalObject, macho_file: *MachO, ctx: anytype) void {
|
||||
var n_strx = self.output_symtab_ctx.stroff;
|
||||
for (self.symbols.items, 0..) |sym, i| {
|
||||
const ref = self.getSymbolRef(@intCast(i), macho_file);
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -640,7 +640,7 @@ pub fn asFile(self: *InternalObject) File {
|
||||
}
|
||||
|
||||
pub fn getAtomRelocs(self: *const InternalObject, 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];
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -150,7 +150,7 @@ pub fn getObjcSelrefsAddress(symbol: Symbol, macho_file: *MachO) u64 {
|
||||
const file = symbol.getFile(macho_file).?;
|
||||
return switch (file) {
|
||||
.dylib, .zig_object => unreachable,
|
||||
.object, .internal => |x| x.symbols.items[extra.objc_selrefs].getAddress(.{}, macho_file),
|
||||
inline else => |x| x.symbols.items[extra.objc_selrefs].getAddress(.{}, macho_file),
|
||||
};
|
||||
}
|
||||
|
||||
@ -186,7 +186,7 @@ pub fn getOutputSymtabIndex(symbol: Symbol, macho_file: *MachO) ?u32 {
|
||||
const symtab_ctx = switch (file) {
|
||||
inline else => |x| x.output_symtab_ctx,
|
||||
};
|
||||
var idx = symbol.getExtra(macho_file).?.symtab;
|
||||
var idx = symbol.getExtra(macho_file).symtab;
|
||||
if (symbol.isLocal()) {
|
||||
idx += symtab_ctx.ilocal;
|
||||
} else if (symbol.flags.@"export") {
|
||||
|
||||
@ -473,11 +473,11 @@ pub const Record = struct {
|
||||
}
|
||||
|
||||
pub fn getAtom(rec: Record, macho_file: *MachO) *Atom {
|
||||
return macho_file.getAtom(rec.atom).?;
|
||||
return rec.getObject(macho_file).getAtom(rec.atom).?;
|
||||
}
|
||||
|
||||
pub fn getLsdaAtom(rec: Record, macho_file: *MachO) ?*Atom {
|
||||
return macho_file.getAtom(rec.lsda);
|
||||
return rec.getObject(macho_file).getAtom(rec.lsda);
|
||||
}
|
||||
|
||||
pub fn getPersonality(rec: Record, macho_file: *MachO) ?*Symbol {
|
||||
|
||||
@ -343,6 +343,36 @@ pub fn writeAr(self: ZigObject, ar_format: Archive.Format, writer: anytype) !voi
|
||||
try writer.writeAll(self.data.items);
|
||||
}
|
||||
|
||||
pub fn claimUnresolved(self: *ZigObject, macho_file: *MachO) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
for (self.symbols.items, 0..) |*sym, i| {
|
||||
const nlist = self.symtab.items(.nlist)[i];
|
||||
if (!nlist.ext()) continue;
|
||||
if (!nlist.undf()) continue;
|
||||
|
||||
if (self.getSymbolRef(@intCast(i), macho_file).getFile(macho_file) != null) continue;
|
||||
|
||||
const is_import = switch (macho_file.undefined_treatment) {
|
||||
.@"error" => false,
|
||||
.warn, .suppress => nlist.weakRef(),
|
||||
.dynamic_lookup => true,
|
||||
};
|
||||
if (is_import) {
|
||||
sym.value = 0;
|
||||
sym.atom_ref = .{ .index = 0, .file = 0 };
|
||||
sym.flags.weak = false;
|
||||
sym.flags.weak_ref = nlist.weakRef();
|
||||
sym.flags.import = is_import;
|
||||
sym.visibility = .global;
|
||||
|
||||
const idx = self.globals.items[i];
|
||||
macho_file.resolver.values.items[idx - 1] = .{ .index = @intCast(i), .file = self.index };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scanRelocs(self: *ZigObject, macho_file: *MachO) !void {
|
||||
for (self.getAtoms()) |atom_index| {
|
||||
const atom = self.getAtom(atom_index) orelse continue;
|
||||
@ -378,7 +408,7 @@ pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void {
|
||||
pub fn writeSymtab(self: ZigObject, macho_file: *MachO, ctx: anytype) void {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
@ -388,13 +418,13 @@ pub fn writeSymtab(self: ZigObject, 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;
|
||||
}
|
||||
}
|
||||
@ -1098,7 +1128,7 @@ pub fn lowerUnnamedConst(
|
||||
},
|
||||
};
|
||||
const sym = self.symbols.items[sym_index];
|
||||
try unnamed_consts.append(gpa, sym.atom);
|
||||
try unnamed_consts.append(gpa, sym.atom_ref.index);
|
||||
return sym_index;
|
||||
}
|
||||
|
||||
|
||||
@ -34,7 +34,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
|
||||
for (objects.items) |index| {
|
||||
const file = macho_file.getFile(index).?;
|
||||
for (file.getAtoms()) |atom_index| {
|
||||
const atom = macho_file.getAtom(atom_index) orelse continue;
|
||||
const atom = file.getAtom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
if (atom.getInputSection(macho_file).isZerofill()) continue;
|
||||
const atom_addr = atom.getAddress(macho_file);
|
||||
@ -43,7 +43,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
|
||||
for (atom.getRelocs(macho_file)) |rel| {
|
||||
if (rel.type != .unsigned or rel.meta.length != 3) continue;
|
||||
if (rel.tag == .@"extern") {
|
||||
const sym = rel.getTargetSymbol(macho_file);
|
||||
const sym = rel.getTargetSymbol(atom.*, macho_file);
|
||||
if (sym.isTlvInit(macho_file)) continue;
|
||||
if (sym.flags.import) continue;
|
||||
}
|
||||
@ -72,7 +72,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
|
||||
const seg_id = macho_file.sections.items(.segment_id)[sid];
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
for (macho_file.got.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
|
||||
if (!sym.flags.import) {
|
||||
try rebase.entries.append(gpa, .{
|
||||
@ -88,7 +88,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
|
||||
const seg_id = macho_file.sections.items(.segment_id)[sid];
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = sect.addr + idx * @sizeOf(u64);
|
||||
const rebase_entry = Rebase.Entry{
|
||||
.offset = addr - seg.vmaddr,
|
||||
@ -104,7 +104,7 @@ pub fn updateSize(rebase: *Rebase, macho_file: *MachO) !void {
|
||||
const seg_id = macho_file.sections.items(.segment_id)[sid];
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
|
||||
if (!sym.flags.import) {
|
||||
try rebase.entries.append(gpa, .{
|
||||
|
||||
@ -94,33 +94,31 @@ pub fn updateSize(self: *Trie, macho_file: *MachO) !void {
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
|
||||
try self.init(gpa);
|
||||
// TODO
|
||||
// try self.nodes.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);
|
||||
// try self.edges.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);
|
||||
try self.nodes.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);
|
||||
try self.edges.ensureUnusedCapacity(gpa, macho_file.resolver.values.items.len * 2);
|
||||
|
||||
const seg = macho_file.getTextSegment();
|
||||
for (macho_file.objects.items) |index| {
|
||||
for (macho_file.getFile(index).?.getSymbols()) |ref| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
if (!sym.flags.@"export") continue;
|
||||
if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue;
|
||||
var flags: u64 = if (sym.flags.abs)
|
||||
macho.EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
|
||||
else if (sym.flags.tlv)
|
||||
macho.EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
|
||||
else
|
||||
macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
|
||||
if (sym.flags.weak) {
|
||||
flags |= macho.EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
|
||||
macho_file.weak_defines = true;
|
||||
macho_file.binds_to_weak = true;
|
||||
}
|
||||
try self.put(gpa, .{
|
||||
.name = sym.getName(macho_file),
|
||||
.vmaddr_offset = sym.getAddress(.{ .stubs = false }, macho_file) - seg.vmaddr,
|
||||
.export_flags = flags,
|
||||
});
|
||||
for (macho_file.resolver.values.items) |ref| {
|
||||
if (ref.getFile(macho_file) == null) continue;
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
if (!sym.flags.@"export") continue;
|
||||
if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue;
|
||||
var flags: u64 = if (sym.flags.abs)
|
||||
macho.EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE
|
||||
else if (sym.flags.tlv)
|
||||
macho.EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL
|
||||
else
|
||||
macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
|
||||
if (sym.flags.weak) {
|
||||
flags |= macho.EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
|
||||
macho_file.weak_defines = true;
|
||||
macho_file.binds_to_weak = true;
|
||||
}
|
||||
try self.put(gpa, .{
|
||||
.name = sym.getName(macho_file),
|
||||
.vmaddr_offset = sym.getAddress(.{ .stubs = false }, macho_file) - seg.vmaddr,
|
||||
.export_flags = flags,
|
||||
});
|
||||
}
|
||||
|
||||
try self.finalize(gpa);
|
||||
|
||||
@ -1,17 +1,19 @@
|
||||
pub const Entry = struct {
|
||||
target: Symbol.Index,
|
||||
target: MachO.Ref,
|
||||
offset: u64,
|
||||
segment_id: u8,
|
||||
addend: i64,
|
||||
|
||||
pub fn lessThan(ctx: *MachO, entry: Entry, other: Entry) bool {
|
||||
_ = ctx;
|
||||
if (entry.segment_id == other.segment_id) {
|
||||
if (entry.target == other.target) {
|
||||
if (entry.target.eql(other.target)) {
|
||||
return entry.offset < other.offset;
|
||||
}
|
||||
const entry_name = ctx.getSymbol(entry.target).getName(ctx);
|
||||
const other_name = ctx.getSymbol(other.target).getName(ctx);
|
||||
return std.mem.lessThan(u8, entry_name, other_name);
|
||||
if (entry.target.file == other.target.file) {
|
||||
return entry.target.index < other.target.index;
|
||||
}
|
||||
return entry.target.file < other.target.file;
|
||||
}
|
||||
return entry.segment_id < other.segment_id;
|
||||
}
|
||||
@ -44,7 +46,7 @@ pub const Bind = struct {
|
||||
for (objects.items) |index| {
|
||||
const file = macho_file.getFile(index).?;
|
||||
for (file.getAtoms()) |atom_index| {
|
||||
const atom = macho_file.getAtom(atom_index) orelse continue;
|
||||
const atom = file.getAtom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
if (atom.getInputSection(macho_file).isZerofill()) continue;
|
||||
const atom_addr = atom.getAddress(macho_file);
|
||||
@ -55,10 +57,10 @@ pub const Bind = struct {
|
||||
if (rel.type != .unsigned or rel.meta.length != 3 or rel.tag != .@"extern") continue;
|
||||
const rel_offset = rel.offset - atom.off;
|
||||
const addend = rel.addend + rel.getRelocAddend(cpu_arch);
|
||||
const sym = rel.getTargetSymbol(macho_file);
|
||||
const sym = rel.getTargetSymbol(atom.*, macho_file);
|
||||
if (sym.isTlvInit(macho_file)) continue;
|
||||
const entry = Entry{
|
||||
.target = rel.target,
|
||||
.target = rel.getTargetSymbolRef(atom.*, macho_file),
|
||||
.offset = atom_addr + rel_offset - seg.vmaddr,
|
||||
.segment_id = seg_id,
|
||||
.addend = addend,
|
||||
@ -74,7 +76,7 @@ pub const Bind = struct {
|
||||
const seg_id = macho_file.sections.items(.segment_id)[sid];
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
for (macho_file.got.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
|
||||
const entry = Entry{
|
||||
.target = ref,
|
||||
@ -93,7 +95,7 @@ pub const Bind = struct {
|
||||
const seg_id = macho_file.sections.items(.segment_id)[sid];
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = sect.addr + idx * @sizeOf(u64);
|
||||
const bind_entry = Entry{
|
||||
.target = ref,
|
||||
@ -112,7 +114,7 @@ pub const Bind = struct {
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
|
||||
for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
|
||||
const entry = Entry{
|
||||
.target = ref,
|
||||
@ -162,7 +164,7 @@ pub const Bind = struct {
|
||||
var addend: i64 = 0;
|
||||
var count: usize = 0;
|
||||
var skip: u64 = 0;
|
||||
var target: ?Symbol.Index = null;
|
||||
var target: ?MachO.Ref = null;
|
||||
|
||||
var state: enum {
|
||||
start,
|
||||
@ -173,7 +175,7 @@ pub const Bind = struct {
|
||||
var i: usize = 0;
|
||||
while (i < entries.len) : (i += 1) {
|
||||
const current = entries[i];
|
||||
if (target == null or target.? != current.target) {
|
||||
if (target == null or !target.?.eql(current.target)) {
|
||||
switch (state) {
|
||||
.start => {},
|
||||
.bind_single => try doBind(writer),
|
||||
@ -182,7 +184,7 @@ pub const Bind = struct {
|
||||
state = .start;
|
||||
target = current.target;
|
||||
|
||||
const sym = ctx.getSymbol(current.target);
|
||||
const sym = current.target.getSymbol(ctx).?;
|
||||
const name = sym.getName(ctx);
|
||||
const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
|
||||
const ordinal: i16 = ord: {
|
||||
@ -296,7 +298,7 @@ pub const WeakBind = struct {
|
||||
for (objects.items) |index| {
|
||||
const file = macho_file.getFile(index).?;
|
||||
for (file.getAtoms()) |atom_index| {
|
||||
const atom = macho_file.getAtom(atom_index) orelse continue;
|
||||
const atom = file.getAtom(atom_index) orelse continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
if (atom.getInputSection(macho_file).isZerofill()) continue;
|
||||
const atom_addr = atom.getAddress(macho_file);
|
||||
@ -307,10 +309,10 @@ pub const WeakBind = struct {
|
||||
if (rel.type != .unsigned or rel.meta.length != 3 or rel.tag != .@"extern") continue;
|
||||
const rel_offset = rel.offset - atom.off;
|
||||
const addend = rel.addend + rel.getRelocAddend(cpu_arch);
|
||||
const sym = rel.getTargetSymbol(macho_file);
|
||||
const sym = rel.getTargetSymbol(atom.*, macho_file);
|
||||
if (sym.isTlvInit(macho_file)) continue;
|
||||
const entry = Entry{
|
||||
.target = rel.target,
|
||||
.target = rel.getTargetSymbolRef(atom.*, macho_file),
|
||||
.offset = atom_addr + rel_offset - seg.vmaddr,
|
||||
.segment_id = seg_id,
|
||||
.addend = addend,
|
||||
@ -326,7 +328,7 @@ pub const WeakBind = struct {
|
||||
const seg_id = macho_file.sections.items(.segment_id)[sid];
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
for (macho_file.got.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = macho_file.got.getAddress(@intCast(idx), macho_file);
|
||||
const entry = Entry{
|
||||
.target = ref,
|
||||
@ -346,7 +348,7 @@ pub const WeakBind = struct {
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
|
||||
for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = sect.addr + idx * @sizeOf(u64);
|
||||
const bind_entry = Entry{
|
||||
.target = ref,
|
||||
@ -365,7 +367,7 @@ pub const WeakBind = struct {
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
|
||||
for (macho_file.tlv_ptr.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = macho_file.tlv_ptr.getAddress(@intCast(idx), macho_file);
|
||||
const entry = Entry{
|
||||
.target = ref,
|
||||
@ -415,7 +417,7 @@ pub const WeakBind = struct {
|
||||
var addend: i64 = 0;
|
||||
var count: usize = 0;
|
||||
var skip: u64 = 0;
|
||||
var target: ?Symbol.Index = null;
|
||||
var target: ?MachO.Ref = null;
|
||||
|
||||
var state: enum {
|
||||
start,
|
||||
@ -426,7 +428,7 @@ pub const WeakBind = struct {
|
||||
var i: usize = 0;
|
||||
while (i < entries.len) : (i += 1) {
|
||||
const current = entries[i];
|
||||
if (target == null or target.? != current.target) {
|
||||
if (target == null or !target.?.eql(current.target)) {
|
||||
switch (state) {
|
||||
.start => {},
|
||||
.bind_single => try doBind(writer),
|
||||
@ -435,7 +437,7 @@ pub const WeakBind = struct {
|
||||
state = .start;
|
||||
target = current.target;
|
||||
|
||||
const sym = ctx.getSymbol(current.target);
|
||||
const sym = current.target.getSymbol(ctx).?;
|
||||
const name = sym.getName(ctx);
|
||||
const flags: u8 = 0; // TODO NON_WEAK_DEFINITION
|
||||
|
||||
@ -536,7 +538,7 @@ pub const LazyBind = struct {
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
|
||||
for (macho_file.stubs.symbols.items, 0..) |ref, idx| {
|
||||
const sym = macho_file.getSymbol(ref);
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
const addr = sect.addr + idx * @sizeOf(u64);
|
||||
const bind_entry = Entry{
|
||||
.target = ref,
|
||||
@ -565,7 +567,7 @@ pub const LazyBind = struct {
|
||||
for (self.entries.items) |entry| {
|
||||
self.offsets.appendAssumeCapacity(@intCast(self.buffer.items.len));
|
||||
|
||||
const sym = ctx.getSymbol(entry.target);
|
||||
const sym = entry.target.getSymbol(ctx).?;
|
||||
const name = sym.getName(ctx);
|
||||
const flags: u8 = if (sym.weakRef(ctx)) macho.BIND_SYMBOL_FLAGS_WEAK_IMPORT else 0;
|
||||
const ordinal: i16 = ord: {
|
||||
|
||||
@ -30,10 +30,10 @@ pub const File = union(enum) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resolveSymbols(file: File, macho_file: *MachO) void {
|
||||
switch (file) {
|
||||
pub fn resolveSymbols(file: File, macho_file: *MachO) !void {
|
||||
return switch (file) {
|
||||
inline else => |x| x.resolveSymbols(macho_file),
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub fn scanRelocs(file: File, macho_file: *MachO) !void {
|
||||
@ -147,19 +147,19 @@ pub const File = union(enum) {
|
||||
if (ref.getFile(macho_file) == null) continue;
|
||||
if (ref.file != file.getIndex()) continue;
|
||||
const sym = ref.getSymbol(macho_file).?;
|
||||
if (sym.getSectionFlags().got) {
|
||||
if (sym.flags.needs_got) {
|
||||
log.debug("'{s}' needs GOT", .{sym.getName(macho_file)});
|
||||
try macho_file.got.addSymbol(ref, macho_file);
|
||||
}
|
||||
if (sym.getSectionFlags().stubs) {
|
||||
if (sym.flags.stubs) {
|
||||
log.debug("'{s}' needs STUBS", .{sym.getName(macho_file)});
|
||||
try macho_file.stubs.addSymbol(ref, macho_file);
|
||||
}
|
||||
if (sym.getSectionFlags().tlv_ptr) {
|
||||
if (sym.flags.tlv_ptr) {
|
||||
log.debug("'{s}' needs TLV pointer", .{sym.getName(macho_file)});
|
||||
try macho_file.tlv_ptr.addSymbol(ref, macho_file);
|
||||
}
|
||||
if (sym.getSectionFlags().objc_stubs) {
|
||||
if (sym.flags.objc_stubs) {
|
||||
log.debug("'{s}' needs OBJC STUBS", .{sym.getName(macho_file)});
|
||||
try macho_file.objc_stubs.addSymbol(ref, macho_file);
|
||||
}
|
||||
@ -171,7 +171,7 @@ pub const File = union(enum) {
|
||||
defer tracy.end();
|
||||
for (file.getAtoms()) |atom_index| {
|
||||
const atom = file.getAtom(atom_index) orelse continue;
|
||||
if (!atom.alive.load(.seq_cst)) continue;
|
||||
if (!atom.flags.alive) continue;
|
||||
atom.out_n_sect = try Atom.initOutputSection(atom.getInputSection(macho_file), macho_file);
|
||||
}
|
||||
}
|
||||
@ -185,18 +185,18 @@ pub const File = union(enum) {
|
||||
|
||||
pub fn writeAtoms(file: File, macho_file: *MachO) !void {
|
||||
return switch (file) {
|
||||
.dylib => unreachable,
|
||||
.dylib, .zig_object => unreachable,
|
||||
inline else => |x| x.writeAtoms(macho_file),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn calcSymtabSize(file: File, macho_file: *MachO) !void {
|
||||
pub fn calcSymtabSize(file: File, macho_file: *MachO) void {
|
||||
return switch (file) {
|
||||
inline else => |x| x.calcSymtabSize(macho_file),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn writeSymtab(file: File, macho_file: *MachO, ctx: anytype) !void {
|
||||
pub fn writeSymtab(file: File, macho_file: *MachO, ctx: anytype) void {
|
||||
return switch (file) {
|
||||
inline else => |x| x.writeSymtab(macho_file, ctx),
|
||||
};
|
||||
|
||||
@ -23,7 +23,7 @@ pub const ZigGotSection = struct {
|
||||
const index = try zig_got.allocateEntry(gpa);
|
||||
const entry = &zig_got.entries.items[index];
|
||||
entry.* = sym_index;
|
||||
const symbol = zo.getSymbol(sym_index);
|
||||
const symbol = &zo.symbols.items[sym_index];
|
||||
assert(symbol.flags.needs_zig_got);
|
||||
symbol.flags.has_zig_got = true;
|
||||
symbol.addExtra(.{ .zig_got = index }, macho_file);
|
||||
@ -56,7 +56,7 @@ pub const ZigGotSection = struct {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
const off = zig_got.entryOffset(index, macho_file);
|
||||
const entry = zig_got.entries.items[index];
|
||||
const value = zo.getSymbol(entry).getAddress(.{ .stubs = false }, macho_file);
|
||||
const value = zo.symbols.items[entry].getAddress(.{ .stubs = false }, macho_file);
|
||||
|
||||
var buf: [8]u8 = undefined;
|
||||
std.mem.writeInt(u64, &buf, value, .little);
|
||||
@ -66,7 +66,7 @@ pub const ZigGotSection = struct {
|
||||
pub fn writeAll(zig_got: ZigGotSection, macho_file: *MachO, writer: anytype) !void {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
for (zig_got.entries.items) |entry| {
|
||||
const symbol = zo.getSymbol(entry);
|
||||
const symbol = zo.symbols.items[entry];
|
||||
const value = symbol.address(.{ .stubs = false }, macho_file);
|
||||
try writer.writeInt(u64, value, .little);
|
||||
}
|
||||
@ -94,7 +94,7 @@ pub const ZigGotSection = struct {
|
||||
const zo = macho_file.getZigObject().?;
|
||||
try writer.writeAll("__zig_got\n");
|
||||
for (zig_got.entries.items, 0..) |entry, index| {
|
||||
const symbol = zo.getSymbol(entry);
|
||||
const symbol = zo.symbols.items[entry];
|
||||
try writer.print(" {d}@0x{x} => {d}@0x{x} ({s})\n", .{
|
||||
index,
|
||||
zig_got.entryAddress(@intCast(index), macho_file),
|
||||
@ -694,7 +694,7 @@ pub const DataInCode = struct {
|
||||
dices[next_dice].offset < end_off) : (next_dice += 1)
|
||||
{}
|
||||
|
||||
if (atom.alive.load(.seq_cst)) for (dices[start_dice..next_dice]) |d| {
|
||||
if (atom.flags.alive) for (dices[start_dice..next_dice]) |d| {
|
||||
dice.entries.appendAssumeCapacity(.{
|
||||
.offset = @intCast(atom.getAddress(macho_file) + d.offset - start_off - base_address),
|
||||
.length = d.length,
|
||||
|
||||
@ -37,7 +37,7 @@ pub fn createThunks(sect_id: u8, macho_file: *MachO) !void {
|
||||
|
||||
// Scan relocs in the group and create trampolines for any unreachable callsite
|
||||
try scanRelocs(thunk_index, gpa, atoms[start..i], macho_file);
|
||||
thunk.value = try advance(header, thunk.size(), .@"4");
|
||||
thunk.value = advance(header, thunk.size(), .@"4");
|
||||
|
||||
log.debug("thunk({d}) : {}", .{ thunk_index, thunk.fmt(macho_file) });
|
||||
}
|
||||
@ -99,8 +99,8 @@ pub const Thunk = struct {
|
||||
return header.addr + thunk.value;
|
||||
}
|
||||
|
||||
pub fn getTargetAddress(thunk: Thunk, sym_index: Symbol.Index, macho_file: *MachO) u64 {
|
||||
return thunk.getAddress(macho_file) + thunk.symbols.getIndex(sym_index).? * trampoline_size;
|
||||
pub fn getTargetAddress(thunk: Thunk, ref: MachO.Ref, macho_file: *MachO) u64 {
|
||||
return thunk.getAddress(macho_file) + thunk.symbols.getIndex(ref).? * trampoline_size;
|
||||
}
|
||||
|
||||
pub fn write(thunk: Thunk, macho_file: *MachO, writer: anytype) !void {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user