linker: update target references
This commit is contained in:
@@ -406,7 +406,8 @@ fn emitMemAddress(emit: *Emit, inst: Mir.Inst.Index) !void {
|
||||
const extra_index = emit.mir.instructions.items(.data)[inst].payload;
|
||||
const mem = emit.mir.extraData(Mir.Memory, extra_index).data;
|
||||
const mem_offset = emit.offset() + 1;
|
||||
const is_wasm32 = emit.bin_file.base.options.target.cpu.arch == .wasm32;
|
||||
const target = emit.bin_file.comp.root_mod.resolved_target.result;
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
if (is_wasm32) {
|
||||
try emit.code.append(std.wasm.opcode(.i32_const));
|
||||
var buf: [5]u8 = undefined;
|
||||
|
||||
@@ -1467,6 +1467,7 @@ pub fn updateExports(
|
||||
}
|
||||
|
||||
const ip = &mod.intern_pool;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
if (self.base.options.use_llvm) {
|
||||
// Even in the case of LLVM, we need to notice certain exported symbols in order to
|
||||
@@ -1478,7 +1479,7 @@ pub fn updateExports(
|
||||
};
|
||||
const exported_decl = mod.declPtr(exported_decl_index);
|
||||
if (exported_decl.getOwnedFunction(mod) == null) continue;
|
||||
const winapi_cc = switch (self.base.options.target.cpu.arch) {
|
||||
const winapi_cc = switch (target.cpu.arch) {
|
||||
.x86 => std.builtin.CallingConvention.Stdcall,
|
||||
else => std.builtin.CallingConvention.C,
|
||||
};
|
||||
@@ -1487,7 +1488,7 @@ pub fn updateExports(
|
||||
self.base.options.link_libc)
|
||||
{
|
||||
mod.stage1_flags.have_c_main = true;
|
||||
} else if (decl_cc == winapi_cc and self.base.options.target.os.tag == .windows) {
|
||||
} else if (decl_cc == winapi_cc and target.os.tag == .windows) {
|
||||
if (ip.stringEqlSlice(exp.opts.name, "WinMain")) {
|
||||
mod.stage1_flags.have_winmain = true;
|
||||
} else if (ip.stringEqlSlice(exp.opts.name, "wWinMain")) {
|
||||
@@ -2200,6 +2201,7 @@ fn writeDataDirectoriesHeaders(self: *Coff) !void {
|
||||
}
|
||||
|
||||
fn writeHeader(self: *Coff) !void {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const gpa = self.base.comp.gpa;
|
||||
var buffer = std.ArrayList(u8).init(gpa);
|
||||
defer buffer.deinit();
|
||||
@@ -2225,7 +2227,7 @@ fn writeHeader(self: *Coff) !void {
|
||||
const timestamp = std.time.timestamp();
|
||||
const size_of_optional_header = @as(u16, @intCast(self.getOptionalHeaderSize() + self.getDataDirectoryHeadersSize()));
|
||||
var coff_header = coff.CoffHeader{
|
||||
.machine = coff.MachineType.fromTargetCpuArch(self.base.options.target.cpu.arch),
|
||||
.machine = coff.MachineType.fromTargetCpuArch(target.cpu.arch),
|
||||
.number_of_sections = @as(u16, @intCast(self.sections.slice().len)), // TODO what if we prune a section
|
||||
.time_date_stamp = @as(u32, @truncate(@as(u64, @bitCast(timestamp)))),
|
||||
.pointer_to_symbol_table = self.strtab_offset orelse 0,
|
||||
@@ -2451,8 +2453,9 @@ pub fn getEntryPoint(self: Coff) ?SymbolWithLoc {
|
||||
}
|
||||
|
||||
pub fn getImageBase(self: Coff) u64 {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const image_base: u64 = self.base.options.image_base_override orelse switch (self.base.comp.config.output_mode) {
|
||||
.Exe => switch (self.base.options.target.cpu.arch) {
|
||||
.Exe => switch (target.cpu.arch) {
|
||||
.aarch64 => @as(u64, 0x140000000),
|
||||
.x86_64, .x86 => 0x400000,
|
||||
else => unreachable, // unsupported target architecture
|
||||
|
||||
@@ -107,7 +107,8 @@ pub fn resolve(self: Relocation, atom_index: Atom.Index, code: []u8, image_base:
|
||||
.ptr_width = coff_file.ptr_width,
|
||||
};
|
||||
|
||||
switch (coff_file.base.options.target.cpu.arch) {
|
||||
const target = coff_file.base.comp.root_mod.resolved_target.result;
|
||||
switch (target.cpu.arch) {
|
||||
.aarch64 => self.resolveAarch64(ctx),
|
||||
.x86, .x86_64 => self.resolveX86(ctx),
|
||||
else => unreachable, // unhandled target architecture
|
||||
|
||||
@@ -49,7 +49,7 @@ pub fn linkWithLLD(self: *Coff, comp: *Compilation, prog_node: *std.Progress.Nod
|
||||
const is_dyn_lib = self.base.comp.config.link_mode == .Dynamic and is_lib;
|
||||
const is_exe_or_dyn_lib = is_dyn_lib or self.base.comp.config.output_mode == .Exe;
|
||||
const link_in_crt = self.base.options.link_libc and is_exe_or_dyn_lib;
|
||||
const target = self.base.options.target;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const optimize_mode = self.base.comp.root_mod.optimize_mode;
|
||||
|
||||
// See link/Elf.zig for comments on how this mechanism works.
|
||||
|
||||
@@ -54,7 +54,8 @@ pub fn parse(self: *Object, elf_file: *Elf) !void {
|
||||
|
||||
self.header = try reader.readStruct(elf.Elf64_Ehdr);
|
||||
|
||||
if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
|
||||
const target = elf_file.base.comp.root_mod.resolved_target.result;
|
||||
if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
|
||||
try elf_file.reportParseError2(
|
||||
self.index,
|
||||
"invalid cpu architecture: {s}",
|
||||
|
||||
@@ -53,7 +53,8 @@ pub fn parse(self: *SharedObject, elf_file: *Elf) !void {
|
||||
|
||||
self.header = try reader.readStruct(elf.Elf64_Ehdr);
|
||||
|
||||
if (elf_file.base.options.target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
|
||||
const target = elf_file.base.comp.root_mod.resolved_target.result;
|
||||
if (target.cpu.arch != self.header.?.e_machine.toTargetCpuArch().?) {
|
||||
try elf_file.reportParseError2(
|
||||
self.index,
|
||||
"invalid cpu architecture: {s}",
|
||||
|
||||
@@ -287,7 +287,8 @@ pub const ZigGotSection = struct {
|
||||
zig_got.flags.dirty = false;
|
||||
}
|
||||
const entry_size: u16 = elf_file.archPtrWidthBytes();
|
||||
const endian = elf_file.base.options.target.cpu.arch.endian();
|
||||
const target = elf_file.base.comp.root_mod.resolved_target.result;
|
||||
const endian = target.cpu.arch.endian();
|
||||
const off = zig_got.entryOffset(index, elf_file);
|
||||
const vaddr = zig_got.entryAddress(index, elf_file);
|
||||
const entry = zig_got.entries.items[index];
|
||||
@@ -1575,7 +1576,8 @@ pub const ComdatGroupSection = struct {
|
||||
|
||||
fn writeInt(value: anytype, elf_file: *Elf, writer: anytype) !void {
|
||||
const entry_size = elf_file.archPtrWidthBytes();
|
||||
const endian = elf_file.base.options.target.cpu.arch.endian();
|
||||
const target = elf_file.base.comp.root_mod.resolved_target.result;
|
||||
const endian = target.cpu.arch.endian();
|
||||
switch (entry_size) {
|
||||
2 => try writer.writeInt(u16, @intCast(value), endian),
|
||||
4 => try writer.writeInt(u32, @intCast(value), endian),
|
||||
|
||||
@@ -143,7 +143,7 @@ tlv_table: TlvSymbolTable = .{},
|
||||
/// Hot-code swapping state.
|
||||
hot_state: if (is_hot_update_compatible) HotUpdateState else struct {} = .{},
|
||||
|
||||
darwin_sdk_layout: ?SdkLayout,
|
||||
sdk_layout: ?SdkLayout,
|
||||
/// Size of the __PAGEZERO segment.
|
||||
pagezero_vmsize: u64,
|
||||
/// Minimum space for future expansion of the load commands.
|
||||
@@ -184,20 +184,21 @@ pub const SdkLayout = enum {
|
||||
|
||||
pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {
|
||||
if (build_options.only_c) unreachable;
|
||||
const target = options.comp.root_mod.resolved_target.result;
|
||||
const use_lld = build_options.have_llvm and options.comp.config.use_lld;
|
||||
const use_llvm = options.comp.config.use_llvm;
|
||||
const comp = options.comp;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
const use_lld = build_options.have_llvm and comp.config.use_lld;
|
||||
const use_llvm = comp.config.use_llvm;
|
||||
assert(target.ofmt == .macho);
|
||||
|
||||
const gpa = options.comp.gpa;
|
||||
const gpa = comp.gpa;
|
||||
const emit = options.emit;
|
||||
const mode: Mode = mode: {
|
||||
if (use_llvm or options.module == null or options.cache_mode == .whole)
|
||||
if (use_llvm or comp.module == null or comp.cache_mode == .whole)
|
||||
break :mode .zld;
|
||||
break :mode .incremental;
|
||||
};
|
||||
const sub_path = if (mode == .zld) blk: {
|
||||
if (options.module == null) {
|
||||
if (comp.module == null) {
|
||||
// No point in opening a file, we would not write anything to it.
|
||||
// Initialize with empty.
|
||||
return createEmpty(arena, options);
|
||||
@@ -225,13 +226,13 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {
|
||||
.read = true,
|
||||
.mode = link.File.determineMode(
|
||||
use_lld,
|
||||
options.comp.config.output_mode,
|
||||
options.comp.config.link_mode,
|
||||
comp.config.output_mode,
|
||||
comp.config.link_mode,
|
||||
),
|
||||
});
|
||||
self.base.file = file;
|
||||
|
||||
if (!options.strip and options.module != null) {
|
||||
if (self.base.debug_format != .strip and comp.module != null) {
|
||||
// Create dSYM bundle.
|
||||
log.debug("creating {s}.dSYM bundle", .{sub_path});
|
||||
|
||||
@@ -276,14 +277,15 @@ pub fn open(arena: Allocator, options: link.File.OpenOptions) !*MachO {
|
||||
}
|
||||
|
||||
pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {
|
||||
const self = try arena.create(MachO);
|
||||
const optimize_mode = options.comp.root_mod.optimize_mode;
|
||||
const use_llvm = options.comp.config.use_llvm;
|
||||
const comp = options.comp;
|
||||
const optimize_mode = comp.root_mod.optimize_mode;
|
||||
const use_llvm = comp.config.use_llvm;
|
||||
|
||||
const self = try arena.create(MachO);
|
||||
self.* = .{
|
||||
.base = .{
|
||||
.tag = .macho,
|
||||
.comp = options.comp,
|
||||
.comp = comp,
|
||||
.emit = options.emit,
|
||||
.gc_sections = options.gc_sections orelse (optimize_mode != .Debug),
|
||||
.stack_size = options.stack_size orelse 16777216,
|
||||
@@ -297,7 +299,7 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {
|
||||
.function_sections = options.function_sections,
|
||||
.data_sections = options.data_sections,
|
||||
},
|
||||
.mode = if (use_llvm or options.module == null or options.cache_mode == .whole)
|
||||
.mode = if (use_llvm or comp.module == null or comp.cache_mode == .whole)
|
||||
.zld
|
||||
else
|
||||
.incremental,
|
||||
@@ -305,9 +307,13 @@ pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*MachO {
|
||||
.headerpad_size = options.headerpad_size orelse default_headerpad_size,
|
||||
.headerpad_max_install_names = options.headerpad_max_install_names,
|
||||
.dead_strip_dylibs = options.dead_strip_dylibs,
|
||||
.sdk_layout = options.darwin_sdk_layout,
|
||||
.frameworks = options.frameworks,
|
||||
.install_name = options.install_name,
|
||||
.entitlements = options.entitlements,
|
||||
};
|
||||
|
||||
if (use_llvm and options.module != null) {
|
||||
if (use_llvm and comp.module != null) {
|
||||
self.llvm_object = try LlvmObject.create(arena, options);
|
||||
}
|
||||
|
||||
@@ -357,6 +363,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
|
||||
const output_mode = self.base.comp.config.output_mode;
|
||||
const module = self.base.comp.module orelse return error.LinkingWithoutZigSourceUnimplemented;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
if (self.lazy_syms.getPtr(.none)) |metadata| {
|
||||
// Most lazy symbols can be updated on first use, but
|
||||
@@ -569,7 +576,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
// written out to the file.
|
||||
// The most important here is to have the correct vm and filesize of the __LINKEDIT segment
|
||||
// where the code signature goes into.
|
||||
var codesig = CodeSignature.init(getPageSize(self.base.options.target.cpu.arch));
|
||||
var codesig = CodeSignature.init(getPageSize(target.cpu.arch));
|
||||
codesig.code_directory.ident = self.base.emit.sub_path;
|
||||
if (self.entitlements) |path| {
|
||||
try codesig.addEntitlements(gpa, path);
|
||||
@@ -619,7 +626,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No
|
||||
.version = 0,
|
||||
});
|
||||
{
|
||||
const platform = Platform.fromTarget(self.base.options.target);
|
||||
const platform = Platform.fromTarget(target);
|
||||
const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
|
||||
if (platform.isBuildVersionCompatible()) {
|
||||
try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
|
||||
@@ -701,7 +708,7 @@ pub fn resolveLibSystem(
|
||||
var checked_paths = std.ArrayList([]const u8).init(arena);
|
||||
|
||||
success: {
|
||||
if (self.base.options.darwin_sdk_layout) |sdk_layout| switch (sdk_layout) {
|
||||
if (self.sdk_layout) |sdk_layout| switch (sdk_layout) {
|
||||
.sdk => {
|
||||
const dir = try fs.path.join(arena, &[_][]const u8{ self.base.options.sysroot.?, "usr", "lib" });
|
||||
if (try accessLibPath(arena, &test_path, &checked_paths, dir, "libSystem")) break :success;
|
||||
@@ -817,6 +824,7 @@ fn parseObject(
|
||||
defer tracy.end();
|
||||
|
||||
const gpa = self.base.comp.gpa;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const mtime: u64 = mtime: {
|
||||
const stat = file.stat() catch break :mtime 0;
|
||||
break :mtime @as(u64, @intCast(@divFloor(stat.mtime, 1_000_000_000)));
|
||||
@@ -839,8 +847,8 @@ fn parseObject(
|
||||
else => unreachable,
|
||||
};
|
||||
const detected_platform = object.getPlatform();
|
||||
const this_cpu_arch = self.base.options.target.cpu.arch;
|
||||
const this_platform = Platform.fromTarget(self.base.options.target);
|
||||
const this_cpu_arch = target.cpu.arch;
|
||||
const this_platform = Platform.fromTarget(target);
|
||||
|
||||
if (this_cpu_arch != detected_cpu_arch or
|
||||
(detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
|
||||
@@ -867,8 +875,10 @@ pub fn parseLibrary(
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
if (fat.isFatLibrary(file)) {
|
||||
const offset = try self.parseFatLibrary(file, self.base.options.target.cpu.arch, ctx);
|
||||
const offset = try self.parseFatLibrary(file, target.cpu.arch, ctx);
|
||||
try file.seekTo(offset);
|
||||
|
||||
if (Archive.isArchive(file, offset)) {
|
||||
@@ -934,6 +944,7 @@ fn parseArchive(
|
||||
ctx: *ParseErrorCtx,
|
||||
) ParseError!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
// We take ownership of the file so that we can store it for the duration of symbol resolution.
|
||||
// TODO we shouldn't need to do that and could pre-parse the archive like we do for zld/ELF?
|
||||
@@ -963,8 +974,8 @@ fn parseArchive(
|
||||
else => unreachable,
|
||||
};
|
||||
const detected_platform = object.getPlatform();
|
||||
const this_cpu_arch = self.base.options.target.cpu.arch;
|
||||
const this_platform = Platform.fromTarget(self.base.options.target);
|
||||
const this_cpu_arch = target.cpu.arch;
|
||||
const this_platform = Platform.fromTarget(target);
|
||||
|
||||
if (this_cpu_arch != detected_cpu_arch or
|
||||
(detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
|
||||
@@ -1015,6 +1026,7 @@ fn parseDylib(
|
||||
ctx: *ParseErrorCtx,
|
||||
) ParseError!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const file_stat = try file.stat();
|
||||
const file_size = math.cast(usize, file_stat.size - offset) orelse return error.Overflow;
|
||||
|
||||
@@ -1038,8 +1050,8 @@ fn parseDylib(
|
||||
else => unreachable,
|
||||
};
|
||||
const detected_platform = dylib.getPlatform(contents);
|
||||
const this_cpu_arch = self.base.options.target.cpu.arch;
|
||||
const this_platform = Platform.fromTarget(self.base.options.target);
|
||||
const this_cpu_arch = target.cpu.arch;
|
||||
const this_platform = Platform.fromTarget(target);
|
||||
|
||||
if (this_cpu_arch != detected_cpu_arch or
|
||||
(detected_platform != null and !detected_platform.?.eqlTarget(this_platform)))
|
||||
@@ -1061,6 +1073,8 @@ fn parseLibStub(
|
||||
ctx: *ParseErrorCtx,
|
||||
) ParseError!void {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
var lib_stub = try LibStub.loadFromFile(gpa, file);
|
||||
defer lib_stub.deinit();
|
||||
|
||||
@@ -1068,7 +1082,7 @@ fn parseLibStub(
|
||||
|
||||
// Verify target
|
||||
{
|
||||
var matcher = try Dylib.TargetMatcher.init(gpa, self.base.options.target);
|
||||
var matcher = try Dylib.TargetMatcher.init(gpa, target);
|
||||
defer matcher.deinit();
|
||||
|
||||
const first_tbd = lib_stub.inner[0];
|
||||
@@ -1091,7 +1105,7 @@ fn parseLibStub(
|
||||
|
||||
try dylib.parseFromStub(
|
||||
gpa,
|
||||
self.base.options.target,
|
||||
target,
|
||||
lib_stub,
|
||||
@intCast(self.dylibs.items.len), // TODO defer it till later
|
||||
dependent_libs,
|
||||
@@ -1236,7 +1250,8 @@ pub fn writeAtom(self: *MachO, atom_index: Atom.Index, code: []u8) !void {
|
||||
|
||||
fn writeToMemory(self: *MachO, task: std.os.darwin.MachTask, segment_index: u8, addr: u64, code: []const u8) !void {
|
||||
const segment = self.segments.items[segment_index];
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const nwritten = if (!segment.isWriteable())
|
||||
try task.writeMemProtected(addr, code, cpu_arch)
|
||||
else
|
||||
@@ -1280,7 +1295,8 @@ fn writeStubHelperPreamble(self: *MachO) !void {
|
||||
if (self.stub_helper_preamble_allocated) return;
|
||||
|
||||
const gpa = self.base.comp.gpa;
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const size = stubs.stubHelperPreambleSize(cpu_arch);
|
||||
|
||||
var buf = try std.ArrayList(u8).initCapacity(gpa, size);
|
||||
@@ -1306,11 +1322,12 @@ fn writeStubHelperPreamble(self: *MachO) !void {
|
||||
}
|
||||
|
||||
fn writeStubTableEntry(self: *MachO, index: usize) !void {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const stubs_sect_id = self.stubs_section_index.?;
|
||||
const stub_helper_sect_id = self.stub_helper_section_index.?;
|
||||
const laptr_sect_id = self.la_symbol_ptr_section_index.?;
|
||||
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const stub_entry_size = stubs.stubSize(cpu_arch);
|
||||
const stub_helper_entry_size = stubs.stubHelperSize(cpu_arch);
|
||||
const stub_helper_preamble_size = stubs.stubHelperPreambleSize(cpu_arch);
|
||||
@@ -2243,7 +2260,7 @@ pub fn addStubEntry(self: *MachO, target: SymbolWithLoc) !void {
|
||||
.flags = macho.S_SYMBOL_STUBS |
|
||||
macho.S_ATTR_PURE_INSTRUCTIONS |
|
||||
macho.S_ATTR_SOME_INSTRUCTIONS,
|
||||
.reserved2 = stubs.stubSize(self.base.options.target.cpu.arch),
|
||||
.reserved2 = stubs.stubSize(target.cpu.arch),
|
||||
});
|
||||
self.stub_helper_section_index = try self.initSection("__TEXT", "__stub_helper", .{
|
||||
.flags = macho.S_REGULAR |
|
||||
@@ -3116,7 +3133,8 @@ fn populateMissingMetadata(self: *MachO) !void {
|
||||
assert(self.mode == .incremental);
|
||||
|
||||
const gpa = self.base.comp.gpa;
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const pagezero_vmsize = self.calcPagezeroSize();
|
||||
|
||||
if (self.pagezero_segment_cmd_index == null) {
|
||||
@@ -3263,7 +3281,8 @@ fn populateMissingMetadata(self: *MachO) !void {
|
||||
|
||||
fn calcPagezeroSize(self: *MachO) u64 {
|
||||
const output_mode = self.base.comp.config.output_mode;
|
||||
const page_size = getPageSize(self.base.options.target.cpu.arch);
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = getPageSize(target.cpu.arch);
|
||||
const aligned_pagezero_vmsize = mem.alignBackward(u64, self.pagezero_vmsize, page_size);
|
||||
if (output_mode == .Lib) return 0;
|
||||
if (aligned_pagezero_vmsize == 0) return 0;
|
||||
@@ -3305,7 +3324,8 @@ fn allocateSection(self: *MachO, segname: []const u8, sectname: []const u8, opts
|
||||
reserved2: u32 = 0,
|
||||
}) !u8 {
|
||||
const gpa = self.base.comp.gpa;
|
||||
const page_size = getPageSize(self.base.options.target.cpu.arch);
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = getPageSize(target.cpu.arch);
|
||||
// In incremental context, we create one section per segment pairing. This way,
|
||||
// we can move the segment in raw file as we please.
|
||||
const segment_id = @as(u8, @intCast(self.segments.items.len));
|
||||
@@ -3360,7 +3380,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
|
||||
const segment = &self.segments.items[segment_index];
|
||||
const maybe_last_atom_index = self.sections.items(.last_atom_index)[sect_id];
|
||||
const sect_capacity = self.allocatedSize(header.offset);
|
||||
const page_size = getPageSize(self.base.options.target.cpu.arch);
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = getPageSize(target.cpu.arch);
|
||||
|
||||
if (needed_size > sect_capacity) {
|
||||
const new_offset = self.findFreeSpace(needed_size, page_size);
|
||||
@@ -3400,7 +3421,8 @@ fn growSection(self: *MachO, sect_id: u8, needed_size: u64) !void {
|
||||
}
|
||||
|
||||
fn growSectionVirtualMemory(self: *MachO, sect_id: u8, needed_size: u64) !void {
|
||||
const page_size = getPageSize(self.base.options.target.cpu.arch);
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = getPageSize(target.cpu.arch);
|
||||
const header = &self.sections.items(.header)[sect_id];
|
||||
const segment = self.getSegmentPtr(sect_id);
|
||||
const increased_size = padToIdeal(needed_size);
|
||||
@@ -3611,7 +3633,8 @@ pub fn writeSegmentHeaders(self: *MachO, writer: anytype) !void {
|
||||
}
|
||||
|
||||
pub fn writeLinkeditSegmentData(self: *MachO) !void {
|
||||
const page_size = getPageSize(self.base.options.target.cpu.arch);
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = getPageSize(target.cpu.arch);
|
||||
const seg = self.getLinkeditSegmentPtr();
|
||||
seg.filesize = 0;
|
||||
seg.vmsize = 0;
|
||||
@@ -3698,7 +3721,8 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
|
||||
}
|
||||
|
||||
// Finally, unpack the rest.
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
for (self.objects.items) |*object| {
|
||||
for (object.atoms.items) |atom_index| {
|
||||
const atom = self.getAtom(atom_index);
|
||||
@@ -3744,14 +3768,14 @@ fn collectRebaseData(self: *MachO, rebase: *Rebase) !void {
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
const target = Atom.parseRelocTarget(self, .{
|
||||
const reloc_target = Atom.parseRelocTarget(self, .{
|
||||
.object_id = atom.getFile().?,
|
||||
.rel = rel,
|
||||
.code = code,
|
||||
.base_offset = ctx.base_offset,
|
||||
.base_addr = ctx.base_addr,
|
||||
});
|
||||
const target_sym = self.getSymbol(target);
|
||||
const target_sym = self.getSymbol(reloc_target);
|
||||
if (target_sym.undf()) continue;
|
||||
|
||||
const base_offset = @as(i32, @intCast(sym.n_value - segment.vmaddr));
|
||||
@@ -3853,7 +3877,8 @@ fn collectBindData(self: *MachO, bind: anytype, raw_bindings: anytype) !void {
|
||||
}
|
||||
|
||||
// Finally, unpack the rest.
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
for (self.objects.items) |*object| {
|
||||
for (object.atoms.items) |atom_index| {
|
||||
const atom = self.getAtom(atom_index);
|
||||
@@ -4072,7 +4097,8 @@ fn populateLazyBindOffsetsInStubHelper(self: *MachO, lazy_bind: anytype) !void {
|
||||
|
||||
const header = self.sections.items(.header)[stub_helper_section_index];
|
||||
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const preamble_size = stubs.stubHelperPreambleSize(cpu_arch);
|
||||
const stub_size = stubs.stubHelperSize(cpu_arch);
|
||||
const stub_offset = stubs.stubOffsetInStubHelper(cpu_arch);
|
||||
@@ -4708,13 +4734,14 @@ pub fn writeUuid(self: *MachO, comp: *const Compilation, uuid_cmd_offset: u32, h
|
||||
}
|
||||
|
||||
pub fn writeCodeSignaturePadding(self: *MachO, code_sig: *CodeSignature) !void {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const seg = self.getLinkeditSegmentPtr();
|
||||
// Code signature data has to be 16-bytes aligned for Apple tools to recognize the file
|
||||
// https://github.com/opensource-apple/cctools/blob/fdb4825f303fd5c0751be524babd32958181b3ed/libstuff/checkout.c#L271
|
||||
const offset = mem.alignForward(u64, seg.fileoff + seg.filesize, 16);
|
||||
const needed_size = code_sig.estimateSize(offset);
|
||||
seg.filesize = offset + needed_size - seg.fileoff;
|
||||
seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(self.base.options.target.cpu.arch));
|
||||
seg.vmsize = mem.alignForward(u64, seg.filesize, getPageSize(target.cpu.arch));
|
||||
log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ offset, offset + needed_size });
|
||||
// Pad out the space. We need to do this to calculate valid hashes for everything in the file
|
||||
// except for code signature data.
|
||||
@@ -4758,7 +4785,8 @@ pub fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void {
|
||||
var header: macho.mach_header_64 = .{};
|
||||
header.flags = macho.MH_NOUNDEFS | macho.MH_DYLDLINK | macho.MH_PIE | macho.MH_TWOLEVEL;
|
||||
|
||||
switch (self.base.options.target.cpu.arch) {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
switch (target.cpu.arch) {
|
||||
.aarch64 => {
|
||||
header.cputype = macho.CPU_TYPE_ARM64;
|
||||
header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
|
||||
@@ -5123,9 +5151,10 @@ pub fn getTlvPtrEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {
|
||||
}
|
||||
|
||||
pub fn getStubsEntryAddress(self: *MachO, sym_with_loc: SymbolWithLoc) ?u64 {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const index = self.stub_table.lookup.get(sym_with_loc) orelse return null;
|
||||
const header = self.sections.items(.header)[self.stubs_section_index.?];
|
||||
return header.addr + stubs.stubSize(self.base.options.target.cpu.arch) * index;
|
||||
return header.addr + stubs.stubSize(target.cpu.arch) * index;
|
||||
}
|
||||
|
||||
/// Returns symbol location corresponding to the set entrypoint if any.
|
||||
@@ -5234,8 +5263,9 @@ pub fn handleAndReportParseError(
|
||||
err: ParseError,
|
||||
ctx: *const ParseErrorCtx,
|
||||
) error{OutOfMemory}!void {
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const gpa = self.base.comp.gpa;
|
||||
const cpu_arch = self.base.options.target.cpu.arch;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
switch (err) {
|
||||
error.DylibAlreadyExists => {},
|
||||
error.IncompatibleDylibVersion => {
|
||||
@@ -5270,7 +5300,7 @@ pub fn handleAndReportParseError(
|
||||
error.InvalidTarget => try self.reportParseError(
|
||||
path,
|
||||
"invalid target: expected '{}', but found '{s}'",
|
||||
.{ Platform.fromTarget(self.base.options.target).fmtTarget(cpu_arch), targets_string.items },
|
||||
.{ Platform.fromTarget(target).fmtTarget(cpu_arch), targets_string.items },
|
||||
),
|
||||
error.InvalidTargetFatLibrary => try self.reportParseError(
|
||||
path,
|
||||
|
||||
@@ -387,7 +387,8 @@ pub fn calcInnerSymbolOffset(macho_file: *MachO, atom_index: Index, sym_index: u
|
||||
}
|
||||
|
||||
pub fn scanAtomRelocs(macho_file: *MachO, atom_index: Index, relocs: []align(1) const macho.relocation_info) !void {
|
||||
const arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const arch = target.cpu.arch;
|
||||
const atom = macho_file.getAtom(atom_index);
|
||||
assert(atom.getFile() != null); // synthetic atoms do not have relocs
|
||||
|
||||
@@ -434,6 +435,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const object = &macho_file.objects.items[ctx.object_id];
|
||||
log.debug("parsing reloc target in object({d}) '{s}' ", .{ ctx.object_id, object.name });
|
||||
|
||||
@@ -447,7 +449,7 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
|
||||
else
|
||||
mem.readInt(u32, ctx.code[rel_offset..][0..4], .little);
|
||||
} else blk: {
|
||||
assert(macho_file.base.options.target.cpu.arch == .x86_64);
|
||||
assert(target.cpu.arch == .x86_64);
|
||||
const correction: u3 = switch (@as(macho.reloc_type_x86_64, @enumFromInt(ctx.rel.r_type))) {
|
||||
.X86_64_RELOC_SIGNED => 0,
|
||||
.X86_64_RELOC_SIGNED_1 => 1,
|
||||
@@ -467,18 +469,18 @@ pub fn parseRelocTarget(macho_file: *MachO, ctx: struct {
|
||||
|
||||
const sym_loc = SymbolWithLoc{ .sym_index = sym_index, .file = ctx.object_id + 1 };
|
||||
const sym = macho_file.getSymbol(sym_loc);
|
||||
const target = if (sym.sect() and !sym.ext())
|
||||
const reloc_target = if (sym.sect() and !sym.ext())
|
||||
sym_loc
|
||||
else if (object.getGlobal(sym_index)) |global_index|
|
||||
macho_file.globals.items[global_index]
|
||||
else
|
||||
sym_loc;
|
||||
log.debug(" | target %{d} ('{s}') in object({?d})", .{
|
||||
target.sym_index,
|
||||
macho_file.getSymbolName(target),
|
||||
target.getFile(),
|
||||
reloc_target.sym_index,
|
||||
macho_file.getSymbolName(reloc_target),
|
||||
reloc_target.getFile(),
|
||||
});
|
||||
return target;
|
||||
return reloc_target;
|
||||
}
|
||||
|
||||
pub fn getRelocTargetAtomIndex(macho_file: *MachO, target: SymbolWithLoc) ?Index {
|
||||
@@ -599,7 +601,8 @@ pub fn resolveRelocs(
|
||||
atom_code: []u8,
|
||||
atom_relocs: []align(1) const macho.relocation_info,
|
||||
) !void {
|
||||
const arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const arch = target.cpu.arch;
|
||||
const atom = macho_file.getAtom(atom_index);
|
||||
assert(atom.getFile() != null); // synthetic atoms do not have relocs
|
||||
|
||||
@@ -1192,7 +1195,8 @@ pub fn getAtomRelocs(macho_file: *MachO, atom_index: Index) []const macho.reloca
|
||||
}
|
||||
|
||||
pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {
|
||||
switch (macho_file.base.options.target.cpu.arch) {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
switch (target.cpu.arch) {
|
||||
.aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
|
||||
.ARM64_RELOC_GOT_LOAD_PAGE21,
|
||||
.ARM64_RELOC_GOT_LOAD_PAGEOFF12,
|
||||
@@ -1211,7 +1215,8 @@ pub fn relocRequiresGot(macho_file: *MachO, rel: macho.relocation_info) bool {
|
||||
}
|
||||
|
||||
pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {
|
||||
switch (macho_file.base.options.target.cpu.arch) {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
switch (target.cpu.arch) {
|
||||
.aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
|
||||
.ARM64_RELOC_TLVP_LOAD_PAGE21,
|
||||
.ARM64_RELOC_TLVP_LOAD_PAGEOFF12,
|
||||
@@ -1227,7 +1232,8 @@ pub fn relocIsTlv(macho_file: *MachO, rel: macho.relocation_info) bool {
|
||||
}
|
||||
|
||||
pub fn relocIsStub(macho_file: *MachO, rel: macho.relocation_info) bool {
|
||||
switch (macho_file.base.options.target.cpu.arch) {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
switch (target.cpu.arch) {
|
||||
.aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
|
||||
.ARM64_RELOC_BRANCH26 => return true,
|
||||
else => return false,
|
||||
|
||||
@@ -39,10 +39,12 @@ pub const Reloc = struct {
|
||||
/// You must call this function *after* `MachO.populateMissingMetadata()`
|
||||
/// has been called to get a viable debug symbols output.
|
||||
pub fn populateMissingMetadata(self: *DebugSymbols, macho_file: *MachO) !void {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
if (self.dwarf_segment_cmd_index == null) {
|
||||
self.dwarf_segment_cmd_index = @as(u8, @intCast(self.segments.items.len));
|
||||
|
||||
const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
|
||||
const page_size = MachO.getPageSize(target.cpu.arch);
|
||||
const off = @as(u64, @intCast(page_size));
|
||||
const ideal_size: u16 = 200 + 128 + 160 + 250;
|
||||
const needed_size = mem.alignForward(u64, padToIdeal(ideal_size), page_size);
|
||||
@@ -332,7 +334,8 @@ fn finalizeDwarfSegment(self: *DebugSymbols, macho_file: *MachO) void {
|
||||
file_size = @max(file_size, header.offset + header.size);
|
||||
}
|
||||
|
||||
const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = MachO.getPageSize(target.cpu.arch);
|
||||
const aligned_size = mem.alignForward(u64, file_size, page_size);
|
||||
dwarf_segment.vmaddr = base_vmaddr;
|
||||
dwarf_segment.filesize = aligned_size;
|
||||
@@ -394,10 +397,12 @@ fn writeSegmentHeaders(self: *DebugSymbols, macho_file: *MachO, writer: anytype)
|
||||
}
|
||||
|
||||
fn writeHeader(self: *DebugSymbols, macho_file: *MachO, ncmds: u32, sizeofcmds: u32) !void {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
var header: macho.mach_header_64 = .{};
|
||||
header.filetype = macho.MH_DSYM;
|
||||
|
||||
switch (macho_file.base.options.target.cpu.arch) {
|
||||
switch (target.cpu.arch) {
|
||||
.aarch64 => {
|
||||
header.cputype = macho.CPU_TYPE_ARM64;
|
||||
header.cpusubtype = macho.CPU_SUBTYPE_ARM_ALL;
|
||||
@@ -435,7 +440,8 @@ fn writeLinkeditSegmentData(self: *DebugSymbols, macho_file: *MachO) !void {
|
||||
try self.writeSymtab(macho_file);
|
||||
try self.writeStrtab();
|
||||
|
||||
const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = MachO.getPageSize(target.cpu.arch);
|
||||
const seg = &self.segments.items[self.linkedit_segment_cmd_index.?];
|
||||
const aligned_size = mem.alignForward(u64, seg.filesize, page_size);
|
||||
seg.vmsize = aligned_size;
|
||||
|
||||
@@ -355,6 +355,7 @@ pub fn splitIntoAtoms(self: *Object, macho_file: *MachO, object_id: u32) SplitIn
|
||||
/// into subsections where each subsection then represents an Atom.
|
||||
pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
const sections = self.getSourceSections();
|
||||
for (sections, 0..) |sect, id| {
|
||||
@@ -448,7 +449,7 @@ pub fn splitRegularSections(self: *Object, macho_file: *MachO, object_id: u32) !
|
||||
|
||||
try self.parseRelocs(gpa, section.id);
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const sect_loc = filterSymbolsBySection(symtab[sect_sym_index..], sect_id + 1);
|
||||
const sect_start_index = sect_sym_index + sect_loc.index;
|
||||
|
||||
@@ -676,7 +677,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
|
||||
macho_file.eh_frame_section_index = try macho_file.initSection("__TEXT", "__eh_frame", .{});
|
||||
}
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
try self.parseRelocs(gpa, sect_id);
|
||||
const relocs = self.getRelocs(sect_id);
|
||||
|
||||
@@ -704,7 +706,7 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
|
||||
});
|
||||
|
||||
if (record.tag == .fde) {
|
||||
const target = blk: {
|
||||
const reloc_target = blk: {
|
||||
switch (cpu_arch) {
|
||||
.aarch64 => {
|
||||
assert(rel_pos.len > 0); // TODO convert to an error as the FDE eh frame is malformed
|
||||
@@ -714,13 +716,13 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
|
||||
@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type)) == .ARM64_RELOC_UNSIGNED)
|
||||
break rel;
|
||||
} else unreachable;
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = object_id,
|
||||
.rel = rel,
|
||||
.code = it.data[offset..],
|
||||
.base_offset = @as(i32, @intCast(offset)),
|
||||
});
|
||||
break :blk target;
|
||||
break :blk reloc_target;
|
||||
},
|
||||
.x86_64 => {
|
||||
const target_address = record.getTargetSymbolAddress(.{
|
||||
@@ -728,16 +730,16 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
|
||||
.base_offset = offset,
|
||||
});
|
||||
const target_sym_index = self.getSymbolByAddress(target_address, null);
|
||||
const target = if (self.getGlobal(target_sym_index)) |global_index|
|
||||
const reloc_target = if (self.getGlobal(target_sym_index)) |global_index|
|
||||
macho_file.globals.items[global_index]
|
||||
else
|
||||
SymbolWithLoc{ .sym_index = target_sym_index, .file = object_id + 1 };
|
||||
break :blk target;
|
||||
break :blk reloc_target;
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
};
|
||||
if (target.getFile() != object_id) {
|
||||
if (reloc_target.getFile() != object_id) {
|
||||
log.debug("FDE at offset {x} marked DEAD", .{offset});
|
||||
self.eh_frame_relocs_lookup.getPtr(offset).?.dead = true;
|
||||
} else {
|
||||
@@ -746,12 +748,12 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
|
||||
// very problematic when using Zig's @export feature to re-export symbols under
|
||||
// additional names. For that reason, we need to ensure we record aliases here
|
||||
// too so that we can tie them with their matching unwind records and vice versa.
|
||||
const aliases = self.getSymbolAliases(target.sym_index);
|
||||
const aliases = self.getSymbolAliases(reloc_target.sym_index);
|
||||
var i: u32 = 0;
|
||||
while (i < aliases.len) : (i += 1) {
|
||||
const actual_target = SymbolWithLoc{
|
||||
.sym_index = i + aliases.start,
|
||||
.file = target.file,
|
||||
.file = reloc_target.file,
|
||||
};
|
||||
log.debug("FDE at offset {x} tracks {s}", .{
|
||||
offset,
|
||||
@@ -766,7 +768,8 @@ fn parseEhFrameSection(self: *Object, macho_file: *MachO, object_id: u32) !void
|
||||
|
||||
fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const sect_id = self.unwind_info_sect_id orelse {
|
||||
// If it so happens that the object had `__eh_frame` section defined but no `__compact_unwind`,
|
||||
// we will try fully synthesising unwind info records to somewhat match Apple ld's
|
||||
@@ -818,13 +821,13 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
|
||||
|
||||
// Find function symbol that this record describes
|
||||
const rel = relocs[rel_pos.start..][rel_pos.len - 1];
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = object_id,
|
||||
.rel = rel,
|
||||
.code = mem.asBytes(&record),
|
||||
.base_offset = @as(i32, @intCast(offset)),
|
||||
});
|
||||
if (target.getFile() != object_id) {
|
||||
if (reloc_target.getFile() != object_id) {
|
||||
log.debug("unwind record {d} marked DEAD", .{record_id});
|
||||
self.unwind_relocs_lookup[record_id].dead = true;
|
||||
} else {
|
||||
@@ -833,12 +836,12 @@ fn parseUnwindInfo(self: *Object, macho_file: *MachO, object_id: u32) !void {
|
||||
// very problematic when using Zig's @export feature to re-export symbols under
|
||||
// additional names. For that reason, we need to ensure we record aliases here
|
||||
// too so that we can tie them with their matching unwind records and vice versa.
|
||||
const aliases = self.getSymbolAliases(target.sym_index);
|
||||
const aliases = self.getSymbolAliases(reloc_target.sym_index);
|
||||
var i: u32 = 0;
|
||||
while (i < aliases.len) : (i += 1) {
|
||||
const actual_target = SymbolWithLoc{
|
||||
.sym_index = i + aliases.start,
|
||||
.file = target.file,
|
||||
.file = reloc_target.file,
|
||||
};
|
||||
log.debug("unwind record {d} tracks {s}", .{
|
||||
record_id,
|
||||
|
||||
@@ -58,11 +58,12 @@ pub fn isStubTrampoline(self: Relocation, macho_file: *MachO) bool {
|
||||
}
|
||||
|
||||
pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
if (self.isStubTrampoline(macho_file)) {
|
||||
const index = macho_file.stub_table.lookup.get(self.target) orelse return null;
|
||||
const header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];
|
||||
return header.addr +
|
||||
index * @import("stubs.zig").stubSize(macho_file.base.options.target.cpu.arch);
|
||||
index * @import("stubs.zig").stubSize(target.cpu.arch);
|
||||
}
|
||||
switch (self.type) {
|
||||
.got, .got_page, .got_pageoff => {
|
||||
@@ -84,7 +85,8 @@ pub fn getTargetBaseAddress(self: Relocation, macho_file: *MachO) ?u64 {
|
||||
}
|
||||
|
||||
pub fn resolve(self: Relocation, macho_file: *MachO, atom_index: Atom.Index, code: []u8) void {
|
||||
const arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const arch = target.cpu.arch;
|
||||
const atom = macho_file.getAtom(atom_index);
|
||||
const source_sym = atom.getSymbol(macho_file);
|
||||
const source_addr = source_sym.n_value + self.offset;
|
||||
|
||||
@@ -184,7 +184,8 @@ pub fn deinit(info: *UnwindInfo) void {
|
||||
pub fn scanRelocs(macho_file: *MachO) !void {
|
||||
if (macho_file.unwind_info_section_index == null) return;
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
for (macho_file.objects.items, 0..) |*object, object_id| {
|
||||
const unwind_records = object.getUnwindRecords();
|
||||
for (object.exec_atoms.items) |atom_index| {
|
||||
@@ -196,13 +197,13 @@ pub fn scanRelocs(macho_file: *MachO) !void {
|
||||
if (!UnwindEncoding.isDwarf(record.compactUnwindEncoding, cpu_arch)) {
|
||||
if (getPersonalityFunctionReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {
|
||||
// Personality function; add GOT pointer.
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = @as(u32, @intCast(object_id)),
|
||||
.rel = rel,
|
||||
.code = mem.asBytes(&record),
|
||||
.base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
|
||||
});
|
||||
try macho_file.addGotEntry(target);
|
||||
try macho_file.addGotEntry(reloc_target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -213,7 +214,8 @@ pub fn scanRelocs(macho_file: *MachO) !void {
|
||||
pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
|
||||
if (macho_file.unwind_info_section_index == null) return;
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
|
||||
var records = std.ArrayList(macho.compact_unwind_entry).init(info.gpa);
|
||||
defer records.deinit();
|
||||
@@ -247,15 +249,15 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
|
||||
@as(u32, @intCast(object_id)),
|
||||
record_id,
|
||||
)) |rel| {
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = @as(u32, @intCast(object_id)),
|
||||
.rel = rel,
|
||||
.code = mem.asBytes(&record),
|
||||
.base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
|
||||
});
|
||||
const personality_index = info.getPersonalityFunction(target) orelse inner: {
|
||||
const personality_index = info.getPersonalityFunction(reloc_target) orelse inner: {
|
||||
const personality_index = info.personalities_count;
|
||||
info.personalities[personality_index] = target;
|
||||
info.personalities[personality_index] = reloc_target;
|
||||
info.personalities_count += 1;
|
||||
break :inner personality_index;
|
||||
};
|
||||
@@ -265,13 +267,13 @@ pub fn collect(info: *UnwindInfo, macho_file: *MachO) !void {
|
||||
}
|
||||
|
||||
if (getLsdaReloc(macho_file, @as(u32, @intCast(object_id)), record_id)) |rel| {
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = @as(u32, @intCast(object_id)),
|
||||
.rel = rel,
|
||||
.code = mem.asBytes(&record),
|
||||
.base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
|
||||
});
|
||||
record.lsda = @as(u64, @bitCast(target));
|
||||
record.lsda = @as(u64, @bitCast(reloc_target));
|
||||
}
|
||||
}
|
||||
break :blk record;
|
||||
@@ -557,13 +559,14 @@ pub fn write(info: *UnwindInfo, macho_file: *MachO) !void {
|
||||
const text_sect = macho_file.sections.items(.header)[text_sect_id];
|
||||
|
||||
var personalities: [max_personalities]u32 = undefined;
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
|
||||
log.debug("Personalities:", .{});
|
||||
for (info.personalities[0..info.personalities_count], 0..) |target, i| {
|
||||
const addr = macho_file.getGotEntryAddress(target).?;
|
||||
for (info.personalities[0..info.personalities_count], 0..) |reloc_target, i| {
|
||||
const addr = macho_file.getGotEntryAddress(reloc_target).?;
|
||||
personalities[i] = @as(u32, @intCast(addr - seg.vmaddr));
|
||||
log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(target) });
|
||||
log.debug(" {d}: 0x{x} ({s})", .{ i, personalities[i], macho_file.getSymbolName(reloc_target) });
|
||||
}
|
||||
|
||||
for (info.records.items) |*rec| {
|
||||
|
||||
@@ -118,7 +118,8 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
|
||||
|
||||
alive.putAssumeCapacityNoClobber(atom_index, {});
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
|
||||
const sym = macho_file.getSymbol(atom.getSymbolWithLoc());
|
||||
const header = macho_file.sections.items(.header)[sym.n_sect - 1];
|
||||
@@ -129,7 +130,7 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
|
||||
const ctx = Atom.getRelocContext(macho_file, atom_index);
|
||||
|
||||
for (relocs) |rel| {
|
||||
const target = switch (cpu_arch) {
|
||||
const reloc_target = switch (cpu_arch) {
|
||||
.aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
|
||||
.ARM64_RELOC_ADDEND => continue,
|
||||
else => Atom.parseRelocTarget(macho_file, .{
|
||||
@@ -149,19 +150,19 @@ fn markLive(macho_file: *MachO, atom_index: Atom.Index, alive: *AtomTable) void
|
||||
}),
|
||||
else => unreachable,
|
||||
};
|
||||
const target_sym = macho_file.getSymbol(target);
|
||||
const target_sym = macho_file.getSymbol(reloc_target);
|
||||
|
||||
if (target_sym.undf()) continue;
|
||||
if (target.getFile() == null) {
|
||||
const target_sym_name = macho_file.getSymbolName(target);
|
||||
if (reloc_target.getFile() == null) {
|
||||
const target_sym_name = macho_file.getSymbolName(reloc_target);
|
||||
if (mem.eql(u8, "__mh_execute_header", target_sym_name)) continue;
|
||||
if (mem.eql(u8, "___dso_handle", target_sym_name)) continue;
|
||||
|
||||
unreachable; // referenced symbol not found
|
||||
}
|
||||
|
||||
const object = macho_file.objects.items[target.getFile().?];
|
||||
const target_atom_index = object.getAtomIndexForSymbol(target.sym_index).?;
|
||||
const object = macho_file.objects.items[reloc_target.getFile().?];
|
||||
const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index).?;
|
||||
log.debug(" following ATOM({d}, %{d}, {?d})", .{
|
||||
target_atom_index,
|
||||
macho_file.getAtom(target_atom_index).sym_index,
|
||||
@@ -178,7 +179,8 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
|
||||
|
||||
log.debug("refersLive(ATOM({d}, %{d}, {?d}))", .{ atom_index, sym_loc.sym_index, sym_loc.getFile() });
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
|
||||
const sym = macho_file.getSymbol(sym_loc);
|
||||
const header = macho_file.sections.items(.header)[sym.n_sect - 1];
|
||||
@@ -189,7 +191,7 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
|
||||
const ctx = Atom.getRelocContext(macho_file, atom_index);
|
||||
|
||||
for (relocs) |rel| {
|
||||
const target = switch (cpu_arch) {
|
||||
const reloc_target = switch (cpu_arch) {
|
||||
.aarch64 => switch (@as(macho.reloc_type_arm64, @enumFromInt(rel.r_type))) {
|
||||
.ARM64_RELOC_ADDEND => continue,
|
||||
else => Atom.parseRelocTarget(macho_file, .{
|
||||
@@ -210,9 +212,9 @@ fn refersLive(macho_file: *MachO, atom_index: Atom.Index, alive: AtomTable) bool
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
const object = macho_file.objects.items[target.getFile().?];
|
||||
const target_atom_index = object.getAtomIndexForSymbol(target.sym_index) orelse {
|
||||
log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(target)});
|
||||
const object = macho_file.objects.items[reloc_target.getFile().?];
|
||||
const target_atom_index = object.getAtomIndexForSymbol(reloc_target.sym_index) orelse {
|
||||
log.debug("atom for symbol '{s}' not found; skipping...", .{macho_file.getSymbolName(reloc_target)});
|
||||
continue;
|
||||
};
|
||||
if (alive.contains(target_atom_index)) {
|
||||
@@ -271,7 +273,8 @@ fn mark(macho_file: *MachO, roots: AtomTable, alive: *AtomTable) void {
|
||||
|
||||
fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void {
|
||||
const object = &macho_file.objects.items[object_id];
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
|
||||
const unwind_records = object.getUnwindRecords();
|
||||
|
||||
@@ -310,29 +313,29 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void
|
||||
markEhFrameRecords(macho_file, object_id, atom_index, alive);
|
||||
} else {
|
||||
if (UnwindInfo.getPersonalityFunctionReloc(macho_file, object_id, record_id)) |rel| {
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = object_id,
|
||||
.rel = rel,
|
||||
.code = mem.asBytes(&record),
|
||||
.base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
|
||||
});
|
||||
const target_sym = macho_file.getSymbol(target);
|
||||
const target_sym = macho_file.getSymbol(reloc_target);
|
||||
if (!target_sym.undf()) {
|
||||
const target_object = macho_file.objects.items[target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;
|
||||
const target_object = macho_file.objects.items[reloc_target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
|
||||
markLive(macho_file, target_atom_index, alive);
|
||||
}
|
||||
}
|
||||
|
||||
if (UnwindInfo.getLsdaReloc(macho_file, object_id, record_id)) |rel| {
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = object_id,
|
||||
.rel = rel,
|
||||
.code = mem.asBytes(&record),
|
||||
.base_offset = @as(i32, @intCast(record_id * @sizeOf(macho.compact_unwind_entry))),
|
||||
});
|
||||
const target_object = macho_file.objects.items[target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;
|
||||
const target_object = macho_file.objects.items[reloc_target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
|
||||
markLive(macho_file, target_atom_index, alive);
|
||||
}
|
||||
}
|
||||
@@ -341,7 +344,8 @@ fn markUnwindRecords(macho_file: *MachO, object_id: u32, alive: *AtomTable) void
|
||||
}
|
||||
|
||||
fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index, alive: *AtomTable) void {
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const object = &macho_file.objects.items[object_id];
|
||||
var it = object.getEhFrameRecordsIterator();
|
||||
var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);
|
||||
@@ -361,16 +365,16 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index
|
||||
// Mark FDE references which should include any referenced LSDA record
|
||||
const relocs = eh_frame.getRelocs(macho_file, object_id, fde_offset);
|
||||
for (relocs) |rel| {
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = object_id,
|
||||
.rel = rel,
|
||||
.code = fde.data,
|
||||
.base_offset = @as(i32, @intCast(fde_offset)) + 4,
|
||||
});
|
||||
const target_sym = macho_file.getSymbol(target);
|
||||
const target_sym = macho_file.getSymbol(reloc_target);
|
||||
if (!target_sym.undf()) blk: {
|
||||
const target_object = macho_file.objects.items[target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index) orelse
|
||||
const target_object = macho_file.objects.items[reloc_target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index) orelse
|
||||
break :blk;
|
||||
markLive(macho_file, target_atom_index, alive);
|
||||
}
|
||||
@@ -394,11 +398,11 @@ fn markEhFrameRecords(macho_file: *MachO, object_id: u32, atom_index: Atom.Index
|
||||
|
||||
// Mark CIE references which should include any referenced personalities
|
||||
// that are defined locally.
|
||||
if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |target| {
|
||||
const target_sym = macho_file.getSymbol(target);
|
||||
if (cie.getPersonalityPointerReloc(macho_file, object_id, cie_offset)) |reloc_target| {
|
||||
const target_sym = macho_file.getSymbol(reloc_target);
|
||||
if (!target_sym.undf()) {
|
||||
const target_object = macho_file.objects.items[target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(target.sym_index).?;
|
||||
const target_object = macho_file.objects.items[reloc_target.getFile().?];
|
||||
const target_atom_index = target_object.getAtomIndexForSymbol(reloc_target.sym_index).?;
|
||||
markLive(macho_file, target_atom_index, alive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ pub fn calcSectionSize(macho_file: *MachO, unwind_info: *const UnwindInfo) error
|
||||
sect.@"align" = 3;
|
||||
sect.size = 0;
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const gpa = macho_file.base.allocator;
|
||||
var size: u32 = 0;
|
||||
|
||||
@@ -86,7 +87,8 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
|
||||
const seg_id = macho_file.sections.items(.segment_index)[sect_id];
|
||||
const seg = macho_file.segments.items[seg_id];
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const gpa = macho_file.base.allocator;
|
||||
|
||||
var eh_records = std.AutoArrayHashMap(u32, EhFrameRecord(true)).init(gpa);
|
||||
@@ -109,11 +111,11 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
|
||||
|
||||
for (object.exec_atoms.items) |atom_index| {
|
||||
var inner_syms_it = Atom.getInnerSymbolsIterator(macho_file, atom_index);
|
||||
while (inner_syms_it.next()) |target| {
|
||||
const fde_record_offset = object.eh_frame_records_lookup.get(target) orelse continue;
|
||||
while (inner_syms_it.next()) |reloc_target| {
|
||||
const fde_record_offset = object.eh_frame_records_lookup.get(reloc_target) orelse continue;
|
||||
if (object.eh_frame_relocs_lookup.get(fde_record_offset).?.dead) continue;
|
||||
|
||||
const record_id = unwind_info.records_lookup.get(target) orelse continue;
|
||||
const record_id = unwind_info.records_lookup.get(reloc_target) orelse continue;
|
||||
const record = &unwind_info.records.items[record_id];
|
||||
|
||||
// TODO skip this check if no __compact_unwind is present
|
||||
@@ -153,7 +155,7 @@ pub fn write(macho_file: *MachO, unwind_info: *UnwindInfo) !void {
|
||||
.aarch64 => {}, // relocs take care of LSDA pointers
|
||||
.x86_64 => {
|
||||
// We need to relocate target symbol address ourselves.
|
||||
const atom_sym = macho_file.getSymbol(target);
|
||||
const atom_sym = macho_file.getSymbol(reloc_target);
|
||||
try fde_record.setTargetSymbolAddress(atom_sym.n_value, .{
|
||||
.base_addr = sect.addr,
|
||||
.base_offset = eh_frame_offset,
|
||||
@@ -278,7 +280,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
|
||||
object_id: u32,
|
||||
source_offset: u32,
|
||||
) ?SymbolWithLoc {
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const relocs = getRelocs(macho_file, object_id, source_offset);
|
||||
for (relocs) |rel| {
|
||||
switch (cpu_arch) {
|
||||
@@ -301,13 +304,13 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = object_id,
|
||||
.rel = rel,
|
||||
.code = rec.data,
|
||||
.base_offset = @as(i32, @intCast(source_offset)) + 4,
|
||||
});
|
||||
return target;
|
||||
return reloc_target;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -319,11 +322,12 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
|
||||
}) !void {
|
||||
comptime assert(is_mutable);
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const relocs = getRelocs(macho_file, object_id, ctx.source_offset);
|
||||
|
||||
for (relocs) |rel| {
|
||||
const target = Atom.parseRelocTarget(macho_file, .{
|
||||
const reloc_target = Atom.parseRelocTarget(macho_file, .{
|
||||
.object_id = object_id,
|
||||
.rel = rel,
|
||||
.code = rec.data,
|
||||
@@ -340,14 +344,14 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
|
||||
// Address of the __eh_frame in the source object file
|
||||
},
|
||||
.ARM64_RELOC_POINTER_TO_GOT => {
|
||||
const target_addr = macho_file.getGotEntryAddress(target).?;
|
||||
const target_addr = macho_file.getGotEntryAddress(reloc_target).?;
|
||||
const result = math.cast(i32, @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr))) orelse
|
||||
return error.Overflow;
|
||||
mem.writeInt(i32, rec.data[rel_offset..][0..4], result, .little);
|
||||
},
|
||||
.ARM64_RELOC_UNSIGNED => {
|
||||
assert(rel.r_extern == 1);
|
||||
const target_addr = Atom.getRelocTargetAddress(macho_file, target, false);
|
||||
const target_addr = Atom.getRelocTargetAddress(macho_file, reloc_target, false);
|
||||
const result = @as(i64, @intCast(target_addr)) - @as(i64, @intCast(source_addr));
|
||||
mem.writeInt(i64, rec.data[rel_offset..][0..8], @as(i64, @intCast(result)), .little);
|
||||
},
|
||||
@@ -358,7 +362,7 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
|
||||
const rel_type = @as(macho.reloc_type_x86_64, @enumFromInt(rel.r_type));
|
||||
switch (rel_type) {
|
||||
.X86_64_RELOC_GOT => {
|
||||
const target_addr = macho_file.getGotEntryAddress(target).?;
|
||||
const target_addr = macho_file.getGotEntryAddress(reloc_target).?;
|
||||
const addend = mem.readInt(i32, rec.data[rel_offset..][0..4], .little);
|
||||
const adjusted_target_addr = @as(u64, @intCast(@as(i64, @intCast(target_addr)) + addend));
|
||||
const disp = try Relocation.calcPcRelativeDisplacementX86(source_addr, adjusted_target_addr, 0);
|
||||
@@ -374,7 +378,8 @@ pub fn EhFrameRecord(comptime is_mutable: bool) type {
|
||||
|
||||
pub fn getCiePointerSource(rec: Record, object_id: u32, macho_file: *MachO, offset: u32) u32 {
|
||||
assert(rec.tag == .fde);
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const addend = mem.readInt(u32, rec.data[0..4], .little);
|
||||
switch (cpu_arch) {
|
||||
.aarch64 => {
|
||||
|
||||
@@ -472,11 +472,11 @@ pub fn inferSdkVersion(gpa: Allocator, comp: *const Compilation) ?std.SemanticVe
|
||||
defer arena_allocator.deinit();
|
||||
const arena = arena_allocator.allocator();
|
||||
|
||||
const options = comp.bin_file.options;
|
||||
const macho_file = comp.bin_file.cast(MachO).?;
|
||||
|
||||
const sdk_layout = options.darwin_sdk_layout orelse return null;
|
||||
const sdk_layout = macho_file.sdk_layout orelse return null;
|
||||
const sdk_dir = switch (sdk_layout) {
|
||||
.sdk => options.sysroot.?,
|
||||
.sdk => macho_file.sysroot.?,
|
||||
.vendored => std.fs.path.join(arena, &.{ comp.zig_lib_directory.path.?, "libc", "darwin" }) catch return null,
|
||||
};
|
||||
if (readSdkVersionFromSettings(arena, sdk_dir)) |ver| {
|
||||
|
||||
@@ -458,7 +458,7 @@ pub fn linkWithZld(
|
||||
}
|
||||
|
||||
try writeAtoms(macho_file);
|
||||
if (macho_file.base.options.target.cpu.arch == .aarch64) try writeThunks(macho_file);
|
||||
if (target.cpu.arch == .aarch64) try writeThunks(macho_file);
|
||||
try writeDyldPrivateAtom(macho_file);
|
||||
|
||||
if (macho_file.stubs_section_index) |_| {
|
||||
@@ -557,7 +557,7 @@ pub fn linkWithZld(
|
||||
.version = 0,
|
||||
});
|
||||
{
|
||||
const platform = Platform.fromTarget(macho_file.base.options.target);
|
||||
const platform = Platform.fromTarget(target);
|
||||
const sdk_version: ?std.SemanticVersion = load_commands.inferSdkVersion(arena, comp);
|
||||
if (platform.isBuildVersionCompatible()) {
|
||||
try load_commands.writeBuildVersionLC(platform, sdk_version, lc_writer);
|
||||
@@ -610,7 +610,8 @@ pub fn linkWithZld(
|
||||
|
||||
fn createSegments(macho_file: *MachO) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const page_size = MachO.getPageSize(target.cpu.arch);
|
||||
const aligned_pagezero_vmsize = mem.alignBackward(u64, macho_file.pagezero_vmsize, page_size);
|
||||
if (macho_file.base.comp.config.output_mode != .Lib and aligned_pagezero_vmsize > 0) {
|
||||
if (aligned_pagezero_vmsize != macho_file.pagezero_vmsize) {
|
||||
@@ -755,7 +756,8 @@ fn writeDyldPrivateAtom(macho_file: *MachO) !void {
|
||||
}
|
||||
|
||||
fn writeThunks(macho_file: *MachO) !void {
|
||||
assert(macho_file.base.options.target.cpu.arch == .aarch64);
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
assert(target.cpu.arch == .aarch64);
|
||||
const gpa = macho_file.base.allocator;
|
||||
|
||||
const sect_id = macho_file.text_section_index orelse return;
|
||||
@@ -791,7 +793,8 @@ fn writePointerEntries(macho_file: *MachO, sect_id: u8, table: anytype) !void {
|
||||
|
||||
fn writeStubs(macho_file: *MachO) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const stubs_header = macho_file.sections.items(.header)[macho_file.stubs_section_index.?];
|
||||
const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];
|
||||
|
||||
@@ -813,7 +816,8 @@ fn writeStubs(macho_file: *MachO) !void {
|
||||
|
||||
fn writeStubHelpers(macho_file: *MachO) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];
|
||||
|
||||
const capacity = math.cast(usize, stub_helper_header.size) orelse return error.Overflow;
|
||||
@@ -856,7 +860,8 @@ fn writeStubHelpers(macho_file: *MachO) !void {
|
||||
|
||||
fn writeLaSymbolPtrs(macho_file: *MachO) !void {
|
||||
const gpa = macho_file.base.allocator;
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
const la_symbol_ptr_header = macho_file.sections.items(.header)[macho_file.la_symbol_ptr_section_index.?];
|
||||
const stub_helper_header = macho_file.sections.items(.header)[macho_file.stub_helper_section_index.?];
|
||||
|
||||
@@ -964,11 +969,12 @@ fn pruneAndSortSections(macho_file: *MachO) !void {
|
||||
}
|
||||
|
||||
fn calcSectionSizes(macho_file: *MachO) !void {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const slice = macho_file.sections.slice();
|
||||
for (slice.items(.header), 0..) |*header, sect_id| {
|
||||
if (header.size == 0) continue;
|
||||
if (macho_file.text_section_index) |txt| {
|
||||
if (txt == sect_id and macho_file.base.options.target.cpu.arch == .aarch64) continue;
|
||||
if (txt == sect_id and target.cpu.arch == .aarch64) continue;
|
||||
}
|
||||
|
||||
var atom_index = slice.items(.first_atom_index)[sect_id] orelse continue;
|
||||
@@ -991,7 +997,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (macho_file.text_section_index != null and macho_file.base.options.target.cpu.arch == .aarch64) {
|
||||
if (macho_file.text_section_index != null and target.cpu.arch == .aarch64) {
|
||||
// Create jump/branch range extenders if needed.
|
||||
try thunks.createThunks(macho_file, macho_file.text_section_index.?);
|
||||
}
|
||||
@@ -1043,7 +1049,7 @@ fn calcSectionSizes(macho_file: *MachO) !void {
|
||||
header.@"align" = 3;
|
||||
}
|
||||
|
||||
const cpu_arch = macho_file.base.options.target.cpu.arch;
|
||||
const cpu_arch = target.cpu.arch;
|
||||
|
||||
if (macho_file.stubs_section_index) |sect_id| {
|
||||
const header = &macho_file.sections.items(.header)[sect_id];
|
||||
@@ -1093,6 +1099,7 @@ fn getSegmentAllocBase(macho_file: *MachO, segment_index: u8) struct { vmaddr: u
|
||||
}
|
||||
|
||||
fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void {
|
||||
const target = macho_file.base.comp.root_mod.resolved_target.result;
|
||||
const segment = &macho_file.segments.items[segment_index];
|
||||
|
||||
if (mem.eql(u8, segment.segName(), "__PAGEZERO")) return; // allocated upon creation
|
||||
@@ -1175,7 +1182,7 @@ fn allocateSegment(macho_file: *MachO, segment_index: u8, init_size: u64) !void
|
||||
segment.vmsize = start;
|
||||
}
|
||||
|
||||
const page_size = MachO.getPageSize(macho_file.base.options.target.cpu.arch);
|
||||
const page_size = MachO.getPageSize(target.cpu.arch);
|
||||
segment.filesize = mem.alignForward(u64, segment.filesize, page_size);
|
||||
segment.vmsize = mem.alignForward(u64, segment.vmsize, page_size);
|
||||
}
|
||||
|
||||
@@ -206,7 +206,8 @@ pub const Atom = struct {
|
||||
|
||||
// asserts that self.got_index != null
|
||||
pub fn getOffsetTableAddress(self: Atom, plan9: *Plan9) u64 {
|
||||
const ptr_bytes = @divExact(plan9.base.options.target.ptrBitWidth(), 8);
|
||||
const target = plan9.base.comp.root_mod.resolved_target.result;
|
||||
const ptr_bytes = @divExact(target.ptrBitWidth(), 8);
|
||||
const got_addr = plan9.bases.data;
|
||||
const got_index = self.got_index.?;
|
||||
return got_addr + got_index * ptr_bytes;
|
||||
@@ -293,9 +294,11 @@ pub fn defaultBaseAddrs(arch: std.Target.Cpu.Arch) Bases {
|
||||
};
|
||||
}
|
||||
|
||||
pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {
|
||||
if (options.use_llvm)
|
||||
return error.LLVMBackendDoesNotSupportPlan9;
|
||||
pub fn createEmpty(arena: Allocator, options: link.File.OpenOptions) !*Plan9 {
|
||||
_ = arena;
|
||||
const target = options.comp.root_mod.resolved_target.result;
|
||||
const gpa = options.comp.gpa;
|
||||
|
||||
const sixtyfour_bit: bool = switch (options.target.ptrBitWidth()) {
|
||||
0...32 => false,
|
||||
33...64 => true,
|
||||
@@ -315,7 +318,7 @@ pub fn createEmpty(gpa: Allocator, options: link.Options) !*Plan9 {
|
||||
},
|
||||
.sixtyfour_bit = sixtyfour_bit,
|
||||
.bases = undefined,
|
||||
.magic = try aout.magicFromArch(self.base.options.target.cpu.arch),
|
||||
.magic = try aout.magicFromArch(target.cpu.arch),
|
||||
};
|
||||
// a / will always be in a file path
|
||||
try self.file_segments.put(gpa, "/", 1);
|
||||
@@ -399,6 +402,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
|
||||
}
|
||||
|
||||
const gpa = self.base.comp.gpa;
|
||||
const target = self.base.comp.root_mod.resolved_target.result;
|
||||
const func = mod.funcInfo(func_index);
|
||||
const decl_index = func.owner_decl;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
@@ -414,7 +418,7 @@ pub fn updateFunc(self: *Plan9, mod: *Module, func_index: InternPool.Index, air:
|
||||
.end_line = undefined,
|
||||
.pcop_change_index = null,
|
||||
// we have already checked the target in the linker to make sure it is compatable
|
||||
.pc_quanta = aout.getPCQuant(self.base.options.target.cpu.arch) catch unreachable,
|
||||
.pc_quanta = aout.getPCQuant(target.cpu.arch) catch unreachable,
|
||||
};
|
||||
defer dbg_info_output.dbg_line.deinit();
|
||||
|
||||
@@ -658,6 +662,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
}
|
||||
|
||||
const gpa = comp.gpa;
|
||||
const target = comp.root_mod.resolved_target.result;
|
||||
|
||||
const tracy = trace(@src());
|
||||
defer tracy.end();
|
||||
@@ -749,9 +754,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
atom.offset = off;
|
||||
log.debug("write text decl {*} ({}), lines {d} to {d}.;__GOT+0x{x} vaddr: 0x{x}", .{ decl, decl.name.fmt(&mod.intern_pool), out.start_line + 1, out.end_line, atom.got_index.? * 8, off });
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[atom.sym_index.?].value = off;
|
||||
if (mod.decl_exports.get(decl_index)) |exports| {
|
||||
@@ -778,9 +783,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
text_i += code.len;
|
||||
text_atom.offset = off;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[text_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[text_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[text_atom.sym_index.?].value = off;
|
||||
}
|
||||
@@ -791,9 +796,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
const val = self.getAddr(text_i, .t);
|
||||
self.syms.items[etext_atom.sym_index.?].value = val;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[etext_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[etext_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
|
||||
}
|
||||
}
|
||||
// global offset table is in data
|
||||
@@ -815,9 +820,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
data_i += code.len;
|
||||
atom.offset = off;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[atom.sym_index.?].value = off;
|
||||
if (mod.decl_exports.get(decl_index)) |exports| {
|
||||
@@ -838,9 +843,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
data_i += code.len;
|
||||
atom.offset = off;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[atom.sym_index.?].value = off;
|
||||
}
|
||||
@@ -859,9 +864,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
data_i += code.len;
|
||||
atom.offset = off;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[atom.sym_index.?].value = off;
|
||||
}
|
||||
@@ -879,9 +884,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
data_i += code.len;
|
||||
data_atom.offset = off;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[data_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(off)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[data_atom.got_index.? * 8 ..][0..8], off, target.cpu.arch.endian());
|
||||
}
|
||||
self.syms.items[data_atom.sym_index.?].value = off;
|
||||
}
|
||||
@@ -891,9 +896,9 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
const val = self.getAddr(data_i, .b);
|
||||
self.syms.items[edata_atom.sym_index.?].value = val;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[edata_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
|
||||
} else {
|
||||
mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[edata_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
|
||||
}
|
||||
}
|
||||
// end symbol (same as edata because native backends don't do .bss yet)
|
||||
@@ -902,10 +907,10 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
const val = self.getAddr(data_i, .b);
|
||||
self.syms.items[end_atom.sym_index.?].value = val;
|
||||
if (!self.sixtyfour_bit) {
|
||||
mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u32, got_table[end_atom.got_index.? * 4 ..][0..4], @as(u32, @intCast(val)), target.cpu.arch.endian());
|
||||
} else {
|
||||
log.debug("write end (got_table[0x{x}] = 0x{x})", .{ end_atom.got_index.? * 8, val });
|
||||
mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, self.base.options.target.cpu.arch.endian());
|
||||
mem.writeInt(u64, got_table[end_atom.got_index.? * 8 ..][0..8], val, target.cpu.arch.endian());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -942,7 +947,7 @@ pub fn flushModule(self: *Plan9, comp: *Compilation, prog_node: *std.Progress.No
|
||||
const source_atom = self.getAtom(source_atom_index);
|
||||
const source_atom_symbol = self.syms.items[source_atom.sym_index.?];
|
||||
const code = source_atom.code.getCode(self);
|
||||
const endian = self.base.options.target.cpu.arch.endian();
|
||||
const endian = target.cpu.arch.endian();
|
||||
for (kv.value_ptr.items) |reloc| {
|
||||
const offset = reloc.offset;
|
||||
const addend = reloc.addend;
|
||||
|
||||
@@ -1119,7 +1119,8 @@ fn validateFeatures(
|
||||
to_emit: *[@typeInfo(types.Feature.Tag).Enum.fields.len]bool,
|
||||
emit_features_count: *u32,
|
||||
) !void {
|
||||
const cpu_features = wasm.base.options.target.cpu.features;
|
||||
const target = wasm.base.comp.root_mod.resolved_target.result;
|
||||
const cpu_features = target.cpu.features;
|
||||
const infer = cpu_features.isEmpty(); // when the user did not define any features, we infer them from linked objects.
|
||||
const known_features_count = @typeInfo(types.Feature.Tag).Enum.fields.len;
|
||||
|
||||
@@ -1752,6 +1753,7 @@ pub fn getDeclVAddr(
|
||||
decl_index: InternPool.DeclIndex,
|
||||
reloc_info: link.File.RelocInfo,
|
||||
) !u64 {
|
||||
const target = wasm.base.comp.root_mod.resolved_target.result;
|
||||
const gpa = wasm.base.comp.gpa;
|
||||
const mod = wasm.base.comp.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
@@ -1762,7 +1764,7 @@ pub fn getDeclVAddr(
|
||||
assert(reloc_info.parent_atom_index != 0);
|
||||
const atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
|
||||
const atom = wasm.getAtomPtr(atom_index);
|
||||
const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
if (decl.ty.zigTypeTag(mod) == .Fn) {
|
||||
assert(reloc_info.addend == 0); // addend not allowed for function relocations
|
||||
// We found a function pointer, so add it to our table,
|
||||
@@ -1825,12 +1827,13 @@ pub fn lowerAnonDecl(
|
||||
|
||||
pub fn getAnonDeclVAddr(wasm: *Wasm, decl_val: InternPool.Index, reloc_info: link.File.RelocInfo) !u64 {
|
||||
const gpa = wasm.base.comp.gpa;
|
||||
const target = wasm.base.comp.root_mod.resolved_target.result;
|
||||
const atom_index = wasm.anon_decls.get(decl_val).?;
|
||||
const target_symbol_index = wasm.getAtom(atom_index).getSymbolIndex().?;
|
||||
|
||||
const parent_atom_index = wasm.symbol_atom.get(.{ .file = null, .index = reloc_info.parent_atom_index }).?;
|
||||
const parent_atom = wasm.getAtomPtr(parent_atom_index);
|
||||
const is_wasm32 = wasm.base.options.target.cpu.arch == .wasm32;
|
||||
const is_wasm32 = target.cpu.arch == .wasm32;
|
||||
const mod = wasm.base.comp.module.?;
|
||||
const ty = Type.fromInterned(mod.intern_pool.typeOf(decl_val));
|
||||
if (ty.zigTypeTag(mod) == .Fn) {
|
||||
@@ -4557,7 +4560,7 @@ fn linkWithLLD(wasm: *Wasm, comp: *Compilation, prog_node: *std.Progress.Node) !
|
||||
break :blk null;
|
||||
};
|
||||
|
||||
const target = wasm.base.options.target;
|
||||
const target = wasm.base.comp.root_mod.resolved_target.result;
|
||||
|
||||
const id_symlink_basename = "lld.id";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user