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