| ... | ... | @@ -155,8 +155,8 @@ pub const PieFixup = struct { |
| 155 | 155 | }; |
| 156 | 156 | |
| 157 | 157 | /// `alloc_num / alloc_den` is the factor of padding when allocating. |
| 158 | | const alloc_num = 4; |
| 159 | | const alloc_den = 3; |
| 158 | pub const alloc_num = 4; |
| 159 | pub const alloc_den = 3; |
| 160 | 160 | |
| 161 | 161 | /// Default path to dyld |
| 162 | 162 | /// TODO instead of hardcoding it, we should probably look through some env vars and search paths |
| ... | ... | @@ -1358,7 +1358,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1358 | 1358 | }; |
| 1359 | 1359 | const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; |
| 1360 | 1360 | const needed_size = self.base.options.program_code_size_hint; |
| 1361 | | const off = self.findFreeSpace(text_segment, needed_size, @as(u16, 1) << alignment); |
| 1361 | const off = text_segment.findFreeSpace(needed_size, @as(u16, 1) << alignment, self.header_pad); |
| 1362 | 1362 | |
| 1363 | 1363 | log.debug("found __text section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); |
| 1364 | 1364 | |
| ... | ... | @@ -1386,7 +1386,7 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1386 | 1386 | |
| 1387 | 1387 | const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS; |
| 1388 | 1388 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 1389 | | const off = self.findFreeSpace(text_segment, needed_size, @alignOf(u64)); |
| 1389 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); |
| 1390 | 1390 | assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment. |
| 1391 | 1391 | |
| 1392 | 1392 | log.debug("found __ziggot section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); |
| ... | ... | @@ -1437,11 +1437,10 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1437 | 1437 | } |
| 1438 | 1438 | if (self.dyld_info_cmd_index == null) { |
| 1439 | 1439 | self.dyld_info_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 1440 | | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1441 | 1440 | |
| 1442 | 1441 | // TODO Preallocate rebase, binding, and lazy binding info. |
| 1443 | 1442 | const export_size = 2; |
| 1444 | | const export_off = self.findFreeSpace(&linkedit_segment, export_size, 1); |
| 1443 | const export_off = self.findFreeSpaceLinkedit(export_size, 1); |
| 1445 | 1444 | |
| 1446 | 1445 | log.debug("found export info free space 0x{x} to 0x{x}", .{ export_off, export_off + export_size }); |
| 1447 | 1446 | |
| ... | ... | @@ -1466,16 +1465,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1466 | 1465 | } |
| 1467 | 1466 | if (self.symtab_cmd_index == null) { |
| 1468 | 1467 | self.symtab_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 1469 | | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1470 | 1468 | |
| 1471 | 1469 | const symtab_size = self.base.options.symbol_count_hint * @sizeOf(macho.nlist_64); |
| 1472 | | const symtab_off = self.findFreeSpace(&linkedit_segment, symtab_size, @sizeOf(macho.nlist_64)); |
| 1470 | const symtab_off = self.findFreeSpaceLinkedit(symtab_size, @sizeOf(macho.nlist_64)); |
| 1473 | 1471 | |
| 1474 | 1472 | log.debug("found symbol table free space 0x{x} to 0x{x}", .{ symtab_off, symtab_off + symtab_size }); |
| 1475 | 1473 | |
| 1476 | 1474 | try self.string_table.append(self.base.allocator, 0); // Need a null at position 0. |
| 1477 | 1475 | const strtab_size = self.string_table.items.len; |
| 1478 | | const strtab_off = self.findFreeSpace(&linkedit_segment, strtab_size, 1); |
| 1476 | const strtab_off = self.findFreeSpaceLinkedit(strtab_size, 1); |
| 1479 | 1477 | |
| 1480 | 1478 | log.debug("found string table free space 0x{x} to 0x{x}", .{ strtab_off, strtab_off + strtab_size }); |
| 1481 | 1479 | |
| ... | ... | @@ -1613,7 +1611,6 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 1613 | 1611 | } |
| 1614 | 1612 | if (self.code_signature_cmd_index == null) { |
| 1615 | 1613 | self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 1616 | | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1617 | 1614 | try self.load_commands.append(self.base.allocator, .{ |
| 1618 | 1615 | .LinkeditData = .{ |
| 1619 | 1616 | .cmd = macho.LC_CODE_SIGNATURE, |
| ... | ... | @@ -1790,48 +1787,41 @@ fn nextSegmentAddressAndOffset(self: *MachO) NextSegmentAddressAndOffset { |
| 1790 | 1787 | }; |
| 1791 | 1788 | } |
| 1792 | 1789 | |
| 1793 | | fn allocatedSize(self: *MachO, segment: *const SegmentCommand, start: u64) u64 { |
| 1790 | fn allocatedSizeLinkedit(self: *MachO, start: u64) u64 { |
| 1794 | 1791 | assert(start > 0); |
| 1795 | 1792 | var min_pos: u64 = std.math.maxInt(u64); |
| 1796 | 1793 | |
| 1797 | | if (parseAndCmpName(&segment.inner.segname, "__LINKEDIT")) { |
| 1798 | | assert(segment.sections.items.len == 0); |
| 1799 | | // __LINKEDIT is a weird segment where sections get their own load commands so we |
| 1800 | | // special-case it. |
| 1801 | | if (self.dyld_info_cmd_index) |idx| { |
| 1802 | | const dyld_info = self.load_commands.items[idx].DyldInfoOnly; |
| 1803 | | if (dyld_info.rebase_off > start and dyld_info.rebase_off < min_pos) min_pos = dyld_info.rebase_off; |
| 1804 | | if (dyld_info.bind_off > start and dyld_info.bind_off < min_pos) min_pos = dyld_info.bind_off; |
| 1805 | | if (dyld_info.weak_bind_off > start and dyld_info.weak_bind_off < min_pos) min_pos = dyld_info.weak_bind_off; |
| 1806 | | if (dyld_info.lazy_bind_off > start and dyld_info.lazy_bind_off < min_pos) min_pos = dyld_info.lazy_bind_off; |
| 1807 | | if (dyld_info.export_off > start and dyld_info.export_off < min_pos) min_pos = dyld_info.export_off; |
| 1808 | | } |
| 1794 | // __LINKEDIT is a weird segment where sections get their own load commands so we |
| 1795 | // special-case it. |
| 1796 | if (self.dyld_info_cmd_index) |idx| { |
| 1797 | const dyld_info = self.load_commands.items[idx].DyldInfoOnly; |
| 1798 | if (dyld_info.rebase_off > start and dyld_info.rebase_off < min_pos) min_pos = dyld_info.rebase_off; |
| 1799 | if (dyld_info.bind_off > start and dyld_info.bind_off < min_pos) min_pos = dyld_info.bind_off; |
| 1800 | if (dyld_info.weak_bind_off > start and dyld_info.weak_bind_off < min_pos) min_pos = dyld_info.weak_bind_off; |
| 1801 | if (dyld_info.lazy_bind_off > start and dyld_info.lazy_bind_off < min_pos) min_pos = dyld_info.lazy_bind_off; |
| 1802 | if (dyld_info.export_off > start and dyld_info.export_off < min_pos) min_pos = dyld_info.export_off; |
| 1803 | } |
| 1809 | 1804 | |
| 1810 | | if (self.function_starts_cmd_index) |idx| { |
| 1811 | | const fstart = self.load_commands.items[idx].LinkeditData; |
| 1812 | | if (fstart.dataoff > start and fstart.dataoff < min_pos) min_pos = fstart.dataoff; |
| 1813 | | } |
| 1805 | if (self.function_starts_cmd_index) |idx| { |
| 1806 | const fstart = self.load_commands.items[idx].LinkeditData; |
| 1807 | if (fstart.dataoff > start and fstart.dataoff < min_pos) min_pos = fstart.dataoff; |
| 1808 | } |
| 1814 | 1809 | |
| 1815 | | if (self.data_in_code_cmd_index) |idx| { |
| 1816 | | const dic = self.load_commands.items[idx].LinkeditData; |
| 1817 | | if (dic.dataoff > start and dic.dataoff < min_pos) min_pos = dic.dataoff; |
| 1818 | | } |
| 1810 | if (self.data_in_code_cmd_index) |idx| { |
| 1811 | const dic = self.load_commands.items[idx].LinkeditData; |
| 1812 | if (dic.dataoff > start and dic.dataoff < min_pos) min_pos = dic.dataoff; |
| 1813 | } |
| 1819 | 1814 | |
| 1820 | | if (self.dysymtab_cmd_index) |idx| { |
| 1821 | | const dysymtab = self.load_commands.items[idx].Dysymtab; |
| 1822 | | if (dysymtab.indirectsymoff > start and dysymtab.indirectsymoff < min_pos) min_pos = dysymtab.indirectsymoff; |
| 1823 | | // TODO Handle more dynamic symbol table sections. |
| 1824 | | } |
| 1815 | if (self.dysymtab_cmd_index) |idx| { |
| 1816 | const dysymtab = self.load_commands.items[idx].Dysymtab; |
| 1817 | if (dysymtab.indirectsymoff > start and dysymtab.indirectsymoff < min_pos) min_pos = dysymtab.indirectsymoff; |
| 1818 | // TODO Handle more dynamic symbol table sections. |
| 1819 | } |
| 1825 | 1820 | |
| 1826 | | if (self.symtab_cmd_index) |idx| { |
| 1827 | | const symtab = self.load_commands.items[idx].Symtab; |
| 1828 | | if (symtab.symoff > start and symtab.symoff < min_pos) min_pos = symtab.symoff; |
| 1829 | | if (symtab.stroff > start and symtab.stroff < min_pos) min_pos = symtab.stroff; |
| 1830 | | } |
| 1831 | | } else { |
| 1832 | | for (segment.sections.items) |section| { |
| 1833 | | if (section.offset > start and section.offset < min_pos) min_pos = section.offset; |
| 1834 | | } |
| 1821 | if (self.symtab_cmd_index) |idx| { |
| 1822 | const symtab = self.load_commands.items[idx].Symtab; |
| 1823 | if (symtab.symoff > start and symtab.symoff < min_pos) min_pos = symtab.symoff; |
| 1824 | if (symtab.stroff > start and symtab.stroff < min_pos) min_pos = symtab.stroff; |
| 1835 | 1825 | } |
| 1836 | 1826 | |
| 1837 | 1827 | return min_pos - start; |
| ... | ... | @@ -1846,101 +1836,90 @@ inline fn checkForCollision(start: u64, end: u64, off: u64, size: u64) ?u64 { |
| 1846 | 1836 | return null; |
| 1847 | 1837 | } |
| 1848 | 1838 | |
| 1849 | | fn detectAllocCollision(self: *MachO, segment: *const SegmentCommand, start: u64, size: u64) ?u64 { |
| 1839 | fn detectAllocCollisionLinkedit(self: *MachO, start: u64, size: u64) ?u64 { |
| 1850 | 1840 | const end = start + satMul(size, alloc_num) / alloc_den; |
| 1851 | 1841 | |
| 1852 | | if (parseAndCmpName(&segment.inner.segname, "__LINKEDIT")) { |
| 1853 | | assert(segment.sections.items.len == 0); |
| 1854 | | // __LINKEDIT is a weird segment where sections get their own load commands so we |
| 1855 | | // special-case it. |
| 1856 | | if (self.dyld_info_cmd_index) |idx| outer: { |
| 1857 | | if (self.load_commands.items.len == idx) break :outer; |
| 1858 | | const dyld_info = self.load_commands.items[idx].DyldInfoOnly; |
| 1859 | | if (checkForCollision(start, end, dyld_info.rebase_off, dyld_info.rebase_size)) |pos| { |
| 1860 | | return pos; |
| 1861 | | } |
| 1862 | | // Binding info |
| 1863 | | if (checkForCollision(start, end, dyld_info.bind_off, dyld_info.bind_size)) |pos| { |
| 1864 | | return pos; |
| 1865 | | } |
| 1866 | | // Weak binding info |
| 1867 | | if (checkForCollision(start, end, dyld_info.weak_bind_off, dyld_info.weak_bind_size)) |pos| { |
| 1868 | | return pos; |
| 1869 | | } |
| 1870 | | // Lazy binding info |
| 1871 | | if (checkForCollision(start, end, dyld_info.lazy_bind_off, dyld_info.lazy_bind_size)) |pos| { |
| 1872 | | return pos; |
| 1873 | | } |
| 1874 | | // Export info |
| 1875 | | if (checkForCollision(start, end, dyld_info.export_off, dyld_info.export_size)) |pos| { |
| 1876 | | return pos; |
| 1877 | | } |
| 1842 | // __LINKEDIT is a weird segment where sections get their own load commands so we |
| 1843 | // special-case it. |
| 1844 | if (self.dyld_info_cmd_index) |idx| outer: { |
| 1845 | if (self.load_commands.items.len == idx) break :outer; |
| 1846 | const dyld_info = self.load_commands.items[idx].DyldInfoOnly; |
| 1847 | if (checkForCollision(start, end, dyld_info.rebase_off, dyld_info.rebase_size)) |pos| { |
| 1848 | return pos; |
| 1849 | } |
| 1850 | // Binding info |
| 1851 | if (checkForCollision(start, end, dyld_info.bind_off, dyld_info.bind_size)) |pos| { |
| 1852 | return pos; |
| 1853 | } |
| 1854 | // Weak binding info |
| 1855 | if (checkForCollision(start, end, dyld_info.weak_bind_off, dyld_info.weak_bind_size)) |pos| { |
| 1856 | return pos; |
| 1857 | } |
| 1858 | // Lazy binding info |
| 1859 | if (checkForCollision(start, end, dyld_info.lazy_bind_off, dyld_info.lazy_bind_size)) |pos| { |
| 1860 | return pos; |
| 1878 | 1861 | } |
| 1862 | // Export info |
| 1863 | if (checkForCollision(start, end, dyld_info.export_off, dyld_info.export_size)) |pos| { |
| 1864 | return pos; |
| 1865 | } |
| 1866 | } |
| 1879 | 1867 | |
| 1880 | | if (self.function_starts_cmd_index) |idx| outer: { |
| 1881 | | if (self.load_commands.items.len == idx) break :outer; |
| 1882 | | const fstart = self.load_commands.items[idx].LinkeditData; |
| 1883 | | if (checkForCollision(start, end, fstart.dataoff, fstart.datasize)) |pos| { |
| 1884 | | return pos; |
| 1885 | | } |
| 1868 | if (self.function_starts_cmd_index) |idx| outer: { |
| 1869 | if (self.load_commands.items.len == idx) break :outer; |
| 1870 | const fstart = self.load_commands.items[idx].LinkeditData; |
| 1871 | if (checkForCollision(start, end, fstart.dataoff, fstart.datasize)) |pos| { |
| 1872 | return pos; |
| 1886 | 1873 | } |
| 1874 | } |
| 1887 | 1875 | |
| 1888 | | if (self.data_in_code_cmd_index) |idx| outer: { |
| 1889 | | if (self.load_commands.items.len == idx) break :outer; |
| 1890 | | const dic = self.load_commands.items[idx].LinkeditData; |
| 1891 | | if (checkForCollision(start, end, dic.dataoff, dic.datasize)) |pos| { |
| 1892 | | return pos; |
| 1893 | | } |
| 1876 | if (self.data_in_code_cmd_index) |idx| outer: { |
| 1877 | if (self.load_commands.items.len == idx) break :outer; |
| 1878 | const dic = self.load_commands.items[idx].LinkeditData; |
| 1879 | if (checkForCollision(start, end, dic.dataoff, dic.datasize)) |pos| { |
| 1880 | return pos; |
| 1894 | 1881 | } |
| 1882 | } |
| 1895 | 1883 | |
| 1896 | | if (self.dysymtab_cmd_index) |idx| outer: { |
| 1897 | | if (self.load_commands.items.len == idx) break :outer; |
| 1898 | | const dysymtab = self.load_commands.items[idx].Dysymtab; |
| 1899 | | // Indirect symbol table |
| 1900 | | const nindirectsize = dysymtab.nindirectsyms * @sizeOf(u32); |
| 1901 | | if (checkForCollision(start, end, dysymtab.indirectsymoff, nindirectsize)) |pos| { |
| 1902 | | return pos; |
| 1903 | | } |
| 1904 | | // TODO Handle more dynamic symbol table sections. |
| 1884 | if (self.dysymtab_cmd_index) |idx| outer: { |
| 1885 | if (self.load_commands.items.len == idx) break :outer; |
| 1886 | const dysymtab = self.load_commands.items[idx].Dysymtab; |
| 1887 | // Indirect symbol table |
| 1888 | const nindirectsize = dysymtab.nindirectsyms * @sizeOf(u32); |
| 1889 | if (checkForCollision(start, end, dysymtab.indirectsymoff, nindirectsize)) |pos| { |
| 1890 | return pos; |
| 1905 | 1891 | } |
| 1892 | // TODO Handle more dynamic symbol table sections. |
| 1893 | } |
| 1906 | 1894 | |
| 1907 | | if (self.symtab_cmd_index) |idx| outer: { |
| 1908 | | if (self.load_commands.items.len == idx) break :outer; |
| 1909 | | const symtab = self.load_commands.items[idx].Symtab; |
| 1910 | | // Symbol table |
| 1911 | | const symsize = symtab.nsyms * @sizeOf(macho.nlist_64); |
| 1912 | | if (checkForCollision(start, end, symtab.symoff, symsize)) |pos| { |
| 1913 | | return pos; |
| 1914 | | } |
| 1915 | | // String table |
| 1916 | | if (checkForCollision(start, end, symtab.stroff, symtab.strsize)) |pos| { |
| 1917 | | return pos; |
| 1918 | | } |
| 1895 | if (self.symtab_cmd_index) |idx| outer: { |
| 1896 | if (self.load_commands.items.len == idx) break :outer; |
| 1897 | const symtab = self.load_commands.items[idx].Symtab; |
| 1898 | // Symbol table |
| 1899 | const symsize = symtab.nsyms * @sizeOf(macho.nlist_64); |
| 1900 | if (checkForCollision(start, end, symtab.symoff, symsize)) |pos| { |
| 1901 | return pos; |
| 1919 | 1902 | } |
| 1920 | | } else { |
| 1921 | | for (segment.sections.items) |section| { |
| 1922 | | if (checkForCollision(start, end, section.offset, section.size)) |pos| { |
| 1923 | | return pos; |
| 1924 | | } |
| 1903 | // String table |
| 1904 | if (checkForCollision(start, end, symtab.stroff, symtab.strsize)) |pos| { |
| 1905 | return pos; |
| 1925 | 1906 | } |
| 1926 | 1907 | } |
| 1927 | 1908 | |
| 1928 | 1909 | return null; |
| 1929 | 1910 | } |
| 1930 | 1911 | |
| 1931 | | fn findFreeSpace(self: *MachO, segment: *const SegmentCommand, object_size: u64, min_alignment: u16) u64 { |
| 1932 | | var start: u64 = if (parseAndCmpName(&segment.inner.segname, "__TEXT")) |
| 1933 | | self.header_pad |
| 1934 | | else |
| 1935 | | segment.inner.fileoff; |
| 1936 | | while (self.detectAllocCollision(segment, start, object_size)) |item_end| { |
| 1912 | fn findFreeSpaceLinkedit(self: *MachO, object_size: u64, min_alignment: u16) u64 { |
| 1913 | const linkedit = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1914 | var start: u64 = linkedit.inner.fileoff; |
| 1915 | while (self.detectAllocCollisionLinkedit(start, object_size)) |item_end| { |
| 1937 | 1916 | start = mem.alignForwardGeneric(u64, item_end, min_alignment); |
| 1938 | 1917 | } |
| 1939 | 1918 | return start; |
| 1940 | 1919 | } |
| 1941 | 1920 | |
| 1942 | 1921 | /// Saturating multiplication |
| 1943 | | fn satMul(a: anytype, b: anytype) @TypeOf(a, b) { |
| 1922 | pub fn satMul(a: anytype, b: anytype) @TypeOf(a, b) { |
| 1944 | 1923 | const T = @TypeOf(a, b); |
| 1945 | 1924 | return std.math.mul(T, a, b) catch std.math.maxInt(T); |
| 1946 | 1925 | } |
| ... | ... | @@ -1993,9 +1972,9 @@ fn relocateSymbolTable(self: *MachO) !void { |
| 1993 | 1972 | if (symtab.nsyms < nsyms) { |
| 1994 | 1973 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 1995 | 1974 | const needed_size = nsyms * @sizeOf(macho.nlist_64); |
| 1996 | | if (needed_size > self.allocatedSize(&linkedit_segment, symtab.symoff)) { |
| 1975 | if (needed_size > self.allocatedSizeLinkedit(symtab.symoff)) { |
| 1997 | 1976 | // Move the entire symbol table to a new location |
| 1998 | | const new_symoff = self.findFreeSpace(&linkedit_segment, needed_size, @alignOf(macho.nlist_64)); |
| 1977 | const new_symoff = self.findFreeSpaceLinkedit(needed_size, @alignOf(macho.nlist_64)); |
| 1999 | 1978 | const existing_size = symtab.nsyms * @sizeOf(macho.nlist_64); |
| 2000 | 1979 | |
| 2001 | 1980 | log.debug("relocating symbol table from 0x{x}-0x{x} to 0x{x}-0x{x}", .{ |
| ... | ... | @@ -2140,12 +2119,12 @@ fn writeExportTrie(self: *MachO) !void { |
| 2140 | 2119 | |
| 2141 | 2120 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2142 | 2121 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 2143 | | const allocated_size = self.allocatedSize(&linkedit_segment, dyld_info.export_off); |
| 2122 | const allocated_size = self.allocatedSizeLinkedit(dyld_info.export_off); |
| 2144 | 2123 | const needed_size = mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)); |
| 2145 | 2124 | |
| 2146 | 2125 | if (needed_size > allocated_size) { |
| 2147 | 2126 | dyld_info.export_off = 0; |
| 2148 | | dyld_info.export_off = @intCast(u32, self.findFreeSpace(&linkedit_segment, needed_size, 1)); |
| 2127 | dyld_info.export_off = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1)); |
| 2149 | 2128 | } |
| 2150 | 2129 | dyld_info.export_size = @intCast(u32, needed_size); |
| 2151 | 2130 | log.debug("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size }); |
| ... | ... | @@ -2170,12 +2149,12 @@ fn writeBindingInfoTable(self: *MachO) !void { |
| 2170 | 2149 | |
| 2171 | 2150 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2172 | 2151 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 2173 | | const allocated_size = self.allocatedSize(&linkedit_segment, dyld_info.bind_off); |
| 2152 | const allocated_size = self.allocatedSizeLinkedit(dyld_info.bind_off); |
| 2174 | 2153 | const needed_size = mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)); |
| 2175 | 2154 | |
| 2176 | 2155 | if (needed_size > allocated_size) { |
| 2177 | 2156 | dyld_info.bind_off = 0; |
| 2178 | | dyld_info.bind_off = @intCast(u32, self.findFreeSpace(&linkedit_segment, needed_size, 1)); |
| 2157 | dyld_info.bind_off = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1)); |
| 2179 | 2158 | } |
| 2180 | 2159 | |
| 2181 | 2160 | dyld_info.bind_size = @intCast(u32, needed_size); |
| ... | ... | @@ -2198,12 +2177,12 @@ fn writeLazyBindingInfoTable(self: *MachO) !void { |
| 2198 | 2177 | |
| 2199 | 2178 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2200 | 2179 | const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfoOnly; |
| 2201 | | const allocated_size = self.allocatedSize(&linkedit_segment, dyld_info.lazy_bind_off); |
| 2180 | const allocated_size = self.allocatedSizeLinkedit(dyld_info.lazy_bind_off); |
| 2202 | 2181 | const needed_size = mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64)); |
| 2203 | 2182 | |
| 2204 | 2183 | if (needed_size > allocated_size) { |
| 2205 | 2184 | dyld_info.lazy_bind_off = 0; |
| 2206 | | dyld_info.lazy_bind_off = @intCast(u32, self.findFreeSpace(&linkedit_segment, needed_size, 1)); |
| 2185 | dyld_info.lazy_bind_off = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1)); |
| 2207 | 2186 | } |
| 2208 | 2187 | |
| 2209 | 2188 | dyld_info.lazy_bind_size = @intCast(u32, needed_size); |
| ... | ... | @@ -2222,12 +2201,12 @@ fn writeStringTable(self: *MachO) !void { |
| 2222 | 2201 | |
| 2223 | 2202 | const linkedit_segment = self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment; |
| 2224 | 2203 | const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab; |
| 2225 | | const allocated_size = self.allocatedSize(&linkedit_segment, symtab.stroff); |
| 2204 | const allocated_size = self.allocatedSizeLinkedit(symtab.stroff); |
| 2226 | 2205 | const needed_size = mem.alignForwardGeneric(u64, self.string_table.items.len, @alignOf(u64)); |
| 2227 | 2206 | |
| 2228 | 2207 | if (needed_size > allocated_size) { |
| 2229 | 2208 | symtab.strsize = 0; |
| 2230 | | symtab.stroff = @intCast(u32, self.findFreeSpace(&linkedit_segment, needed_size, 1)); |
| 2209 | symtab.stroff = @intCast(u32, self.findFreeSpaceLinkedit(needed_size, 1)); |
| 2231 | 2210 | } |
| 2232 | 2211 | symtab.strsize = @intCast(u32, needed_size); |
| 2233 | 2212 | log.debug("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| ... | ... | @@ -2280,7 +2259,7 @@ fn updateLinkeditSegmentSizes(self: *MachO) !void { |
| 2280 | 2259 | const filesize = final_offset - linkedit_segment.inner.fileoff; |
| 2281 | 2260 | linkedit_segment.inner.filesize = filesize; |
| 2282 | 2261 | linkedit_segment.inner.vmsize = mem.alignForwardGeneric(u64, filesize, self.page_size); |
| 2283 | | try self.base.file.?.pwriteAll(&[_]u8{ 0 }, final_offset); |
| 2262 | try self.base.file.?.pwriteAll(&[_]u8{0}, final_offset); |
| 2284 | 2263 | self.load_commands_dirty = true; |
| 2285 | 2264 | } |
| 2286 | 2265 | |
| ... | ... | @@ -2301,7 +2280,7 @@ fn writeLoadCommands(self: *MachO) !void { |
| 2301 | 2280 | } |
| 2302 | 2281 | |
| 2303 | 2282 | const off = @sizeOf(macho.mach_header_64); |
| 2304 | | log.debug("writing {} load commands from 0x{x} to 0x{x}", .{self.load_commands.items.len, off, off + sizeofcmds}); |
| 2283 | log.debug("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds }); |
| 2305 | 2284 | try self.base.file.?.pwriteAll(buffer, off); |
| 2306 | 2285 | self.load_commands_dirty = false; |
| 2307 | 2286 | } |