| author | |
| committer | |
| log | 6d0ba6dd10b9ba9137b3ea9532789fcc5e971649 |
| tree | 866c19c472a2142c4f9eb59995635a2583b984a6 |
| parent | 03b33b0f0139129e649f57952209586db188cb79 |
8 files changed, 262 insertions(+), 31 deletions(-)
CMakeLists.txt+1| ... | @@ -608,6 +608,7 @@ set(ZIG_STAGE2_SOURCES | ... | @@ -608,6 +608,7 @@ set(ZIG_STAGE2_SOURCES |
| 608 | "${CMAKE_SOURCE_DIR}/src/link/MachO/Relocation.zig" | 608 | "${CMAKE_SOURCE_DIR}/src/link/MachO/Relocation.zig" |
| 609 | "${CMAKE_SOURCE_DIR}/src/link/MachO/Symbol.zig" | 609 | "${CMAKE_SOURCE_DIR}/src/link/MachO/Symbol.zig" |
| 610 | "${CMAKE_SOURCE_DIR}/src/link/MachO/UnwindInfo.zig" | 610 | "${CMAKE_SOURCE_DIR}/src/link/MachO/UnwindInfo.zig" |
| 611 | "${CMAKE_SOURCE_DIR}/src/link/MachO/ZigObject.zig" | ||
| 611 | "${CMAKE_SOURCE_DIR}/src/link/MachO/dead_strip.zig" | 612 | "${CMAKE_SOURCE_DIR}/src/link/MachO/dead_strip.zig" |
| 612 | "${CMAKE_SOURCE_DIR}/src/link/MachO/dyld_info/bind.zig" | 613 | "${CMAKE_SOURCE_DIR}/src/link/MachO/dyld_info/bind.zig" |
| 613 | "${CMAKE_SOURCE_DIR}/src/link/MachO/dyld_info/Rebase.zig" | 614 | "${CMAKE_SOURCE_DIR}/src/link/MachO/dyld_info/Rebase.zig" |
src/link/MachO.zig+21-7| ... | @@ -10,6 +10,7 @@ d_sym: ?DebugSymbols = null, | ... | @@ -10,6 +10,7 @@ d_sym: ?DebugSymbols = null, |
| 10 | /// Index of each input file also encodes the priority or precedence of one input file | 10 | /// Index of each input file also encodes the priority or precedence of one input file |
| 11 | /// over another. | 11 | /// over another. |
| 12 | files: std.MultiArrayList(File.Entry) = .{}, | 12 | files: std.MultiArrayList(File.Entry) = .{}, |
| 13 | zig_object: ?File.Index = null, | ||
| 13 | internal_object: ?File.Index = null, | 14 | internal_object: ?File.Index = null, |
| 14 | objects: std.ArrayListUnmanaged(File.Index) = .{}, | 15 | objects: std.ArrayListUnmanaged(File.Index) = .{}, |
| 15 | dylibs: std.ArrayListUnmanaged(File.Index) = .{}, | 16 | dylibs: std.ArrayListUnmanaged(File.Index) = .{}, |
| ... | @@ -222,12 +223,19 @@ pub fn createEmpty( | ... | @@ -222,12 +223,19 @@ pub fn createEmpty( |
| 222 | try self.symbols.append(gpa, .{}); | 223 | try self.symbols.append(gpa, .{}); |
| 223 | try self.symbols_extra.append(gpa, 0); | 224 | try self.symbols_extra.append(gpa, 0); |
| 224 | 225 | ||
| 225 | // TODO: init | ||
| 226 | |||
| 227 | if (opt_zcu) |zcu| { | 226 | if (opt_zcu) |zcu| { |
| 228 | if (!use_llvm) { | 227 | if (!use_llvm) { |
| 229 | _ = zcu; | 228 | const index: File.Index = @intCast(try self.files.addOne(gpa)); |
| 230 | // TODO: create .zig_object | 229 | self.files.set(index, .{ .zig_object = .{ |
| 230 | .index = index, | ||
| 231 | .path = try std.fmt.allocPrint(arena, "{s}.o", .{std.fs.path.stem( | ||
| 232 | zcu.main_mod.root_src_path, | ||
| 233 | )}), | ||
| 234 | } }); | ||
| 235 | self.zig_object = index; | ||
| 236 | try self.getZigObject().?.init(self); | ||
| 237 | |||
| 238 | // TODO init metadata | ||
| 231 | 239 | ||
| 232 | if (comp.config.debug_format != .strip) { | 240 | if (comp.config.debug_format != .strip) { |
| 233 | // Create dSYM bundle. | 241 | // Create dSYM bundle. |
| ... | @@ -281,6 +289,7 @@ pub fn deinit(self: *MachO) void { | ... | @@ -281,6 +289,7 @@ pub fn deinit(self: *MachO) void { |
| 281 | 289 | ||
| 282 | for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) { | 290 | for (self.files.items(.tags), self.files.items(.data)) |tag, *data| switch (tag) { |
| 283 | .null => {}, | 291 | .null => {}, |
| 292 | .zig_object => data.zig_object.deinit(gpa), | ||
| 284 | .internal => data.internal.deinit(gpa), | 293 | .internal => data.internal.deinit(gpa), |
| 285 | .object => data.object.deinit(gpa), | 294 | .object => data.object.deinit(gpa), |
| 286 | .dylib => data.dylib.deinit(gpa), | 295 | .dylib => data.dylib.deinit(gpa), |
| ... | @@ -3109,9 +3118,7 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void { | ... | @@ -3109,9 +3118,7 @@ pub fn freeDecl(self: *MachO, decl_index: InternPool.DeclIndex) void { |
| 3109 | 3118 | ||
| 3110 | pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { | 3119 | pub fn getDeclVAddr(self: *MachO, decl_index: InternPool.DeclIndex, reloc_info: link.File.RelocInfo) !u64 { |
| 3111 | assert(self.llvm_object == null); | 3120 | assert(self.llvm_object == null); |
| 3112 | _ = decl_index; | 3121 | return self.getZigObject().?.getDeclVAddr(self, decl_index, reloc_info); |
| 3113 | _ = reloc_info; | ||
| 3114 | @panic("TODO getDeclVAddr"); | ||
| 3115 | } | 3122 | } |
| 3116 | 3123 | ||
| 3117 | pub fn lowerAnonDecl( | 3124 | pub fn lowerAnonDecl( |
| ... | @@ -3297,12 +3304,18 @@ pub fn getFile(self: *MachO, index: File.Index) ?File { | ... | @@ -3297,12 +3304,18 @@ pub fn getFile(self: *MachO, index: File.Index) ?File { |
| 3297 | const tag = self.files.items(.tags)[index]; | 3304 | const tag = self.files.items(.tags)[index]; |
| 3298 | return switch (tag) { | 3305 | return switch (tag) { |
| 3299 | .null => null, | 3306 | .null => null, |
| 3307 | .zig_object => .{ .zig_object = &self.files.items(.data)[index].zig_object }, | ||
| 3300 | .internal => .{ .internal = &self.files.items(.data)[index].internal }, | 3308 | .internal => .{ .internal = &self.files.items(.data)[index].internal }, |
| 3301 | .object => .{ .object = &self.files.items(.data)[index].object }, | 3309 | .object => .{ .object = &self.files.items(.data)[index].object }, |
| 3302 | .dylib => .{ .dylib = &self.files.items(.data)[index].dylib }, | 3310 | .dylib => .{ .dylib = &self.files.items(.data)[index].dylib }, |
| 3303 | }; | 3311 | }; |
| 3304 | } | 3312 | } |
| 3305 | 3313 | ||
| 3314 | pub fn getZigObject(self: *MachO) ?*ZigObject { | ||
| 3315 | const index = self.zig_object orelse return null; | ||
| 3316 | return self.getFile(index).?.zig_object; | ||
| 3317 | } | ||
| 3318 | |||
| 3306 | pub fn getInternalObject(self: *MachO) ?*InternalObject { | 3319 | pub fn getInternalObject(self: *MachO) ?*InternalObject { |
| 3307 | const index = self.internal_object orelse return null; | 3320 | const index = self.internal_object orelse return null; |
| 3308 | return self.getFile(index).?.internal; | 3321 | return self.getFile(index).?.internal; |
| ... | @@ -4123,3 +4136,4 @@ const TlvPtrSection = synthetic.TlvPtrSection; | ... | @@ -4123,3 +4136,4 @@ const TlvPtrSection = synthetic.TlvPtrSection; |
| 4123 | const TypedValue = @import("../TypedValue.zig"); | 4136 | const TypedValue = @import("../TypedValue.zig"); |
| 4124 | const UnwindInfo = @import("MachO/UnwindInfo.zig"); | 4137 | const UnwindInfo = @import("MachO/UnwindInfo.zig"); |
| 4125 | const WeakBindSection = synthetic.WeakBindSection; | 4138 | const WeakBindSection = synthetic.WeakBindSection; |
| 4139 | const ZigObject = @import("MachO/ZigObject.zig"); |
src/link/MachO/Atom.zig+25-23| ... | @@ -45,10 +45,27 @@ pub fn getFile(self: Atom, macho_file: *MachO) File { | ... | @@ -45,10 +45,27 @@ pub fn getFile(self: Atom, macho_file: *MachO) File { |
| 45 | return macho_file.getFile(self.file).?; | 45 | return macho_file.getFile(self.file).?; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | pub fn getData(self: Atom, macho_file: *MachO) []const u8 { | ||
| 49 | return switch (self.getFile(macho_file)) { | ||
| 50 | .zig_object => @panic("TODO Atom.getData"), | ||
| 51 | .object => |x| x.getAtomData(self), | ||
| 52 | else => unreachable, | ||
| 53 | }; | ||
| 54 | } | ||
| 55 | |||
| 56 | pub fn getRelocs(self: Atom, macho_file: *MachO) []const Relocation { | ||
| 57 | return switch (self.getFile(macho_file)) { | ||
| 58 | .zig_object => @panic("TODO Atom.getRelocs"), | ||
| 59 | .object => |x| x.getAtomRelocs(self), | ||
| 60 | else => unreachable, | ||
| 61 | }; | ||
| 62 | } | ||
| 63 | |||
| 48 | pub fn getInputSection(self: Atom, macho_file: *MachO) macho.section_64 { | 64 | pub fn getInputSection(self: Atom, macho_file: *MachO) macho.section_64 { |
| 49 | return switch (self.getFile(macho_file)) { | 65 | return switch (self.getFile(macho_file)) { |
| 50 | .dylib => unreachable, | 66 | .zig_object => |x| x.getInputSection(self, macho_file), |
| 51 | inline else => |x| x.sections.items(.header)[self.n_sect], | 67 | .object => |x| x.sections.items(.header)[self.n_sect], |
| 68 | else => unreachable, | ||
| 52 | }; | 69 | }; |
| 53 | } | 70 | } |
| 54 | 71 | ||
| ... | @@ -61,26 +78,10 @@ pub fn getPriority(self: Atom, macho_file: *MachO) u64 { | ... | @@ -61,26 +78,10 @@ pub fn getPriority(self: Atom, macho_file: *MachO) u64 { |
| 61 | return (@as(u64, @intCast(file.getIndex())) << 32) | @as(u64, @intCast(self.n_sect)); | 78 | return (@as(u64, @intCast(file.getIndex())) << 32) | @as(u64, @intCast(self.n_sect)); |
| 62 | } | 79 | } |
| 63 | 80 | ||
| 64 | pub fn getCode(self: Atom, macho_file: *MachO) []const u8 { | ||
| 65 | const code = switch (self.getFile(macho_file)) { | ||
| 66 | .dylib => unreachable, | ||
| 67 | inline else => |x| x.getSectionData(self.n_sect), | ||
| 68 | }; | ||
| 69 | return code[self.off..][0..self.size]; | ||
| 70 | } | ||
| 71 | |||
| 72 | pub fn getRelocs(self: Atom, macho_file: *MachO) []const Relocation { | ||
| 73 | const relocs = switch (self.getFile(macho_file)) { | ||
| 74 | .dylib => unreachable, | ||
| 75 | inline else => |x| x.sections.items(.relocs)[self.n_sect], | ||
| 76 | }; | ||
| 77 | return relocs.items[self.relocs.pos..][0..self.relocs.len]; | ||
| 78 | } | ||
| 79 | |||
| 80 | pub fn getUnwindRecords(self: Atom, macho_file: *MachO) []const UnwindInfo.Record.Index { | 81 | pub fn getUnwindRecords(self: Atom, macho_file: *MachO) []const UnwindInfo.Record.Index { |
| 81 | return switch (self.getFile(macho_file)) { | 82 | return switch (self.getFile(macho_file)) { |
| 82 | .dylib => unreachable, | 83 | .dylib => unreachable, |
| 83 | .internal => &[0]UnwindInfo.Record.Index{}, | 84 | .zig_object, .internal => &[0]UnwindInfo.Record.Index{}, |
| 84 | .object => |x| x.unwind_records.items[self.unwind_records.pos..][0..self.unwind_records.len], | 85 | .object => |x| x.unwind_records.items[self.unwind_records.pos..][0..self.unwind_records.len], |
| 85 | }; | 86 | }; |
| 86 | } | 87 | } |
| ... | @@ -290,10 +291,10 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void { | ... | @@ -290,10 +291,10 @@ pub fn resolveRelocs(self: Atom, macho_file: *MachO, buffer: []u8) !void { |
| 290 | defer tracy.end(); | 291 | defer tracy.end(); |
| 291 | 292 | ||
| 292 | assert(!self.getInputSection(macho_file).isZerofill()); | 293 | assert(!self.getInputSection(macho_file).isZerofill()); |
| 293 | const relocs = self.getRelocs(macho_file); | ||
| 294 | const file = self.getFile(macho_file); | 294 | const file = self.getFile(macho_file); |
| 295 | const name = self.getName(macho_file); | 295 | const name = self.getName(macho_file); |
| 296 | @memcpy(buffer, self.getCode(macho_file)); | 296 | const relocs = self.getRelocs(macho_file); |
| 297 | @memcpy(buffer, self.getData(macho_file)); | ||
| 297 | 298 | ||
| 298 | relocs_log.debug("{x}: {s}", .{ self.value, name }); | 299 | relocs_log.debug("{x}: {s}", .{ self.value, name }); |
| 299 | 300 | ||
| ... | @@ -683,10 +684,11 @@ const x86_64 = struct { | ... | @@ -683,10 +684,11 @@ const x86_64 = struct { |
| 683 | }; | 684 | }; |
| 684 | 685 | ||
| 685 | pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 { | 686 | pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 { |
| 687 | const relocs = self.getRelocs(macho_file); | ||
| 686 | switch (macho_file.getTarget().cpu.arch) { | 688 | switch (macho_file.getTarget().cpu.arch) { |
| 687 | .aarch64 => { | 689 | .aarch64 => { |
| 688 | var nreloc: u32 = 0; | 690 | var nreloc: u32 = 0; |
| 689 | for (self.getRelocs(macho_file)) |rel| { | 691 | for (relocs) |rel| { |
| 690 | nreloc += 1; | 692 | nreloc += 1; |
| 691 | switch (rel.type) { | 693 | switch (rel.type) { |
| 692 | .page, .pageoff => if (rel.addend > 0) { | 694 | .page, .pageoff => if (rel.addend > 0) { |
| ... | @@ -697,7 +699,7 @@ pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 { | ... | @@ -697,7 +699,7 @@ pub fn calcNumRelocs(self: Atom, macho_file: *MachO) u32 { |
| 697 | } | 699 | } |
| 698 | return nreloc; | 700 | return nreloc; |
| 699 | }, | 701 | }, |
| 700 | .x86_64 => return @intCast(self.getRelocs(macho_file).len), | 702 | .x86_64 => return @intCast(relocs.len), |
| 701 | else => unreachable, | 703 | else => unreachable, |
| 702 | } | 704 | } |
| 703 | } | 705 | } |
src/link/MachO/Object.zig+10| ... | @@ -1547,6 +1547,16 @@ pub fn getSectionData(self: *const Object, index: u32) []const u8 { | ... | @@ -1547,6 +1547,16 @@ pub fn getSectionData(self: *const Object, index: u32) []const u8 { |
| 1547 | return self.data[sect.offset..][0..sect.size]; | 1547 | return self.data[sect.offset..][0..sect.size]; |
| 1548 | } | 1548 | } |
| 1549 | 1549 | ||
| 1550 | pub fn getAtomData(self: *const Object, atom: Atom) []const u8 { | ||
| 1551 | const data = self.getSectionData(atom.n_sect); | ||
| 1552 | return data[atom.off..][0..atom.size]; | ||
| 1553 | } | ||
| 1554 | |||
| 1555 | pub fn getAtomRelocs(self: *const Object, atom: Atom) []const Relocation { | ||
| 1556 | const relocs = self.sections.items(.relocs)[atom.n_sect]; | ||
| 1557 | return relocs.items[atom.relocs.pos..][0..atom.relocs.len]; | ||
| 1558 | } | ||
| 1559 | |||
| 1550 | fn getString(self: Object, off: u32) [:0]const u8 { | 1560 | fn getString(self: Object, off: u32) [:0]const u8 { |
| 1551 | assert(off < self.strtab.len); | 1561 | assert(off < self.strtab.len); |
| 1552 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.ptr + off)), 0); | 1562 | return mem.sliceTo(@as([*:0]const u8, @ptrCast(self.strtab.ptr + off)), 0); |
src/link/MachO/Symbol.zig+1| ... | @@ -306,6 +306,7 @@ fn format2( | ... | @@ -306,6 +306,7 @@ fn format2( |
| 306 | if (symbol.flags.weak) try writer.writeAll(" : weak"); | 306 | if (symbol.flags.weak) try writer.writeAll(" : weak"); |
| 307 | if (symbol.isSymbolStab(ctx.macho_file)) try writer.writeAll(" : stab"); | 307 | if (symbol.isSymbolStab(ctx.macho_file)) try writer.writeAll(" : stab"); |
| 308 | switch (file) { | 308 | switch (file) { |
| 309 | .zig_object => |x| try writer.print(" : zig_object({d})", .{x.index}), | ||
| 309 | .internal => |x| try writer.print(" : internal({d})", .{x.index}), | 310 | .internal => |x| try writer.print(" : internal({d})", .{x.index}), |
| 310 | .object => |x| try writer.print(" : object({d})", .{x.index}), | 311 | .object => |x| try writer.print(" : object({d})", .{x.index}), |
| 311 | .dylib => |x| try writer.print(" : dylib({d})", .{x.index}), | 312 | .dylib => |x| try writer.print(" : dylib({d})", .{x.index}), |
src/link/MachO/ZigObject.zig created+199| ... | @@ -0,0 +1,199 @@ | ||
| 1 | /// Externally owned memory. | ||
| 2 | path: []const u8, | ||
| 3 | index: File.Index, | ||
| 4 | |||
| 5 | symtab: std.MultiArrayList(Nlist) = .{}, | ||
| 6 | |||
| 7 | symbols: std.ArrayListUnmanaged(Symbol.Index) = .{}, | ||
| 8 | atoms: std.ArrayListUnmanaged(Atom.Index) = .{}, | ||
| 9 | |||
| 10 | output_symtab_ctx: MachO.SymtabCtx = .{}, | ||
| 11 | |||
| 12 | pub fn init(self: *ZigObject, macho_file: *MachO) !void { | ||
| 13 | const comp = macho_file.base.comp; | ||
| 14 | const gpa = comp.gpa; | ||
| 15 | |||
| 16 | try self.atoms.append(gpa, 0); // null input section | ||
| 17 | } | ||
| 18 | |||
| 19 | pub fn deinit(self: *ZigObject, allocator: Allocator) void { | ||
| 20 | self.symtab.deinit(allocator); | ||
| 21 | self.symbols.deinit(allocator); | ||
| 22 | self.atoms.deinit(allocator); | ||
| 23 | } | ||
| 24 | |||
| 25 | fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index { | ||
| 26 | try self.symtab.ensureUnusedCapacity(allocator, 1); | ||
| 27 | const index = @as(Symbol.Index, @intCast(self.symtab.addOneAssumeCapacity())); | ||
| 28 | self.symtab.set(index, .{ | ||
| 29 | .nlist = MachO.null_sym, | ||
| 30 | .size = 0, | ||
| 31 | .atom = 0, | ||
| 32 | }); | ||
| 33 | return index; | ||
| 34 | } | ||
| 35 | |||
| 36 | pub fn getDeclVAddr( | ||
| 37 | self: *ZigObject, | ||
| 38 | macho_file: *MachO, | ||
| 39 | decl_index: InternPool.DeclIndex, | ||
| 40 | reloc_info: link.File.RelocInfo, | ||
| 41 | ) !u64 { | ||
| 42 | _ = self; | ||
| 43 | _ = macho_file; | ||
| 44 | _ = decl_index; | ||
| 45 | _ = reloc_info; | ||
| 46 | @panic("TODO getDeclVAddr"); | ||
| 47 | } | ||
| 48 | |||
| 49 | pub fn resolveSymbols(self: *ZigObject, macho_file: *MachO) void { | ||
| 50 | _ = self; | ||
| 51 | _ = macho_file; | ||
| 52 | @panic("TODO resolveSymbols"); | ||
| 53 | } | ||
| 54 | |||
| 55 | pub fn resetGlobals(self: *ZigObject, macho_file: *MachO) void { | ||
| 56 | for (self.symbols.items, 0..) |sym_index, nlist_idx| { | ||
| 57 | if (!self.symtab.items(.nlist)[nlist_idx].ext()) continue; | ||
| 58 | const sym = macho_file.getSymbol(sym_index); | ||
| 59 | const name = sym.name; | ||
| 60 | sym.* = .{}; | ||
| 61 | sym.name = name; | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | pub fn calcSymtabSize(self: *ZigObject, macho_file: *MachO) !void { | ||
| 66 | const tracy = trace(@src()); | ||
| 67 | defer tracy.end(); | ||
| 68 | |||
| 69 | for (self.symbols.items) |sym_index| { | ||
| 70 | const sym = macho_file.getSymbol(sym_index); | ||
| 71 | const file = sym.getFile(macho_file) orelse continue; | ||
| 72 | if (file.getIndex() != self.index) continue; | ||
| 73 | if (sym.getAtom(macho_file)) |atom| if (!atom.flags.alive) continue; | ||
| 74 | sym.flags.output_symtab = true; | ||
| 75 | if (sym.isLocal()) { | ||
| 76 | try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nlocals }, macho_file); | ||
| 77 | self.output_symtab_ctx.nlocals += 1; | ||
| 78 | } else if (sym.flags.@"export") { | ||
| 79 | try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nexports }, macho_file); | ||
| 80 | self.output_symtab_ctx.nexports += 1; | ||
| 81 | } else { | ||
| 82 | assert(sym.flags.import); | ||
| 83 | try sym.addExtra(.{ .symtab = self.output_symtab_ctx.nimports }, macho_file); | ||
| 84 | self.output_symtab_ctx.nimports += 1; | ||
| 85 | } | ||
| 86 | self.output_symtab_ctx.strsize += @as(u32, @intCast(sym.getName(macho_file).len + 1)); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | pub fn writeSymtab(self: ZigObject, macho_file: *MachO) void { | ||
| 91 | const tracy = trace(@src()); | ||
| 92 | defer tracy.end(); | ||
| 93 | |||
| 94 | for (self.symbols.items) |sym_index| { | ||
| 95 | const sym = macho_file.getSymbol(sym_index); | ||
| 96 | const file = sym.getFile(macho_file) orelse continue; | ||
| 97 | if (file.getIndex() != self.index) continue; | ||
| 98 | const idx = sym.getOutputSymtabIndex(macho_file) orelse continue; | ||
| 99 | const n_strx = @as(u32, @intCast(macho_file.strtab.items.len)); | ||
| 100 | macho_file.strtab.appendSliceAssumeCapacity(sym.getName(macho_file)); | ||
| 101 | macho_file.strtab.appendAssumeCapacity(0); | ||
| 102 | const out_sym = &macho_file.symtab.items[idx]; | ||
| 103 | out_sym.n_strx = n_strx; | ||
| 104 | sym.setOutputSym(macho_file, out_sym); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | pub fn getInputSection(self: ZigObject, atom: Atom, macho_file: *MachO) macho.section_64 { | ||
| 109 | _ = self; | ||
| 110 | var sect = macho_file.sections.items(.header)[atom.out_n_sect]; | ||
| 111 | sect.addr = 0; | ||
| 112 | sect.offset = 0; | ||
| 113 | sect.size = atom.size; | ||
| 114 | sect.@"align" = atom.alignment.toLog2Units(); | ||
| 115 | return sect; | ||
| 116 | } | ||
| 117 | |||
| 118 | pub fn fmtSymtab(self: *ZigObject, macho_file: *MachO) std.fmt.Formatter(formatSymtab) { | ||
| 119 | return .{ .data = .{ | ||
| 120 | .self = self, | ||
| 121 | .macho_file = macho_file, | ||
| 122 | } }; | ||
| 123 | } | ||
| 124 | |||
| 125 | const FormatContext = struct { | ||
| 126 | self: *ZigObject, | ||
| 127 | macho_file: *MachO, | ||
| 128 | }; | ||
| 129 | |||
| 130 | fn formatSymtab( | ||
| 131 | ctx: FormatContext, | ||
| 132 | comptime unused_fmt_string: []const u8, | ||
| 133 | options: std.fmt.FormatOptions, | ||
| 134 | writer: anytype, | ||
| 135 | ) !void { | ||
| 136 | _ = unused_fmt_string; | ||
| 137 | _ = options; | ||
| 138 | try writer.writeAll(" symbols\n"); | ||
| 139 | for (ctx.self.symbols.items) |index| { | ||
| 140 | const sym = ctx.macho_file.getSymbol(index); | ||
| 141 | try writer.print(" {}\n", .{sym.fmt(ctx.macho_file)}); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | pub fn fmtAtoms(self: *ZigObject, macho_file: *MachO) std.fmt.Formatter(formatAtoms) { | ||
| 146 | return .{ .data = .{ | ||
| 147 | .self = self, | ||
| 148 | .macho_file = macho_file, | ||
| 149 | } }; | ||
| 150 | } | ||
| 151 | |||
| 152 | fn formatAtoms( | ||
| 153 | ctx: FormatContext, | ||
| 154 | comptime unused_fmt_string: []const u8, | ||
| 155 | options: std.fmt.FormatOptions, | ||
| 156 | writer: anytype, | ||
| 157 | ) !void { | ||
| 158 | _ = unused_fmt_string; | ||
| 159 | _ = options; | ||
| 160 | try writer.writeAll(" atoms\n"); | ||
| 161 | for (ctx.self.atoms.items) |atom_index| { | ||
| 162 | const atom = ctx.macho_file.getAtom(atom_index) orelse continue; | ||
| 163 | try writer.print(" {}\n", .{atom.fmt(ctx.macho_file)}); | ||
| 164 | } | ||
| 165 | } | ||
| 166 | |||
| 167 | const Nlist = struct { | ||
| 168 | nlist: macho.nlist_64, | ||
| 169 | size: u64, | ||
| 170 | atom: Atom.Index, | ||
| 171 | }; | ||
| 172 | |||
| 173 | const assert = std.debug.assert; | ||
| 174 | const builtin = @import("builtin"); | ||
| 175 | const codegen = @import("../../codegen.zig"); | ||
| 176 | const link = @import("../../link.zig"); | ||
| 177 | const log = std.log.scoped(.link); | ||
| 178 | const macho = std.macho; | ||
| 179 | const mem = std.mem; | ||
| 180 | const trace = @import("../../tracy.zig").trace; | ||
| 181 | const std = @import("std"); | ||
| 182 | |||
| 183 | const Air = @import("../../Air.zig"); | ||
| 184 | const Allocator = std.mem.Allocator; | ||
| 185 | const Archive = @import("Archive.zig"); | ||
| 186 | const Atom = @import("Atom.zig"); | ||
| 187 | const Dwarf = @import("../Dwarf.zig"); | ||
| 188 | const File = @import("file.zig").File; | ||
| 189 | const InternPool = @import("../../InternPool.zig"); | ||
| 190 | const Liveness = @import("../../Liveness.zig"); | ||
| 191 | const MachO = @import("../MachO.zig"); | ||
| 192 | const Module = @import("../../Module.zig"); | ||
| 193 | const Object = @import("Object.zig"); | ||
| 194 | const Symbol = @import("Symbol.zig"); | ||
| 195 | const StringTable = @import("../StringTable.zig"); | ||
| 196 | const Type = @import("../../type.zig").Type; | ||
| 197 | const Value = @import("../../value.zig").Value; | ||
| 198 | const TypedValue = @import("../../TypedValue.zig"); | ||
| 199 | const ZigObject = @This(); | ||
src/link/MachO/file.zig+4| ... | @@ -1,4 +1,5 @@ | ... | @@ -1,4 +1,5 @@ |
| 1 | pub const File = union(enum) { | 1 | pub const File = union(enum) { |
| 2 | zig_object: *ZigObject, | ||
| 2 | internal: *InternalObject, | 3 | internal: *InternalObject, |
| 3 | object: *Object, | 4 | object: *Object, |
| 4 | dylib: *Dylib, | 5 | dylib: *Dylib, |
| ... | @@ -22,6 +23,7 @@ pub const File = union(enum) { | ... | @@ -22,6 +23,7 @@ pub const File = union(enum) { |
| 22 | _ = unused_fmt_string; | 23 | _ = unused_fmt_string; |
| 23 | _ = options; | 24 | _ = options; |
| 24 | switch (file) { | 25 | switch (file) { |
| 26 | .zig_object => |x| try writer.writeAll(x.path), | ||
| 25 | .internal => try writer.writeAll(""), | 27 | .internal => try writer.writeAll(""), |
| 26 | .object => |x| try writer.print("{}", .{x.fmtPath()}), | 28 | .object => |x| try writer.print("{}", .{x.fmtPath()}), |
| 27 | .dylib => |x| try writer.writeAll(x.path), | 29 | .dylib => |x| try writer.writeAll(x.path), |
| ... | @@ -98,6 +100,7 @@ pub const File = union(enum) { | ... | @@ -98,6 +100,7 @@ pub const File = union(enum) { |
| 98 | 100 | ||
| 99 | pub const Entry = union(enum) { | 101 | pub const Entry = union(enum) { |
| 100 | null: void, | 102 | null: void, |
| 103 | zig_object: ZigObject, | ||
| 101 | internal: InternalObject, | 104 | internal: InternalObject, |
| 102 | object: Object, | 105 | object: Object, |
| 103 | dylib: Dylib, | 106 | dylib: Dylib, |
| ... | @@ -114,3 +117,4 @@ const MachO = @import("../MachO.zig"); | ... | @@ -114,3 +117,4 @@ const MachO = @import("../MachO.zig"); |
| 114 | const Object = @import("Object.zig"); | 117 | const Object = @import("Object.zig"); |
| 115 | const Dylib = @import("Dylib.zig"); | 118 | const Dylib = @import("Dylib.zig"); |
| 116 | const Symbol = @import("Symbol.zig"); | 119 | const Symbol = @import("Symbol.zig"); |
| 120 | const ZigObject = @import("ZigObject.zig"); |
src/link/MachO/relocatable.zig+1-1| ... | @@ -274,7 +274,7 @@ fn writeAtoms(macho_file: *MachO) !void { | ... | @@ -274,7 +274,7 @@ fn writeAtoms(macho_file: *MachO) !void { |
| 274 | const atom = macho_file.getAtom(atom_index).?; | 274 | const atom = macho_file.getAtom(atom_index).?; |
| 275 | assert(atom.flags.alive); | 275 | assert(atom.flags.alive); |
| 276 | const off = atom.value - header.addr; | 276 | const off = atom.value - header.addr; |
| 277 | @memcpy(code[off..][0..atom.size], atom.getCode(macho_file)); | 277 | @memcpy(code[off..][0..atom.size], atom.getData(macho_file)); |
| 278 | try atom.writeRelocs(macho_file, code[off..][0..atom.size], &relocs); | 278 | try atom.writeRelocs(macho_file, code[off..][0..atom.size], &relocs); |
| 279 | } | 279 | } |
| 280 | 280 |