| ... | @@ -290,7 +290,7 @@ pub const Zld = struct { | ... | @@ -290,7 +290,7 @@ pub const Zld = struct { |
| 290 | for (self.globals.items) |global| { | 290 | for (self.globals.items) |global| { |
| 291 | const sym = self.getSymbolPtr(global); | 291 | const sym = self.getSymbolPtr(global); |
| 292 | if (!sym.tentative()) continue; | 292 | if (!sym.tentative()) continue; |
| 293 | if (sym.n_desc == N_DEAD) continue; | 293 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 294 | | 294 | |
| 295 | log.debug("creating tentative definition for ATOM(%{d}, '{s}') in object({?})", .{ | 295 | log.debug("creating tentative definition for ATOM(%{d}, '{s}') in object({?})", .{ |
| 296 | global.sym_index, self.getSymbolName(global), global.file, | 296 | global.sym_index, self.getSymbolName(global), global.file, |
| ... | @@ -688,7 +688,7 @@ pub const Zld = struct { | ... | @@ -688,7 +688,7 @@ pub const Zld = struct { |
| 688 | | 688 | |
| 689 | // __TEXT segment is non-optional | 689 | // __TEXT segment is non-optional |
| 690 | { | 690 | { |
| 691 | const protection = getSegmentMemoryProtection("__TEXT"); | 691 | const protection = MachO.getSegmentMemoryProtection("__TEXT"); |
| 692 | try self.segments.append(self.gpa, .{ | 692 | try self.segments.append(self.gpa, .{ |
| 693 | .cmdsize = @sizeOf(macho.segment_command_64), | 693 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 694 | .segname = makeStaticString("__TEXT"), | 694 | .segname = makeStaticString("__TEXT"), |
| ... | @@ -704,7 +704,7 @@ pub const Zld = struct { | ... | @@ -704,7 +704,7 @@ pub const Zld = struct { |
| 704 | const segment_id = self.getSegmentByName(segname) orelse blk: { | 704 | const segment_id = self.getSegmentByName(segname) orelse blk: { |
| 705 | log.debug("creating segment '{s}'", .{segname}); | 705 | log.debug("creating segment '{s}'", .{segname}); |
| 706 | const segment_id = @as(u8, @intCast(self.segments.items.len)); | 706 | const segment_id = @as(u8, @intCast(self.segments.items.len)); |
| 707 | const protection = getSegmentMemoryProtection(segname); | 707 | const protection = MachO.getSegmentMemoryProtection(segname); |
| 708 | try self.segments.append(self.gpa, .{ | 708 | try self.segments.append(self.gpa, .{ |
| 709 | .cmdsize = @sizeOf(macho.segment_command_64), | 709 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 710 | .segname = makeStaticString(segname), | 710 | .segname = makeStaticString(segname), |
| ... | @@ -721,7 +721,7 @@ pub const Zld = struct { | ... | @@ -721,7 +721,7 @@ pub const Zld = struct { |
| 721 | | 721 | |
| 722 | // __LINKEDIT always comes last | 722 | // __LINKEDIT always comes last |
| 723 | { | 723 | { |
| 724 | const protection = getSegmentMemoryProtection("__LINKEDIT"); | 724 | const protection = MachO.getSegmentMemoryProtection("__LINKEDIT"); |
| 725 | try self.segments.append(self.gpa, .{ | 725 | try self.segments.append(self.gpa, .{ |
| 726 | .cmdsize = @sizeOf(macho.segment_command_64), | 726 | .cmdsize = @sizeOf(macho.segment_command_64), |
| 727 | .segname = makeStaticString("__LINKEDIT"), | 727 | .segname = makeStaticString("__LINKEDIT"), |
| ... | @@ -1009,7 +1009,7 @@ pub const Zld = struct { | ... | @@ -1009,7 +1009,7 @@ pub const Zld = struct { |
| 1009 | pub fn lessThan(zld: *Zld, lhs: @This(), rhs: @This()) bool { | 1009 | pub fn lessThan(zld: *Zld, lhs: @This(), rhs: @This()) bool { |
| 1010 | const lhs_header = zld.sections.items(.header)[lhs.index]; | 1010 | const lhs_header = zld.sections.items(.header)[lhs.index]; |
| 1011 | const rhs_header = zld.sections.items(.header)[rhs.index]; | 1011 | const rhs_header = zld.sections.items(.header)[rhs.index]; |
| 1012 | return getSectionPrecedence(lhs_header) < getSectionPrecedence(rhs_header); | 1012 | return MachO.getSectionPrecedence(lhs_header) < MachO.getSectionPrecedence(rhs_header); |
| 1013 | } | 1013 | } |
| 1014 | }; | 1014 | }; |
| 1015 | | 1015 | |
| ... | @@ -1317,49 +1317,6 @@ pub const Zld = struct { | ... | @@ -1317,49 +1317,6 @@ pub const Zld = struct { |
| 1317 | return index; | 1317 | return index; |
| 1318 | } | 1318 | } |
| 1319 | | 1319 | |
| 1320 | fn getSegmentPrecedence(segname: []const u8) u4 { | | |
| 1321 | if (mem.eql(u8, segname, "__PAGEZERO")) return 0x0; | | |
| 1322 | if (mem.eql(u8, segname, "__TEXT")) return 0x1; | | |
| 1323 | if (mem.eql(u8, segname, "__DATA_CONST")) return 0x2; | | |
| 1324 | if (mem.eql(u8, segname, "__DATA")) return 0x3; | | |
| 1325 | if (mem.eql(u8, segname, "__LINKEDIT")) return 0x5; | | |
| 1326 | return 0x4; | | |
| 1327 | } | | |
| 1328 | | | |
| 1329 | fn getSegmentMemoryProtection(segname: []const u8) macho.vm_prot_t { | | |
| 1330 | if (mem.eql(u8, segname, "__PAGEZERO")) return macho.PROT.NONE; | | |
| 1331 | if (mem.eql(u8, segname, "__TEXT")) return macho.PROT.READ | macho.PROT.EXEC; | | |
| 1332 | if (mem.eql(u8, segname, "__LINKEDIT")) return macho.PROT.READ; | | |
| 1333 | return macho.PROT.READ | macho.PROT.WRITE; | | |
| 1334 | } | | |
| 1335 | | | |
| 1336 | fn getSectionPrecedence(header: macho.section_64) u8 { | | |
| 1337 | const segment_precedence: u4 = getSegmentPrecedence(header.segName()); | | |
| 1338 | const section_precedence: u4 = blk: { | | |
| 1339 | if (header.isCode()) { | | |
| 1340 | if (mem.eql(u8, "__text", header.sectName())) break :blk 0x0; | | |
| 1341 | if (header.type() == macho.S_SYMBOL_STUBS) break :blk 0x1; | | |
| 1342 | break :blk 0x2; | | |
| 1343 | } | | |
| 1344 | switch (header.type()) { | | |
| 1345 | macho.S_NON_LAZY_SYMBOL_POINTERS, | | |
| 1346 | macho.S_LAZY_SYMBOL_POINTERS, | | |
| 1347 | => break :blk 0x0, | | |
| 1348 | macho.S_MOD_INIT_FUNC_POINTERS => break :blk 0x1, | | |
| 1349 | macho.S_MOD_TERM_FUNC_POINTERS => break :blk 0x2, | | |
| 1350 | macho.S_ZEROFILL => break :blk 0xf, | | |
| 1351 | macho.S_THREAD_LOCAL_REGULAR => break :blk 0xd, | | |
| 1352 | macho.S_THREAD_LOCAL_ZEROFILL => break :blk 0xe, | | |
| 1353 | else => { | | |
| 1354 | if (mem.eql(u8, "__unwind_info", header.sectName())) break :blk 0xe; | | |
| 1355 | if (mem.eql(u8, "__eh_frame", header.sectName())) break :blk 0xf; | | |
| 1356 | break :blk 0x3; | | |
| 1357 | }, | | |
| 1358 | } | | |
| 1359 | }; | | |
| 1360 | return (@as(u8, @intCast(segment_precedence)) << 4) + section_precedence; | | |
| 1361 | } | | |
| 1362 | | | |
| 1363 | fn writeSegmentHeaders(self: *Zld, writer: anytype) !void { | 1320 | fn writeSegmentHeaders(self: *Zld, writer: anytype) !void { |
| 1364 | for (self.segments.items, 0..) |seg, i| { | 1321 | for (self.segments.items, 0..) |seg, i| { |
| 1365 | const indexes = self.getSectionIndexes(@as(u8, @intCast(i))); | 1322 | const indexes = self.getSectionIndexes(@as(u8, @intCast(i))); |
| ... | @@ -1626,7 +1583,7 @@ pub const Zld = struct { | ... | @@ -1626,7 +1583,7 @@ pub const Zld = struct { |
| 1626 | for (self.globals.items) |global| { | 1583 | for (self.globals.items) |global| { |
| 1627 | const sym = self.getSymbol(global); | 1584 | const sym = self.getSymbol(global); |
| 1628 | if (sym.undf()) continue; | 1585 | if (sym.undf()) continue; |
| 1629 | if (sym.n_desc == N_DEAD) continue; | 1586 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 1630 | | 1587 | |
| 1631 | const sym_name = self.getSymbolName(global); | 1588 | const sym_name = self.getSymbolName(global); |
| 1632 | log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); | 1589 | log.debug(" (putting '{s}' defined at 0x{x})", .{ sym_name, sym.n_value }); |
| ... | @@ -1736,7 +1693,7 @@ pub const Zld = struct { | ... | @@ -1736,7 +1693,7 @@ pub const Zld = struct { |
| 1736 | fn addSymbolToFunctionStarts(self: *Zld, sym_loc: SymbolWithLoc, addresses: *std.ArrayList(u64)) !void { | 1693 | fn addSymbolToFunctionStarts(self: *Zld, sym_loc: SymbolWithLoc, addresses: *std.ArrayList(u64)) !void { |
| 1737 | const sym = self.getSymbol(sym_loc); | 1694 | const sym = self.getSymbol(sym_loc); |
| 1738 | if (sym.n_strx == 0) return; | 1695 | if (sym.n_strx == 0) return; |
| 1739 | if (sym.n_desc == N_DEAD) return; | 1696 | if (sym.n_desc == MachO.N_DEAD) return; |
| 1740 | if (self.symbolIsTemp(sym_loc)) return; | 1697 | if (self.symbolIsTemp(sym_loc)) return; |
| 1741 | try addresses.append(sym.n_value); | 1698 | try addresses.append(sym.n_value); |
| 1742 | } | 1699 | } |
| ... | @@ -1845,7 +1802,7 @@ pub const Zld = struct { | ... | @@ -1845,7 +1802,7 @@ pub const Zld = struct { |
| 1845 | for (object.exec_atoms.items) |atom_index| { | 1802 | for (object.exec_atoms.items) |atom_index| { |
| 1846 | const atom = self.getAtom(atom_index); | 1803 | const atom = self.getAtom(atom_index); |
| 1847 | const sym = self.getSymbol(atom.getSymbolWithLoc()); | 1804 | const sym = self.getSymbol(atom.getSymbolWithLoc()); |
| 1848 | if (sym.n_desc == N_DEAD) continue; | 1805 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 1849 | | 1806 | |
| 1850 | const source_addr = if (object.getSourceSymbol(atom.sym_index)) |source_sym| | 1807 | const source_addr = if (object.getSourceSymbol(atom.sym_index)) |source_sym| |
| 1851 | source_sym.n_value | 1808 | source_sym.n_value |
| ... | @@ -1903,7 +1860,7 @@ pub const Zld = struct { | ... | @@ -1903,7 +1860,7 @@ pub const Zld = struct { |
| 1903 | fn addLocalToSymtab(self: *Zld, sym_loc: SymbolWithLoc, locals: *std.ArrayList(macho.nlist_64)) !void { | 1860 | fn addLocalToSymtab(self: *Zld, sym_loc: SymbolWithLoc, locals: *std.ArrayList(macho.nlist_64)) !void { |
| 1904 | const sym = self.getSymbol(sym_loc); | 1861 | const sym = self.getSymbol(sym_loc); |
| 1905 | if (sym.n_strx == 0) return; // no name, skip | 1862 | if (sym.n_strx == 0) return; // no name, skip |
| 1906 | if (sym.n_desc == N_DEAD) return; // garbage-collected, skip | 1863 | if (sym.n_desc == MachO.N_DEAD) return; // garbage-collected, skip |
| 1907 | if (sym.ext()) return; // an export lands in its own symtab section, skip | 1864 | if (sym.ext()) return; // an export lands in its own symtab section, skip |
| 1908 | if (self.symbolIsTemp(sym_loc)) return; // local temp symbol, skip | 1865 | if (self.symbolIsTemp(sym_loc)) return; // local temp symbol, skip |
| 1909 | | 1866 | |
| ... | @@ -1937,7 +1894,7 @@ pub const Zld = struct { | ... | @@ -1937,7 +1894,7 @@ pub const Zld = struct { |
| 1937 | for (self.globals.items) |global| { | 1894 | for (self.globals.items) |global| { |
| 1938 | const sym = self.getSymbol(global); | 1895 | const sym = self.getSymbol(global); |
| 1939 | if (sym.undf()) continue; // import, skip | 1896 | if (sym.undf()) continue; // import, skip |
| 1940 | if (sym.n_desc == N_DEAD) continue; | 1897 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 1941 | | 1898 | |
| 1942 | var out_sym = sym; | 1899 | var out_sym = sym; |
| 1943 | out_sym.n_strx = try self.strtab.insert(gpa, self.getSymbolName(global)); | 1900 | out_sym.n_strx = try self.strtab.insert(gpa, self.getSymbolName(global)); |
| ... | @@ -1952,7 +1909,7 @@ pub const Zld = struct { | ... | @@ -1952,7 +1909,7 @@ pub const Zld = struct { |
| 1952 | for (self.globals.items) |global| { | 1909 | for (self.globals.items) |global| { |
| 1953 | const sym = self.getSymbol(global); | 1910 | const sym = self.getSymbol(global); |
| 1954 | if (!sym.undf()) continue; // not an import, skip | 1911 | if (!sym.undf()) continue; // not an import, skip |
| 1955 | if (sym.n_desc == N_DEAD) continue; | 1912 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 1956 | | 1913 | |
| 1957 | const new_index = @as(u32, @intCast(imports.items.len)); | 1914 | const new_index = @as(u32, @intCast(imports.items.len)); |
| 1958 | var out_sym = sym; | 1915 | var out_sym = sym; |
| ... | @@ -2615,7 +2572,7 @@ pub const Zld = struct { | ... | @@ -2615,7 +2572,7 @@ pub const Zld = struct { |
| 2615 | for (self.globals.items, 0..) |global, i| { | 2572 | for (self.globals.items, 0..) |global, i| { |
| 2616 | const sym = self.getSymbol(global); | 2573 | const sym = self.getSymbol(global); |
| 2617 | if (sym.undf()) continue; | 2574 | if (sym.undf()) continue; |
| 2618 | if (sym.n_desc == N_DEAD) continue; | 2575 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 2619 | scoped_log.debug(" %{d}: {s} @{x} in sect({d}), {s} (def in object({?}))", .{ | 2576 | scoped_log.debug(" %{d}: {s} @{x} in sect({d}), {s} (def in object({?}))", .{ |
| 2620 | i, | 2577 | i, |
| 2621 | self.getSymbolName(global), | 2578 | self.getSymbolName(global), |
| ... | @@ -2630,7 +2587,7 @@ pub const Zld = struct { | ... | @@ -2630,7 +2587,7 @@ pub const Zld = struct { |
| 2630 | for (self.globals.items, 0..) |global, i| { | 2587 | for (self.globals.items, 0..) |global, i| { |
| 2631 | const sym = self.getSymbol(global); | 2588 | const sym = self.getSymbol(global); |
| 2632 | if (!sym.undf()) continue; | 2589 | if (!sym.undf()) continue; |
| 2633 | if (sym.n_desc == N_DEAD) continue; | 2590 | if (sym.n_desc == MachO.N_DEAD) continue; |
| 2634 | const ord = @divTrunc(sym.n_desc, macho.N_SYMBOL_RESOLVER); | 2591 | const ord = @divTrunc(sym.n_desc, macho.N_SYMBOL_RESOLVER); |
| 2635 | scoped_log.debug(" %{d}: {s} @{x} in ord({d}), {s}", .{ | 2592 | scoped_log.debug(" %{d}: {s} @{x} in ord({d}), {s}", .{ |
| 2636 | i, | 2593 | i, |
| ... | @@ -2740,26 +2697,6 @@ pub const Zld = struct { | ... | @@ -2740,26 +2697,6 @@ pub const Zld = struct { |
| 2740 | } | 2697 | } |
| 2741 | }; | 2698 | }; |
| 2742 | | 2699 | |
| 2743 | pub const N_DEAD: u16 = @as(u16, @bitCast(@as(i16, -1))); | | |
| 2744 | | | |
| 2745 | const IndirectPointer = struct { | | |
| 2746 | target: SymbolWithLoc, | | |
| 2747 | atom_index: Atom.Index, | | |
| 2748 | | | |
| 2749 | pub fn getTargetSymbol(self: @This(), zld: *Zld) macho.nlist_64 { | | |
| 2750 | return zld.getSymbol(self.target); | | |
| 2751 | } | | |
| 2752 | | | |
| 2753 | pub fn getTargetSymbolName(self: @This(), zld: *Zld) []const u8 { | | |
| 2754 | return zld.getSymbolName(self.target); | | |
| 2755 | } | | |
| 2756 | | | |
| 2757 | pub fn getAtomSymbol(self: @This(), zld: *Zld) macho.nlist_64 { | | |
| 2758 | const atom = zld.getAtom(self.atom_index); | | |
| 2759 | return zld.getSymbol(atom.getSymbolWithLoc()); | | |
| 2760 | } | | |
| 2761 | }; | | |
| 2762 | | | |
| 2763 | pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { | 2700 | pub fn linkWithZld(macho_file: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) link.File.FlushError!void { |
| 2764 | const tracy = trace(@src()); | 2701 | const tracy = trace(@src()); |
| 2765 | defer tracy.end(); | 2702 | defer tracy.end(); |