authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-11 21:30:32+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2024-01-24 12:34:39+01:00
log32ebceea95d22d399bc979370e5ce4cc3ca7d0ef
tree397c1dec33bff0a83584cc9602e05864d7e33da9
parent0b2231998f5b95845c8414083622ec7913d60af6

macho: sort sections; use Atom.Alignment for alignment; init segments


7 files changed, 367 insertions(+), 19 deletions(-)

src/link/MachO.zig+353-4
...@@ -89,7 +89,7 @@ weak_defines: bool = false,...@@ -89,7 +89,7 @@ weak_defines: bool = false,
89/// SDK layout89/// SDK layout
90sdk_layout: ?SdkLayout,90sdk_layout: ?SdkLayout,
91/// Size of the __PAGEZERO segment.91/// Size of the __PAGEZERO segment.
92pagezero_vmsize: ?u64,92pagezero_size: ?u64,
93/// Minimum space for future expansion of the load commands.93/// Minimum space for future expansion of the load commands.
94headerpad_size: ?u32,94headerpad_size: ?u32,
95/// Set enough space as if all paths were MATPATHLEN.95/// Set enough space as if all paths were MATPATHLEN.
...@@ -170,7 +170,7 @@ pub fn createEmpty(...@@ -170,7 +170,7 @@ pub fn createEmpty(
170 .build_id = options.build_id,170 .build_id = options.build_id,
171 .rpath_list = options.rpath_list,171 .rpath_list = options.rpath_list,
172 },172 },
173 .pagezero_vmsize = options.pagezero_size,173 .pagezero_size = options.pagezero_size,
174 .headerpad_size = options.headerpad_size,174 .headerpad_size = options.headerpad_size,
175 .headerpad_max_install_names = options.headerpad_max_install_names,175 .headerpad_max_install_names = options.headerpad_max_install_names,
176 .dead_strip_dylibs = options.dead_strip_dylibs,176 .dead_strip_dylibs = options.dead_strip_dylibs,
...@@ -527,6 +527,11 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node...@@ -527,6 +527,11 @@ pub fn flushModule(self: *MachO, arena: Allocator, prog_node: *std.Progress.Node
527527
528 try self.initOutputSections();528 try self.initOutputSections();
529 try self.initSyntheticSections();529 try self.initSyntheticSections();
530 try self.sortSections();
531 try self.addAtomsToSections();
532 try self.calcSectionSizes();
533 try self.generateUnwindInfo();
534 try self.initSegments();
530535
531 state_log.debug("{}", .{self.dumpState()});536 state_log.debug("{}", .{self.dumpState()});
532537
...@@ -613,7 +618,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {...@@ -613,7 +618,7 @@ fn dumpArgv(self: *MachO, comp: *Compilation) !void {
613 try argv.append(rpath);618 try argv.append(rpath);
614 }619 }
615620
616 if (self.pagezero_vmsize) |size| {621 if (self.pagezero_size) |size| {
617 try argv.append("-pagezero_size");622 try argv.append("-pagezero_size");
618 try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{size}));623 try argv.append(try std.fmt.allocPrint(arena, "0x{x}", .{size}));
619 }624 }
...@@ -1667,6 +1672,350 @@ fn getSegmentProt(segname: []const u8) macho.vm_prot_t {...@@ -1667,6 +1672,350 @@ fn getSegmentProt(segname: []const u8) macho.vm_prot_t {
1667 return macho.PROT.READ | macho.PROT.WRITE;1672 return macho.PROT.READ | macho.PROT.WRITE;
1668}1673}
16691674
1675fn getSegmentRank(segname: []const u8) u4 {
1676 if (mem.eql(u8, segname, "__PAGEZERO")) return 0x0;
1677 if (mem.eql(u8, segname, "__TEXT")) return 0x1;
1678 if (mem.eql(u8, segname, "__DATA_CONST")) return 0x2;
1679 if (mem.eql(u8, segname, "__DATA")) return 0x3;
1680 if (mem.eql(u8, segname, "__LINKEDIT")) return 0x5;
1681 return 0x4;
1682}
1683
1684fn getSectionRank(self: *MachO, sect_index: u8) u8 {
1685 const header = self.sections.items(.header)[sect_index];
1686 const segment_rank = getSegmentRank(header.segName());
1687 const section_rank: u4 = blk: {
1688 if (header.isCode()) {
1689 if (mem.eql(u8, "__text", header.sectName())) break :blk 0x0;
1690 if (header.type() == macho.S_SYMBOL_STUBS) break :blk 0x1;
1691 break :blk 0x2;
1692 }
1693 switch (header.type()) {
1694 macho.S_NON_LAZY_SYMBOL_POINTERS,
1695 macho.S_LAZY_SYMBOL_POINTERS,
1696 => break :blk 0x0,
1697
1698 macho.S_MOD_INIT_FUNC_POINTERS => break :blk 0x1,
1699 macho.S_MOD_TERM_FUNC_POINTERS => break :blk 0x2,
1700 macho.S_ZEROFILL => break :blk 0xf,
1701 macho.S_THREAD_LOCAL_REGULAR => break :blk 0xd,
1702 macho.S_THREAD_LOCAL_ZEROFILL => break :blk 0xe,
1703
1704 else => {
1705 if (mem.eql(u8, "__unwind_info", header.sectName())) break :blk 0xe;
1706 if (mem.eql(u8, "__compact_unwind", header.sectName())) break :blk 0xe;
1707 if (mem.eql(u8, "__eh_frame", header.sectName())) break :blk 0xf;
1708 break :blk 0x3;
1709 },
1710 }
1711 };
1712 return (@as(u8, @intCast(segment_rank)) << 4) + section_rank;
1713}
1714
1715pub fn sortSections(self: *MachO) !void {
1716 const Entry = struct {
1717 index: u8,
1718
1719 pub fn lessThan(macho_file: *MachO, lhs: @This(), rhs: @This()) bool {
1720 return macho_file.getSectionRank(lhs.index) < macho_file.getSectionRank(rhs.index);
1721 }
1722 };
1723
1724 const gpa = self.base.comp.gpa;
1725
1726 var entries = try std.ArrayList(Entry).initCapacity(gpa, self.sections.slice().len);
1727 defer entries.deinit();
1728 for (0..self.sections.slice().len) |index| {
1729 entries.appendAssumeCapacity(.{ .index = @intCast(index) });
1730 }
1731
1732 mem.sort(Entry, entries.items, self, Entry.lessThan);
1733
1734 const backlinks = try gpa.alloc(u8, entries.items.len);
1735 defer gpa.free(backlinks);
1736 for (entries.items, 0..) |entry, i| {
1737 backlinks[entry.index] = @intCast(i);
1738 }
1739
1740 var slice = self.sections.toOwnedSlice();
1741 defer slice.deinit(gpa);
1742
1743 try self.sections.ensureTotalCapacity(gpa, slice.len);
1744 for (entries.items) |sorted| {
1745 self.sections.appendAssumeCapacity(slice.get(sorted.index));
1746 }
1747
1748 for (self.objects.items) |index| {
1749 for (self.getFile(index).?.object.atoms.items) |atom_index| {
1750 const atom = self.getAtom(atom_index) orelse continue;
1751 if (!atom.flags.alive) continue;
1752 atom.out_n_sect = backlinks[atom.out_n_sect];
1753 }
1754 }
1755 if (self.getInternalObject()) |object| {
1756 for (object.atoms.items) |atom_index| {
1757 const atom = self.getAtom(atom_index) orelse continue;
1758 if (!atom.flags.alive) continue;
1759 atom.out_n_sect = backlinks[atom.out_n_sect];
1760 }
1761 }
1762
1763 for (&[_]*?u8{
1764 &self.data_sect_index,
1765 &self.got_sect_index,
1766 &self.stubs_sect_index,
1767 &self.stubs_helper_sect_index,
1768 &self.la_symbol_ptr_sect_index,
1769 &self.tlv_ptr_sect_index,
1770 &self.eh_frame_sect_index,
1771 &self.unwind_info_sect_index,
1772 &self.objc_stubs_sect_index,
1773 }) |maybe_index| {
1774 if (maybe_index.*) |*index| {
1775 index.* = backlinks[index.*];
1776 }
1777 }
1778}
1779
1780pub fn addAtomsToSections(self: *MachO) !void {
1781 const tracy = trace(@src());
1782 defer tracy.end();
1783
1784 for (self.objects.items) |index| {
1785 const object = self.getFile(index).?.object;
1786 for (object.atoms.items) |atom_index| {
1787 const atom = self.getAtom(atom_index) orelse continue;
1788 if (!atom.flags.alive) continue;
1789 const atoms = &self.sections.items(.atoms)[atom.out_n_sect];
1790 try atoms.append(self.base.comp.gpa, atom_index);
1791 }
1792 for (object.symbols.items) |sym_index| {
1793 const sym = self.getSymbol(sym_index);
1794 const atom = sym.getAtom(self) orelse continue;
1795 if (!atom.flags.alive) continue;
1796 if (sym.getFile(self).?.getIndex() != index) continue;
1797 sym.out_n_sect = atom.out_n_sect;
1798 }
1799 }
1800 if (self.getInternalObject()) |object| {
1801 for (object.atoms.items) |atom_index| {
1802 const atom = self.getAtom(atom_index) orelse continue;
1803 if (!atom.flags.alive) continue;
1804 const atoms = &self.sections.items(.atoms)[atom.out_n_sect];
1805 try atoms.append(self.base.comp.gpa, atom_index);
1806 }
1807 for (object.symbols.items) |sym_index| {
1808 const sym = self.getSymbol(sym_index);
1809 const atom = sym.getAtom(self) orelse continue;
1810 if (!atom.flags.alive) continue;
1811 if (sym.getFile(self).?.getIndex() != object.index) continue;
1812 sym.out_n_sect = atom.out_n_sect;
1813 }
1814 }
1815}
1816
1817fn calcSectionSizes(self: *MachO) !void {
1818 const tracy = trace(@src());
1819 defer tracy.end();
1820
1821 const cpu_arch = self.getTarget().cpu.arch;
1822
1823 if (self.data_sect_index) |idx| {
1824 const header = &self.sections.items(.header)[idx];
1825 header.size += @sizeOf(u64);
1826 header.@"align" = 3;
1827 }
1828
1829 const slice = self.sections.slice();
1830 for (slice.items(.header), slice.items(.atoms)) |*header, atoms| {
1831 if (atoms.items.len == 0) continue;
1832 if (self.requiresThunks() and header.isCode()) continue;
1833
1834 for (atoms.items) |atom_index| {
1835 const atom = self.getAtom(atom_index).?;
1836 const atom_alignment = atom.alignment.toByteUnits(1);
1837 const offset = mem.alignForward(u64, header.size, atom_alignment);
1838 const padding = offset - header.size;
1839 atom.value = offset;
1840 header.size += padding + atom.size;
1841 header.@"align" = @max(header.@"align", atom.alignment.toLog2Units());
1842 }
1843 }
1844
1845 if (self.requiresThunks()) {
1846 for (slice.items(.header), slice.items(.atoms), 0..) |header, atoms, i| {
1847 if (!header.isCode()) continue;
1848 if (atoms.items.len == 0) continue;
1849
1850 // Create jump/branch range extenders if needed.
1851 try thunks.createThunks(@intCast(i), self);
1852 }
1853 }
1854
1855 if (self.got_sect_index) |idx| {
1856 const header = &self.sections.items(.header)[idx];
1857 header.size = self.got.size();
1858 header.@"align" = 3;
1859 }
1860
1861 if (self.stubs_sect_index) |idx| {
1862 const header = &self.sections.items(.header)[idx];
1863 header.size = self.stubs.size(self);
1864 header.@"align" = switch (cpu_arch) {
1865 .x86_64 => 0,
1866 .aarch64 => 2,
1867 else => 0,
1868 };
1869 }
1870
1871 if (self.stubs_helper_sect_index) |idx| {
1872 const header = &self.sections.items(.header)[idx];
1873 header.size = self.stubs_helper.size(self);
1874 header.@"align" = switch (cpu_arch) {
1875 .x86_64 => 0,
1876 .aarch64 => 2,
1877 else => 0,
1878 };
1879 }
1880
1881 if (self.la_symbol_ptr_sect_index) |idx| {
1882 const header = &self.sections.items(.header)[idx];
1883 header.size = self.la_symbol_ptr.size(self);
1884 header.@"align" = 3;
1885 }
1886
1887 if (self.tlv_ptr_sect_index) |idx| {
1888 const header = &self.sections.items(.header)[idx];
1889 header.size = self.tlv_ptr.size();
1890 header.@"align" = 3;
1891 }
1892
1893 if (self.objc_stubs_sect_index) |idx| {
1894 const header = &self.sections.items(.header)[idx];
1895 header.size = self.objc_stubs.size(self);
1896 header.@"align" = switch (cpu_arch) {
1897 .x86_64 => 0,
1898 .aarch64 => 2,
1899 else => 0,
1900 };
1901 }
1902}
1903
1904fn generateUnwindInfo(self: *MachO) !void {
1905 const tracy = trace(@src());
1906 defer tracy.end();
1907
1908 if (self.eh_frame_sect_index) |index| {
1909 const sect = &self.sections.items(.header)[index];
1910 sect.size = try eh_frame.calcSize(self);
1911 sect.@"align" = 3;
1912 }
1913 if (self.unwind_info_sect_index) |index| {
1914 const sect = &self.sections.items(.header)[index];
1915 self.unwind_info.generate(self) catch |err| switch (err) {
1916 error.TooManyPersonalities => return self.reportUnexpectedError(
1917 "too many personalities in unwind info",
1918 .{},
1919 ),
1920 else => |e| return e,
1921 };
1922 sect.size = self.unwind_info.calcSize();
1923 sect.@"align" = 2;
1924 }
1925}
1926
1927fn initSegments(self: *MachO) !void {
1928 const gpa = self.base.comp.gpa;
1929 const slice = self.sections.slice();
1930
1931 // First, create segments required by sections
1932 for (slice.items(.header)) |header| {
1933 const segname = header.segName();
1934 if (self.getSegmentByName(segname) == null) {
1935 const prot = getSegmentProt(segname);
1936 try self.segments.append(gpa, .{
1937 .cmdsize = @sizeOf(macho.segment_command_64),
1938 .segname = makeStaticString(segname),
1939 .maxprot = prot,
1940 .initprot = prot,
1941 });
1942 }
1943 }
1944
1945 // Add __PAGEZERO if required
1946 const pagezero_size = self.pagezero_size orelse default_pagezero_size;
1947 const aligned_pagezero_size = mem.alignBackward(u64, pagezero_size, self.getPageSize());
1948 if (!self.base.isDynLib() and aligned_pagezero_size > 0) {
1949 if (aligned_pagezero_size != pagezero_size) {
1950 // TODO convert into a warning
1951 log.warn("requested __PAGEZERO size (0x{x}) is not page aligned", .{pagezero_size});
1952 log.warn(" rounding down to 0x{x}", .{aligned_pagezero_size});
1953 }
1954 try self.segments.append(gpa, .{
1955 .cmdsize = @sizeOf(macho.segment_command_64),
1956 .segname = makeStaticString("__PAGEZERO"),
1957 .vmsize = aligned_pagezero_size,
1958 });
1959 }
1960
1961 // Add __LINKEDIT
1962 {
1963 const protection = getSegmentProt("__LINKEDIT");
1964 self.linkedit_seg_index = @intCast(self.segments.items.len);
1965 try self.segments.append(gpa, .{
1966 .cmdsize = @sizeOf(macho.segment_command_64),
1967 .segname = makeStaticString("__LINKEDIT"),
1968 .maxprot = protection,
1969 .initprot = protection,
1970 });
1971 }
1972
1973 // __TEXT segment is non-optional
1974 if (self.getSegmentByName("__TEXT") == null) {
1975 const protection = getSegmentProt("__TEXT");
1976 try self.segments.append(gpa, .{
1977 .cmdsize = @sizeOf(macho.segment_command_64),
1978 .segname = makeStaticString("__TEXT"),
1979 .maxprot = protection,
1980 .initprot = protection,
1981 });
1982 }
1983
1984 const sortFn = struct {
1985 fn sortFn(ctx: void, lhs: macho.segment_command_64, rhs: macho.segment_command_64) bool {
1986 _ = ctx;
1987 return getSegmentRank(lhs.segName()) < getSegmentRank(rhs.segName());
1988 }
1989 }.sortFn;
1990
1991 // Sort segments
1992 mem.sort(macho.segment_command_64, self.segments.items, {}, sortFn);
1993
1994 // Attach sections to segments
1995 for (slice.items(.header), slice.items(.segment_id)) |header, *seg_id| {
1996 const segname = header.segName();
1997 const segment_id = self.getSegmentByName(segname) orelse blk: {
1998 const segment_id = @as(u8, @intCast(self.segments.items.len));
1999 const protection = getSegmentProt(segname);
2000 try self.segments.append(gpa, .{
2001 .cmdsize = @sizeOf(macho.segment_command_64),
2002 .segname = makeStaticString(segname),
2003 .maxprot = protection,
2004 .initprot = protection,
2005 });
2006 break :blk segment_id;
2007 };
2008 const segment = &self.segments.items[segment_id];
2009 segment.cmdsize += @sizeOf(macho.section_64);
2010 segment.nsects += 1;
2011 seg_id.* = segment_id;
2012 }
2013
2014 self.pagezero_seg_index = self.getSegmentByName("__PAGEZERO");
2015 self.text_seg_index = self.getSegmentByName("__TEXT").?;
2016 self.linkedit_seg_index = self.getSegmentByName("__LINKEDIT").?;
2017}
2018
1670fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void {2019fn shrinkAtom(self: *MachO, atom_index: Atom.Index, new_block_size: u64) void {
1671 _ = self;2020 _ = self;
1672 _ = atom_index;2021 _ = atom_index;
...@@ -2767,7 +3116,7 @@ pub const min_text_capacity = padToIdeal(minimum_text_block_size);...@@ -2767,7 +3116,7 @@ pub const min_text_capacity = padToIdeal(minimum_text_block_size);
27673116
2768/// Default virtual memory offset corresponds to the size of __PAGEZERO segment and3117/// Default virtual memory offset corresponds to the size of __PAGEZERO segment and
2769/// start of __TEXT segment.3118/// start of __TEXT segment.
2770pub const default_pagezero_vmsize: u64 = 0x100000000;3119pub const default_pagezero_size: u64 = 0x100000000;
27713120
2772/// We commit 0x1000 = 4096 bytes of space to the header and3121/// We commit 0x1000 = 4096 bytes of space to the header and
2773/// the table of load commands. This should be plenty for any3122/// the table of load commands. This should be plenty for any
src/link/MachO/Atom.zig+1-1
...@@ -11,7 +11,7 @@ file: File.Index = 0,...@@ -11,7 +11,7 @@ file: File.Index = 0,
11size: u64 = 0,11size: u64 = 0,
1212
13/// Alignment of this atom as a power of two.13/// Alignment of this atom as a power of two.
14alignment: u32 = 0,14alignment: Alignment = .@"1",
1515
16/// Index of the input section.16/// Index of the input section.
17n_sect: u32 = 0,17n_sect: u32 = 0,
src/link/MachO/InternalObject.zig+2-2
...@@ -48,7 +48,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil...@@ -48,7 +48,7 @@ fn addObjcMethnameSection(self: *InternalObject, methname: []const u8, macho_fil
48 atom.name = try macho_file.strings.insert(gpa, name);48 atom.name = try macho_file.strings.insert(gpa, name);
49 atom.file = self.index;49 atom.file = self.index;
50 atom.size = methname.len + 1;50 atom.size = methname.len + 1;
51 atom.alignment = 0;51 atom.alignment = .@"1";
5252
53 const n_sect = try self.addSection(gpa, "__TEXT", "__objc_methname");53 const n_sect = try self.addSection(gpa, "__TEXT", "__objc_methname");
54 const sect = &self.sections.items(.header)[n_sect];54 const sect = &self.sections.items(.header)[n_sect];
...@@ -82,7 +82,7 @@ fn addObjcSelrefsSection(...@@ -82,7 +82,7 @@ fn addObjcSelrefsSection(
82 atom.name = try macho_file.strings.insert(gpa, name);82 atom.name = try macho_file.strings.insert(gpa, name);
83 atom.file = self.index;83 atom.file = self.index;
84 atom.size = @sizeOf(u64);84 atom.size = @sizeOf(u64);
85 atom.alignment = 3;85 atom.alignment = .@"8";
8686
87 const n_sect = try self.addSection(gpa, "__DATA", "__objc_selrefs");87 const n_sect = try self.addSection(gpa, "__DATA", "__objc_selrefs");
88 const sect = &self.sections.items(.header)[n_sect];88 const sect = &self.sections.items(.header)[n_sect];
src/link/MachO/Object.zig+3-3
...@@ -346,7 +346,7 @@ fn addAtom(self: *Object, args: AddAtomArgs, macho_file: *MachO) !Atom.Index {...@@ -346,7 +346,7 @@ fn addAtom(self: *Object, args: AddAtomArgs, macho_file: *MachO) !Atom.Index {
346 atom.name = try macho_file.strings.insert(gpa, args.name);346 atom.name = try macho_file.strings.insert(gpa, args.name);
347 atom.n_sect = args.n_sect;347 atom.n_sect = args.n_sect;
348 atom.size = args.size;348 atom.size = args.size;
349 atom.alignment = args.alignment;349 atom.alignment = Atom.Alignment.fromLog2Units(args.alignment);
350 atom.off = args.off;350 atom.off = args.off;
351 try self.atoms.append(gpa, atom_index);351 try self.atoms.append(gpa, atom_index);
352 return atom_index;352 return atom_index;
...@@ -1120,13 +1120,13 @@ pub fn convertTentativeDefinitions(self: *Object, macho_file: *MachO) !void {...@@ -1120,13 +1120,13 @@ pub fn convertTentativeDefinitions(self: *Object, macho_file: *MachO) !void {
1120 atom.name = try macho_file.strings.insert(gpa, name);1120 atom.name = try macho_file.strings.insert(gpa, name);
1121 atom.file = self.index;1121 atom.file = self.index;
1122 atom.size = nlist.n_value;1122 atom.size = nlist.n_value;
1123 atom.alignment = (nlist.n_desc >> 8) & 0x0f;1123 atom.alignment = Atom.Alignment.fromLog2Units((nlist.n_desc >> 8) & 0x0f);
11241124
1125 const n_sect = try self.addSection(gpa, "__DATA", "__common");1125 const n_sect = try self.addSection(gpa, "__DATA", "__common");
1126 const sect = &self.sections.items(.header)[n_sect];1126 const sect = &self.sections.items(.header)[n_sect];
1127 sect.flags = macho.S_ZEROFILL;1127 sect.flags = macho.S_ZEROFILL;
1128 sect.size = atom.size;1128 sect.size = atom.size;
1129 sect.@"align" = atom.alignment;1129 sect.@"align" = atom.alignment.toLog2Units();
1130 atom.n_sect = n_sect;1130 atom.n_sect = n_sect;
11311131
1132 sym.value = 0;1132 sym.value = 0;
src/link/MachO/UnwindInfo.zig+2-2
...@@ -26,7 +26,7 @@ pub fn deinit(info: *UnwindInfo, allocator: Allocator) void {...@@ -26,7 +26,7 @@ pub fn deinit(info: *UnwindInfo, allocator: Allocator) void {
26}26}
2727
28fn canFold(macho_file: *MachO, lhs_index: Record.Index, rhs_index: Record.Index) bool {28fn canFold(macho_file: *MachO, lhs_index: Record.Index, rhs_index: Record.Index) bool {
29 const cpu_arch = macho_file.options.cpu_arch.?;29 const cpu_arch = macho_file.getTarget().cpu.arch;
30 const lhs = macho_file.getUnwindRecord(lhs_index);30 const lhs = macho_file.getUnwindRecord(lhs_index);
31 const rhs = macho_file.getUnwindRecord(rhs_index);31 const rhs = macho_file.getUnwindRecord(rhs_index);
32 if (cpu_arch == .x86_64) {32 if (cpu_arch == .x86_64) {
...@@ -42,7 +42,7 @@ fn canFold(macho_file: *MachO, lhs_index: Record.Index, rhs_index: Record.Index)...@@ -42,7 +42,7 @@ fn canFold(macho_file: *MachO, lhs_index: Record.Index, rhs_index: Record.Index)
42}42}
4343
44pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {44pub fn generate(info: *UnwindInfo, macho_file: *MachO) !void {
45 const gpa = macho_file.base.allocator;45 const gpa = macho_file.base.comp.gpa;
4646
47 log.debug("generating unwind info", .{});47 log.debug("generating unwind info", .{});
4848
src/link/MachO/eh_frame.zig+1-1
...@@ -314,7 +314,7 @@ pub fn calcSize(macho_file: *MachO) !u32 {...@@ -314,7 +314,7 @@ pub fn calcSize(macho_file: *MachO) !u32 {
314314
315 var offset: u32 = 0;315 var offset: u32 = 0;
316316
317 var cies = std.ArrayList(Cie).init(macho_file.base.allocator);317 var cies = std.ArrayList(Cie).init(macho_file.base.comp.gpa);
318 defer cies.deinit();318 defer cies.deinit();
319319
320 for (macho_file.objects.items) |index| {320 for (macho_file.objects.items) |index| {
src/link/MachO/thunks.zig+5-6
...@@ -2,7 +2,7 @@ pub fn createThunks(sect_id: u8, macho_file: *MachO) !void {...@@ -2,7 +2,7 @@ pub fn createThunks(sect_id: u8, macho_file: *MachO) !void {
2 const tracy = trace(@src());2 const tracy = trace(@src());
3 defer tracy.end();3 defer tracy.end();
44
5 const gpa = macho_file.base.allocator;5 const gpa = macho_file.base.comp.gpa;
6 const slice = macho_file.sections.slice();6 const slice = macho_file.sections.slice();
7 const header = &slice.items(.header)[sect_id];7 const header = &slice.items(.header)[sect_id];
8 const atoms = slice.items(.atoms)[sect_id].items;8 const atoms = slice.items(.atoms)[sect_id].items;
...@@ -46,18 +46,17 @@ pub fn createThunks(sect_id: u8, macho_file: *MachO) !void {...@@ -46,18 +46,17 @@ pub fn createThunks(sect_id: u8, macho_file: *MachO) !void {
46 atom.thunk_index = thunk_index;46 atom.thunk_index = thunk_index;
47 }47 }
4848
49 thunk.value = try advance(header, thunk.size(), 2);49 thunk.value = try advance(header, thunk.size(), .@"4");
5050
51 log.debug("thunk({d}) : {}", .{ thunk_index, thunk.fmt(macho_file) });51 log.debug("thunk({d}) : {}", .{ thunk_index, thunk.fmt(macho_file) });
52 }52 }
53}53}
5454
55fn advance(sect: *macho.section_64, size: u64, pow2_align: u32) !u64 {55fn advance(sect: *macho.section_64, size: u64, alignment: Atom.Alignment) !u64 {
56 const alignment = try math.powi(u32, 2, pow2_align);56 const offset = alignment.forward(sect.size);
57 const offset = mem.alignForward(u64, sect.size, alignment);
58 const padding = offset - sect.size;57 const padding = offset - sect.size;
59 sect.size += padding + size;58 sect.size += padding + size;
60 sect.@"align" = @max(sect.@"align", pow2_align);59 sect.@"align" = @max(sect.@"align", alignment.toLog2Units());
61 return offset;60 return offset;
62}61}
6362