Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Merge pull request ziglang#18576 from ziglang/new-macho
Browse files Browse the repository at this point in the history
macho: upstream a complete rewrite of the MachO linker
  • Loading branch information
kubkon authored Jan 24, 2024
2 parents 9221113 + 0fd0b76 commit dcaf436
Show file tree
Hide file tree
Showing 116 changed files with 15,838 additions and 15,047 deletions.
11 changes: 8 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -603,20 +603,25 @@ set(ZIG_STAGE2_SOURCES
"${CMAKE_SOURCE_DIR}/src/link/MachO/DebugSymbols.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/DwarfInfo.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/Dylib.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/InternalObject.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/Object.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/Relocation.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/Trie.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/Symbol.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/UnwindInfo.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/ZigObject.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/dead_strip.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/dyld_info/bind.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/dyld_info/Rebase.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/dead_strip.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/dyld_info/Trie.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/eh_frame.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/fat.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/file.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/hasher.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/load_commands.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/relocatable.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/synthetic.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/thunks.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/uuid.zig"
"${CMAKE_SOURCE_DIR}/src/link/MachO/zld.zig"
"${CMAKE_SOURCE_DIR}/src/link/Plan9.zig"
"${CMAKE_SOURCE_DIR}/src/link/Plan9/aout.zig"
"${CMAKE_SOURCE_DIR}/src/link/Wasm.zig"
Expand Down
2 changes: 1 addition & 1 deletion build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ fn addCompilerStep(b: *std.Build, options: AddCompilerStepOptions) *std.Build.St
.root_source_file = .{ .path = "src/main.zig" },
.target = options.target,
.optimize = options.optimize,
.max_rss = 7_000_000_000,
.max_rss = 8_000_000_000,
.strip = options.strip,
.sanitize_thread = options.sanitize_thread,
.single_threaded = options.single_threaded,
Expand Down
16 changes: 16 additions & 0 deletions lib/std/macho.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,22 @@ pub const FAT_MAGIC_64 = 0xcafebabf;
/// NXSwapLong(FAT_MAGIC_64)
pub const FAT_CIGAM_64 = 0xbfbafeca;

/// Segment flags
/// The file contents for this segment is for the high part of the VM space, the low part
/// is zero filled (for stacks in core files).
pub const SG_HIGHVM = 0x1;
/// This segment is the VM that is allocated by a fixed VM library, for overlap checking in
/// the link editor.
pub const SG_FVMLIB = 0x2;
/// This segment has nothing that was relocated in it and nothing relocated to it, that is
/// it maybe safely replaced without relocation.
pub const SG_NORELOC = 0x4;
/// This segment is protected. If the segment starts at file offset 0, the
/// first page of the segment is not protected. All other pages of the segment are protected.
pub const SG_PROTECTED_VERSION_1 = 0x8;
/// This segment is made read-only after fixups
pub const SG_READ_ONLY = 0x10;

/// The flags field of a section structure is separated into two parts a section
/// type and section attributes. The section types are mutually exclusive (it
/// can only have one type) but the section attributes are not (it may have more
Expand Down
1 change: 1 addition & 0 deletions src/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1542,6 +1542,7 @@ pub fn create(gpa: Allocator, arena: Allocator, options: CreateOptions) !*Compil
.darwin_sdk_layout = libc_dirs.darwin_sdk_layout,
.frameworks = options.frameworks,
.lib_dirs = options.lib_dirs,
.framework_dirs = options.framework_dirs,
.rpath_list = options.rpath_list,
.symbol_wrap_set = options.symbol_wrap_set,
.allow_shlib_undefined = options.linker_allow_shlib_undefined,
Expand Down
80 changes: 44 additions & 36 deletions src/arch/aarch64/CodeGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4013,10 +4013,11 @@ fn store(self: *Self, ptr: MCValue, value: MCValue, ptr_ty: Type, value_ty: Type
.import => unreachable,
};
const atom_index = switch (self.bin_file.tag) {
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
.macho => {
// const macho_file = self.bin_file.cast(link.File.MachO).?;
// const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
// break :blk macho_file.getAtom(atom).getSymbolIndex().?;
@panic("TODO store");
},
.coff => blk: {
const coff_file = self.bin_file.cast(link.File.Coff).?;
Expand Down Expand Up @@ -4321,14 +4322,16 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const got_addr = @as(u32, @intCast(sym.zigGotAddress(elf_file)));
try self.genSetReg(Type.usize, .x30, .{ .memory = got_addr });
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
try self.genSetReg(Type.u64, .x30, .{
.linker_load = .{
.type = .got,
.sym_index = sym_index,
},
});
_ = macho_file;
@panic("TODO airCall");
// const atom = try macho_file.getOrCreateAtomForDecl(func.owner_decl);
// const sym_index = macho_file.getAtom(atom).getSymbolIndex().?;
// try self.genSetReg(Type.u64, .x30, .{
// .linker_load = .{
// .type = .got,
// .sym_index = sym_index,
// },
// });
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
const atom = try coff_file.getOrCreateAtomForDecl(func.owner_decl);
const sym_index = coff_file.getAtom(atom).getSymbolIndex().?;
Expand All @@ -4352,18 +4355,20 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier
const decl_name = mod.intern_pool.stringToSlice(mod.declPtr(extern_func.decl).name);
const lib_name = mod.intern_pool.stringToSliceUnwrap(extern_func.lib_name);
if (self.bin_file.cast(link.File.MachO)) |macho_file| {
const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
_ = try self.addInst(.{
.tag = .call_extern,
.data = .{
.relocation = .{
.atom_index = atom_index,
.sym_index = sym_index,
},
},
});
_ = macho_file;
@panic("TODO airCall");
// const sym_index = try macho_file.getGlobalSymbol(decl_name, lib_name);
// const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
// const atom_index = macho_file.getAtom(atom).getSymbolIndex().?;
// _ = try self.addInst(.{
// .tag = .call_extern,
// .data = .{
// .relocation = .{
// .atom_index = atom_index,
// .sym_index = sym_index,
// },
// },
// });
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
const sym_index = try coff_file.getGlobalSymbol(decl_name, lib_name);
try self.genSetReg(Type.u64, .x30, .{
Expand Down Expand Up @@ -5532,10 +5537,11 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro
.import => unreachable,
};
const atom_index = switch (self.bin_file.tag) {
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
.macho => {
// const macho_file = self.bin_file.cast(link.File.MachO).?;
// const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
// break :blk macho_file.getAtom(atom).getSymbolIndex().?;
@panic("TODO genSetStack");
},
.coff => blk: {
const coff_file = self.bin_file.cast(link.File.Coff).?;
Expand Down Expand Up @@ -5653,10 +5659,11 @@ fn genSetReg(self: *Self, ty: Type, reg: Register, mcv: MCValue) InnerError!void
.import => .load_memory_import,
};
const atom_index = switch (self.bin_file.tag) {
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
.macho => {
@panic("TODO genSetReg");
// const macho_file = self.bin_file.cast(link.File.MachO).?;
// const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
// break :blk macho_file.getAtom(atom).getSymbolIndex().?;
},
.coff => blk: {
const coff_file = self.bin_file.cast(link.File.Coff).?;
Expand Down Expand Up @@ -5850,10 +5857,11 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I
.import => unreachable,
};
const atom_index = switch (self.bin_file.tag) {
.macho => blk: {
const macho_file = self.bin_file.cast(link.File.MachO).?;
const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
break :blk macho_file.getAtom(atom).getSymbolIndex().?;
.macho => {
@panic("TODO genSetStackArgument");
// const macho_file = self.bin_file.cast(link.File.MachO).?;
// const atom = try macho_file.getOrCreateAtomForDecl(self.owner_decl);
// break :blk macho_file.getAtom(atom).getSymbolIndex().?;
},
.coff => blk: {
const coff_file = self.bin_file.cast(link.File.Coff).?;
Expand Down
80 changes: 43 additions & 37 deletions src/arch/aarch64/Emit.zig
Original file line number Diff line number Diff line change
Expand Up @@ -677,26 +677,30 @@ fn mirDebugEpilogueBegin(emit: *Emit) !void {
fn mirCallExtern(emit: *Emit, inst: Mir.Inst.Index) !void {
assert(emit.mir.instructions.items(.tag)[inst] == .call_extern);
const relocation = emit.mir.instructions.items(.data)[inst].relocation;
_ = relocation;

const offset = blk: {
const offset = @as(u32, @intCast(emit.code.items.len));
// bl
try emit.writeInstruction(Instruction.bl(0));
break :blk offset;
};
_ = offset;

if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
// Add relocation to the decl.
const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index }).?;
const target = macho_file.getGlobalByIndex(relocation.sym_index);
try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
.type = .branch,
.target = target,
.offset = offset,
.addend = 0,
.pcrel = true,
.length = 2,
});
_ = macho_file;
@panic("TODO mirCallExtern");
// // Add relocation to the decl.
// const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = relocation.atom_index }).?;
// const target = macho_file.getGlobalByIndex(relocation.sym_index);
// try link.File.MachO.Atom.addRelocation(macho_file, atom_index, .{
// .type = .branch,
// .target = target,
// .offset = offset,
// .addend = 0,
// .pcrel = true,
// .length = 2,
// });
} else if (emit.bin_file.cast(link.File.Coff)) |_| {
unreachable; // Calling imports is handled via `.load_memory_import`
} else {
Expand Down Expand Up @@ -900,32 +904,34 @@ fn mirLoadMemoryPie(emit: *Emit, inst: Mir.Inst.Index) !void {
}

if (emit.bin_file.cast(link.File.MachO)) |macho_file| {
const Atom = link.File.MachO.Atom;
const Relocation = Atom.Relocation;
const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index }).?;
try Atom.addRelocations(macho_file, atom_index, &[_]Relocation{ .{
.target = .{ .sym_index = data.sym_index },
.offset = offset,
.addend = 0,
.pcrel = true,
.length = 2,
.type = switch (tag) {
.load_memory_got, .load_memory_ptr_got => Relocation.Type.got_page,
.load_memory_direct, .load_memory_ptr_direct => Relocation.Type.page,
else => unreachable,
},
}, .{
.target = .{ .sym_index = data.sym_index },
.offset = offset + 4,
.addend = 0,
.pcrel = false,
.length = 2,
.type = switch (tag) {
.load_memory_got, .load_memory_ptr_got => Relocation.Type.got_pageoff,
.load_memory_direct, .load_memory_ptr_direct => Relocation.Type.pageoff,
else => unreachable,
},
} });
_ = macho_file;
@panic("TODO mirLoadMemoryPie");
// const Atom = link.File.MachO.Atom;
// const Relocation = Atom.Relocation;
// const atom_index = macho_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index }).?;
// try Atom.addRelocations(macho_file, atom_index, &[_]Relocation{ .{
// .target = .{ .sym_index = data.sym_index },
// .offset = offset,
// .addend = 0,
// .pcrel = true,
// .length = 2,
// .type = switch (tag) {
// .load_memory_got, .load_memory_ptr_got => Relocation.Type.got_page,
// .load_memory_direct, .load_memory_ptr_direct => Relocation.Type.page,
// else => unreachable,
// },
// }, .{
// .target = .{ .sym_index = data.sym_index },
// .offset = offset + 4,
// .addend = 0,
// .pcrel = false,
// .length = 2,
// .type = switch (tag) {
// .load_memory_got, .load_memory_ptr_got => Relocation.Type.got_pageoff,
// .load_memory_direct, .load_memory_ptr_direct => Relocation.Type.pageoff,
// else => unreachable,
// },
// } });
} else if (emit.bin_file.cast(link.File.Coff)) |coff_file| {
const atom_index = coff_file.getAtomIndexForSymbol(.{ .sym_index = data.atom_index, .file = null }).?;
const target = switch (tag) {
Expand Down
Loading

0 comments on commit dcaf436

Please sign in to comment.