| ... | ... | @@ -121,48 +121,12 @@ data_const_segment_cmd_index: ?u8 = null, |
| 121 | 121 | data_segment_cmd_index: ?u8 = null, |
| 122 | 122 | linkedit_segment_cmd_index: ?u8 = null, |
| 123 | 123 | |
| 124 | | // __TEXT segment sections |
| 125 | 124 | text_section_index: ?u8 = null, |
| 126 | 125 | stubs_section_index: ?u8 = null, |
| 127 | 126 | stub_helper_section_index: ?u8 = null, |
| 128 | | text_const_section_index: ?u8 = null, |
| 129 | | cstring_section_index: ?u8 = null, |
| 130 | | ustring_section_index: ?u8 = null, |
| 131 | | gcc_except_tab_section_index: ?u8 = null, |
| 132 | | unwind_info_section_index: ?u8 = null, |
| 133 | | eh_frame_section_index: ?u8 = null, |
| 134 | | |
| 135 | | objc_methlist_section_index: ?u8 = null, |
| 136 | | objc_methname_section_index: ?u8 = null, |
| 137 | | objc_methtype_section_index: ?u8 = null, |
| 138 | | objc_classname_section_index: ?u8 = null, |
| 139 | | |
| 140 | | // __DATA_CONST segment sections |
| 141 | 127 | got_section_index: ?u8 = null, |
| 142 | | mod_init_func_section_index: ?u8 = null, |
| 143 | | mod_term_func_section_index: ?u8 = null, |
| 144 | | data_const_section_index: ?u8 = null, |
| 145 | | |
| 146 | | objc_cfstring_section_index: ?u8 = null, |
| 147 | | objc_classlist_section_index: ?u8 = null, |
| 148 | | objc_imageinfo_section_index: ?u8 = null, |
| 149 | | |
| 150 | | // __DATA segment sections |
| 151 | | tlv_section_index: ?u8 = null, |
| 152 | | tlv_data_section_index: ?u8 = null, |
| 153 | | tlv_bss_section_index: ?u8 = null, |
| 154 | | tlv_ptrs_section_index: ?u8 = null, |
| 155 | 128 | la_symbol_ptr_section_index: ?u8 = null, |
| 156 | 129 | data_section_index: ?u8 = null, |
| 157 | | bss_section_index: ?u8 = null, |
| 158 | | |
| 159 | | objc_const_section_index: ?u8 = null, |
| 160 | | objc_selrefs_section_index: ?u8 = null, |
| 161 | | objc_classrefs_section_index: ?u8 = null, |
| 162 | | objc_data_section_index: ?u8 = null, |
| 163 | | |
| 164 | | rustc_section_index: ?u8 = null, |
| 165 | | rustc_section_size: u64 = 0, |
| 166 | 130 | |
| 167 | 131 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 168 | 132 | globals: std.StringArrayHashMapUnmanaged(SymbolWithLoc) = .{}, |
| ... | ... | @@ -547,14 +511,15 @@ pub fn flushModule(self: *MachO, comp: *Compilation, prog_node: *std.Progress.No |
| 547 | 511 | |
| 548 | 512 | try self.createMhExecuteHeaderSymbol(); |
| 549 | 513 | try self.resolveDyldStubBinder(); |
| 550 | | try self.createDyldPrivateAtom(); |
| 551 | | try self.createStubHelperPreambleAtom(); |
| 552 | 514 | try self.resolveSymbolsInDylibs(); |
| 553 | 515 | |
| 554 | 516 | if (self.unresolved.count() > 0) { |
| 555 | 517 | return error.UndefinedSymbolReference; |
| 556 | 518 | } |
| 557 | 519 | |
| 520 | try self.createDyldPrivateAtom(); |
| 521 | try self.createStubHelperPreambleAtom(); |
| 522 | |
| 558 | 523 | try self.allocateSpecialSymbols(); |
| 559 | 524 | |
| 560 | 525 | if (build_options.enable_logging) { |
| ... | ... | @@ -1140,7 +1105,6 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1140 | 1105 | |
| 1141 | 1106 | try self.resolveSymbolsInArchives(); |
| 1142 | 1107 | try self.resolveDyldStubBinder(); |
| 1143 | | try self.createDyldPrivateAtom(); |
| 1144 | 1108 | try self.resolveSymbolsInDylibs(); |
| 1145 | 1109 | try self.createMhExecuteHeaderSymbol(); |
| 1146 | 1110 | try self.createDsoHandleSymbol(); |
| ... | ... | @@ -1160,8 +1124,9 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1160 | 1124 | try object.scanInputSections(self); |
| 1161 | 1125 | } |
| 1162 | 1126 | |
| 1163 | | try self.createStubHelperPreambleAtom(); |
| 1127 | try self.createDyldPrivateAtom(); |
| 1164 | 1128 | try self.createTentativeDefAtoms(); |
| 1129 | try self.createStubHelperPreambleAtom(); |
| 1165 | 1130 | |
| 1166 | 1131 | for (self.objects.items) |*object, object_id| { |
| 1167 | 1132 | try object.splitIntoAtomsOneShot(self, @intCast(u32, object_id)); |
| ... | ... | @@ -1184,11 +1149,6 @@ fn linkOneShot(self: *MachO, comp: *Compilation, prog_node: *std.Progress.Node) |
| 1184 | 1149 | |
| 1185 | 1150 | try self.writeAtomsOneShot(); |
| 1186 | 1151 | |
| 1187 | | if (self.rustc_section_index) |id| { |
| 1188 | | const header = &self.sections.items(.header)[id]; |
| 1189 | | header.size = self.rustc_section_size; |
| 1190 | | } |
| 1191 | | |
| 1192 | 1152 | var lc_buffer = std.ArrayList(u8).init(arena); |
| 1193 | 1153 | const lc_writer = lc_buffer.writer(); |
| 1194 | 1154 | var ncmds: u32 = 0; |
| ... | ... | @@ -1696,417 +1656,142 @@ pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 { |
| 1696 | 1656 | const segname = sect.segName(); |
| 1697 | 1657 | const sectname = sect.sectName(); |
| 1698 | 1658 | const res: ?u8 = blk: { |
| 1659 | if (mem.eql(u8, "__LLVM", segname)) { |
| 1660 | log.debug("TODO LLVM section: type 0x{x}, name '{s},{s}'", .{ |
| 1661 | sect.flags, segname, sectname, |
| 1662 | }); |
| 1663 | break :blk null; |
| 1664 | } |
| 1665 | |
| 1666 | if (sect.isCode()) { |
| 1667 | if (self.text_section_index == null) { |
| 1668 | self.text_section_index = try self.initSection( |
| 1669 | "__TEXT", |
| 1670 | "__text", |
| 1671 | sect.size, |
| 1672 | sect.@"align", |
| 1673 | .{ |
| 1674 | .flags = macho.S_REGULAR | |
| 1675 | macho.S_ATTR_PURE_INSTRUCTIONS | |
| 1676 | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 1677 | }, |
| 1678 | ); |
| 1679 | } |
| 1680 | break :blk self.text_section_index.?; |
| 1681 | } |
| 1682 | |
| 1683 | if (sect.isDebug()) { |
| 1684 | // TODO debug attributes |
| 1685 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { |
| 1686 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ |
| 1687 | sect.flags, segname, sectname, |
| 1688 | }); |
| 1689 | } |
| 1690 | break :blk null; |
| 1691 | } |
| 1692 | |
| 1699 | 1693 | switch (sect.@"type"()) { |
| 1700 | | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 1701 | | if (self.text_const_section_index == null) { |
| 1702 | | self.text_const_section_index = try self.initSection( |
| 1703 | | self.text_segment_cmd_index.?, |
| 1704 | | "__const", |
| 1705 | | sect.size, |
| 1706 | | sect.@"align", |
| 1707 | | .{}, |
| 1708 | | ); |
| 1709 | | } |
| 1710 | | break :blk self.text_const_section_index.?; |
| 1694 | macho.S_4BYTE_LITERALS, |
| 1695 | macho.S_8BYTE_LITERALS, |
| 1696 | macho.S_16BYTE_LITERALS, |
| 1697 | => { |
| 1698 | break :blk self.getSectionByName("__TEXT", "__const") orelse try self.initSection( |
| 1699 | "__TEXT", |
| 1700 | "__const", |
| 1701 | sect.size, |
| 1702 | sect.@"align", |
| 1703 | .{}, |
| 1704 | ); |
| 1711 | 1705 | }, |
| 1712 | 1706 | macho.S_CSTRING_LITERALS => { |
| 1713 | | if (mem.eql(u8, sectname, "__objc_methname")) { |
| 1714 | | // TODO it seems the common values within the sections in objects are deduplicated/merged |
| 1715 | | // on merging the sections' contents. |
| 1716 | | if (self.objc_methname_section_index == null) { |
| 1717 | | self.objc_methname_section_index = try self.initSection( |
| 1718 | | self.text_segment_cmd_index.?, |
| 1719 | | "__objc_methname", |
| 1720 | | sect.size, |
| 1721 | | sect.@"align", |
| 1722 | | .{}, |
| 1723 | | ); |
| 1724 | | } |
| 1725 | | break :blk self.objc_methname_section_index.?; |
| 1726 | | } else if (mem.eql(u8, sectname, "__objc_methtype")) { |
| 1727 | | if (self.objc_methtype_section_index == null) { |
| 1728 | | self.objc_methtype_section_index = try self.initSection( |
| 1729 | | self.text_segment_cmd_index.?, |
| 1730 | | "__objc_methtype", |
| 1731 | | sect.size, |
| 1732 | | sect.@"align", |
| 1733 | | .{}, |
| 1734 | | ); |
| 1735 | | } |
| 1736 | | break :blk self.objc_methtype_section_index.?; |
| 1737 | | } else if (mem.eql(u8, sectname, "__objc_classname")) { |
| 1738 | | if (self.objc_classname_section_index == null) { |
| 1739 | | self.objc_classname_section_index = try self.initSection( |
| 1740 | | self.text_segment_cmd_index.?, |
| 1741 | | "__objc_classname", |
| 1742 | | sect.size, |
| 1743 | | sect.@"align", |
| 1744 | | .{}, |
| 1745 | | ); |
| 1746 | | } |
| 1747 | | break :blk self.objc_classname_section_index.?; |
| 1748 | | } |
| 1749 | | |
| 1750 | | if (self.cstring_section_index == null) { |
| 1751 | | self.cstring_section_index = try self.initSection( |
| 1752 | | self.text_segment_cmd_index.?, |
| 1753 | | "__cstring", |
| 1707 | if (mem.startsWith(u8, sectname, "__objc")) { |
| 1708 | break :blk self.getSectionByName(segname, sectname) orelse try self.initSection( |
| 1709 | segname, |
| 1710 | sectname, |
| 1754 | 1711 | sect.size, |
| 1755 | 1712 | sect.@"align", |
| 1756 | | .{ |
| 1757 | | .flags = macho.S_CSTRING_LITERALS, |
| 1758 | | }, |
| 1759 | | ); |
| 1760 | | } |
| 1761 | | break :blk self.cstring_section_index.?; |
| 1762 | | }, |
| 1763 | | macho.S_LITERAL_POINTERS => { |
| 1764 | | if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__objc_selrefs")) { |
| 1765 | | if (self.objc_selrefs_section_index == null) { |
| 1766 | | self.objc_selrefs_section_index = try self.initSection( |
| 1767 | | self.data_segment_cmd_index.?, |
| 1768 | | "__objc_selrefs", |
| 1769 | | sect.size, |
| 1770 | | sect.@"align", |
| 1771 | | .{ |
| 1772 | | .flags = macho.S_LITERAL_POINTERS, |
| 1773 | | }, |
| 1774 | | ); |
| 1775 | | } |
| 1776 | | break :blk self.objc_selrefs_section_index.?; |
| 1777 | | } else { |
| 1778 | | // TODO investigate |
| 1779 | | break :blk null; |
| 1780 | | } |
| 1781 | | }, |
| 1782 | | macho.S_MOD_INIT_FUNC_POINTERS => { |
| 1783 | | if (self.mod_init_func_section_index == null) { |
| 1784 | | self.mod_init_func_section_index = try self.initSection( |
| 1785 | | self.data_const_segment_cmd_index.?, |
| 1786 | | "__mod_init_func", |
| 1787 | | sect.size, |
| 1788 | | sect.@"align", |
| 1789 | | .{ |
| 1790 | | .flags = macho.S_MOD_INIT_FUNC_POINTERS, |
| 1791 | | }, |
| 1792 | | ); |
| 1793 | | } |
| 1794 | | break :blk self.mod_init_func_section_index.?; |
| 1795 | | }, |
| 1796 | | macho.S_MOD_TERM_FUNC_POINTERS => { |
| 1797 | | if (self.mod_term_func_section_index == null) { |
| 1798 | | self.mod_term_func_section_index = try self.initSection( |
| 1799 | | self.data_const_segment_cmd_index.?, |
| 1800 | | "__mod_term_func", |
| 1801 | | sect.size, |
| 1802 | | sect.@"align", |
| 1803 | | .{ |
| 1804 | | .flags = macho.S_MOD_TERM_FUNC_POINTERS, |
| 1805 | | }, |
| 1806 | | ); |
| 1807 | | } |
| 1808 | | break :blk self.mod_term_func_section_index.?; |
| 1809 | | }, |
| 1810 | | macho.S_ZEROFILL => { |
| 1811 | | if (self.bss_section_index == null) { |
| 1812 | | self.bss_section_index = try self.initSection( |
| 1813 | | self.data_segment_cmd_index.?, |
| 1814 | | "__bss", |
| 1815 | | sect.size, |
| 1816 | | sect.@"align", |
| 1817 | | .{ |
| 1818 | | .flags = macho.S_ZEROFILL, |
| 1819 | | }, |
| 1820 | | ); |
| 1821 | | } |
| 1822 | | break :blk self.bss_section_index.?; |
| 1823 | | }, |
| 1824 | | macho.S_THREAD_LOCAL_VARIABLES => { |
| 1825 | | if (self.tlv_section_index == null) { |
| 1826 | | self.tlv_section_index = try self.initSection( |
| 1827 | | self.data_segment_cmd_index.?, |
| 1828 | | "__thread_vars", |
| 1829 | | sect.size, |
| 1830 | | sect.@"align", |
| 1831 | | .{ |
| 1832 | | .flags = macho.S_THREAD_LOCAL_VARIABLES, |
| 1833 | | }, |
| 1834 | | ); |
| 1835 | | } |
| 1836 | | break :blk self.tlv_section_index.?; |
| 1837 | | }, |
| 1838 | | macho.S_THREAD_LOCAL_VARIABLE_POINTERS => { |
| 1839 | | if (self.tlv_ptrs_section_index == null) { |
| 1840 | | self.tlv_ptrs_section_index = try self.initSection( |
| 1841 | | self.data_segment_cmd_index.?, |
| 1842 | | "__thread_ptrs", |
| 1843 | | sect.size, |
| 1844 | | sect.@"align", |
| 1845 | | .{ |
| 1846 | | .flags = macho.S_THREAD_LOCAL_VARIABLE_POINTERS, |
| 1847 | | }, |
| 1713 | .{}, |
| 1848 | 1714 | ); |
| 1849 | 1715 | } |
| 1850 | | break :blk self.tlv_ptrs_section_index.?; |
| 1716 | break :blk self.getSectionByName("__TEXT", "__cstring") orelse try self.initSection( |
| 1717 | "__TEXT", |
| 1718 | "__cstring", |
| 1719 | sect.size, |
| 1720 | sect.@"align", |
| 1721 | .{ .flags = macho.S_CSTRING_LITERALS }, |
| 1722 | ); |
| 1851 | 1723 | }, |
| 1852 | | macho.S_THREAD_LOCAL_REGULAR => { |
| 1853 | | if (self.tlv_data_section_index == null) { |
| 1854 | | self.tlv_data_section_index = try self.initSection( |
| 1855 | | self.data_segment_cmd_index.?, |
| 1856 | | "__thread_data", |
| 1857 | | sect.size, |
| 1858 | | sect.@"align", |
| 1859 | | .{ |
| 1860 | | .flags = macho.S_THREAD_LOCAL_REGULAR, |
| 1861 | | }, |
| 1862 | | ); |
| 1863 | | } |
| 1864 | | break :blk self.tlv_data_section_index.?; |
| 1724 | macho.S_MOD_INIT_FUNC_POINTERS, |
| 1725 | macho.S_MOD_TERM_FUNC_POINTERS, |
| 1726 | => { |
| 1727 | break :blk self.getSectionByName("__DATA_CONST", sectname) orelse try self.initSection( |
| 1728 | "__DATA_CONST", |
| 1729 | sectname, |
| 1730 | sect.size, |
| 1731 | sect.@"align", |
| 1732 | .{ .flags = sect.flags }, |
| 1733 | ); |
| 1865 | 1734 | }, |
| 1866 | | macho.S_THREAD_LOCAL_ZEROFILL => { |
| 1867 | | if (self.tlv_bss_section_index == null) { |
| 1868 | | self.tlv_bss_section_index = try self.initSection( |
| 1869 | | self.data_segment_cmd_index.?, |
| 1870 | | "__thread_bss", |
| 1871 | | sect.size, |
| 1872 | | sect.@"align", |
| 1873 | | .{ |
| 1874 | | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| 1875 | | }, |
| 1876 | | ); |
| 1877 | | } |
| 1878 | | break :blk self.tlv_bss_section_index.?; |
| 1735 | macho.S_LITERAL_POINTERS, |
| 1736 | macho.S_ZEROFILL, |
| 1737 | macho.S_THREAD_LOCAL_VARIABLES, |
| 1738 | macho.S_THREAD_LOCAL_VARIABLE_POINTERS, |
| 1739 | macho.S_THREAD_LOCAL_REGULAR, |
| 1740 | macho.S_THREAD_LOCAL_ZEROFILL, |
| 1741 | => { |
| 1742 | break :blk self.getSectionByName(segname, sectname) orelse try self.initSection( |
| 1743 | segname, |
| 1744 | sectname, |
| 1745 | sect.size, |
| 1746 | sect.@"align", |
| 1747 | .{ .flags = sect.flags }, |
| 1748 | ); |
| 1879 | 1749 | }, |
| 1880 | 1750 | macho.S_COALESCED => { |
| 1881 | | if (mem.eql(u8, "__TEXT", segname) and mem.eql(u8, "__eh_frame", sectname)) { |
| 1882 | | // TODO I believe __eh_frame is currently part of __unwind_info section |
| 1883 | | // in the latest ld64 output. |
| 1884 | | if (self.eh_frame_section_index == null) { |
| 1885 | | self.eh_frame_section_index = try self.initSection( |
| 1886 | | self.text_segment_cmd_index.?, |
| 1887 | | "__eh_frame", |
| 1888 | | sect.size, |
| 1889 | | sect.@"align", |
| 1890 | | .{}, |
| 1891 | | ); |
| 1892 | | } |
| 1893 | | break :blk self.eh_frame_section_index.?; |
| 1894 | | } |
| 1895 | | |
| 1896 | | // TODO audit this: is this the right mapping? |
| 1897 | | if (self.data_const_section_index == null) { |
| 1898 | | self.data_const_section_index = try self.initSection( |
| 1899 | | self.data_const_segment_cmd_index.?, |
| 1900 | | "__const", |
| 1901 | | sect.size, |
| 1902 | | sect.@"align", |
| 1903 | | .{}, |
| 1904 | | ); |
| 1905 | | } |
| 1906 | | |
| 1907 | | break :blk self.data_const_section_index.?; |
| 1751 | break :blk self.getSectionByName(segname, sectname) orelse try self.initSection( |
| 1752 | segname, |
| 1753 | sectname, |
| 1754 | sect.size, |
| 1755 | sect.@"align", |
| 1756 | .{}, |
| 1757 | ); |
| 1908 | 1758 | }, |
| 1909 | 1759 | macho.S_REGULAR => { |
| 1910 | | if (sect.isCode()) { |
| 1911 | | if (self.text_section_index == null) { |
| 1912 | | self.text_section_index = try self.initSection( |
| 1913 | | self.text_segment_cmd_index.?, |
| 1914 | | "__text", |
| 1915 | | sect.size, |
| 1916 | | sect.@"align", |
| 1917 | | .{ |
| 1918 | | .flags = macho.S_REGULAR | |
| 1919 | | macho.S_ATTR_PURE_INSTRUCTIONS | |
| 1920 | | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 1921 | | }, |
| 1922 | | ); |
| 1923 | | } |
| 1924 | | break :blk self.text_section_index.?; |
| 1925 | | } |
| 1926 | | if (sect.isDebug()) { |
| 1927 | | // TODO debug attributes |
| 1928 | | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { |
| 1929 | | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ |
| 1930 | | sect.flags, segname, sectname, |
| 1931 | | }); |
| 1932 | | } |
| 1933 | | break :blk null; |
| 1934 | | } |
| 1935 | | |
| 1936 | 1760 | if (mem.eql(u8, segname, "__TEXT")) { |
| 1937 | | if (mem.eql(u8, sectname, "__ustring")) { |
| 1938 | | if (self.ustring_section_index == null) { |
| 1939 | | self.ustring_section_index = try self.initSection( |
| 1940 | | self.text_segment_cmd_index.?, |
| 1941 | | "__ustring", |
| 1942 | | sect.size, |
| 1943 | | sect.@"align", |
| 1944 | | .{}, |
| 1945 | | ); |
| 1946 | | } |
| 1947 | | break :blk self.ustring_section_index.?; |
| 1948 | | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { |
| 1949 | | if (self.gcc_except_tab_section_index == null) { |
| 1950 | | self.gcc_except_tab_section_index = try self.initSection( |
| 1951 | | self.text_segment_cmd_index.?, |
| 1952 | | "__gcc_except_tab", |
| 1953 | | sect.size, |
| 1954 | | sect.@"align", |
| 1955 | | .{}, |
| 1956 | | ); |
| 1957 | | } |
| 1958 | | break :blk self.gcc_except_tab_section_index.?; |
| 1959 | | } else if (mem.eql(u8, sectname, "__objc_methlist")) { |
| 1960 | | if (self.objc_methlist_section_index == null) { |
| 1961 | | self.objc_methlist_section_index = try self.initSection( |
| 1962 | | self.text_segment_cmd_index.?, |
| 1963 | | "__objc_methlist", |
| 1964 | | sect.size, |
| 1965 | | sect.@"align", |
| 1966 | | .{}, |
| 1967 | | ); |
| 1968 | | } |
| 1969 | | break :blk self.objc_methlist_section_index.?; |
| 1970 | | } else if (mem.eql(u8, sectname, "__rodata") or |
| 1761 | if (mem.eql(u8, sectname, "__rodata") or |
| 1971 | 1762 | mem.eql(u8, sectname, "__typelink") or |
| 1972 | 1763 | mem.eql(u8, sectname, "__itablink") or |
| 1973 | 1764 | mem.eql(u8, sectname, "__gosymtab") or |
| 1974 | 1765 | mem.eql(u8, sectname, "__gopclntab")) |
| 1975 | 1766 | { |
| 1976 | | if (self.data_const_section_index == null) { |
| 1977 | | self.data_const_section_index = try self.initSection( |
| 1978 | | self.data_const_segment_cmd_index.?, |
| 1979 | | "__const", |
| 1980 | | sect.size, |
| 1981 | | sect.@"align", |
| 1982 | | .{}, |
| 1983 | | ); |
| 1984 | | } |
| 1985 | | break :blk self.data_const_section_index.?; |
| 1986 | | } else { |
| 1987 | | if (self.text_const_section_index == null) { |
| 1988 | | self.text_const_section_index = try self.initSection( |
| 1989 | | self.text_segment_cmd_index.?, |
| 1990 | | "__const", |
| 1991 | | sect.size, |
| 1992 | | sect.@"align", |
| 1993 | | .{}, |
| 1994 | | ); |
| 1995 | | } |
| 1996 | | break :blk self.text_const_section_index.?; |
| 1997 | | } |
| 1998 | | } |
| 1999 | | |
| 2000 | | if (mem.eql(u8, segname, "__DATA_CONST")) { |
| 2001 | | if (self.data_const_section_index == null) { |
| 2002 | | self.data_const_section_index = try self.initSection( |
| 2003 | | self.data_const_segment_cmd_index.?, |
| 1767 | break :blk self.getSectionByName("__DATA_CONST", "__const") orelse try self.initSection( |
| 1768 | "__DATA_CONST", |
| 2004 | 1769 | "__const", |
| 2005 | 1770 | sect.size, |
| 2006 | 1771 | sect.@"align", |
| 2007 | 1772 | .{}, |
| 2008 | 1773 | ); |
| 2009 | 1774 | } |
| 2010 | | break :blk self.data_const_section_index.?; |
| 2011 | 1775 | } |
| 2012 | | |
| 2013 | 1776 | if (mem.eql(u8, segname, "__DATA")) { |
| 2014 | | if (mem.eql(u8, sectname, "__const")) { |
| 2015 | | if (self.data_const_section_index == null) { |
| 2016 | | self.data_const_section_index = try self.initSection( |
| 2017 | | self.data_const_segment_cmd_index.?, |
| 2018 | | "__const", |
| 2019 | | sect.size, |
| 2020 | | sect.@"align", |
| 2021 | | .{}, |
| 2022 | | ); |
| 2023 | | } |
| 2024 | | break :blk self.data_const_section_index.?; |
| 2025 | | } else if (mem.eql(u8, sectname, "__cfstring")) { |
| 2026 | | if (self.objc_cfstring_section_index == null) { |
| 2027 | | self.objc_cfstring_section_index = try self.initSection( |
| 2028 | | self.data_const_segment_cmd_index.?, |
| 2029 | | "__cfstring", |
| 2030 | | sect.size, |
| 2031 | | sect.@"align", |
| 2032 | | .{}, |
| 2033 | | ); |
| 2034 | | } |
| 2035 | | break :blk self.objc_cfstring_section_index.?; |
| 2036 | | } else if (mem.eql(u8, sectname, "__objc_classlist")) { |
| 2037 | | if (self.objc_classlist_section_index == null) { |
| 2038 | | self.objc_classlist_section_index = try self.initSection( |
| 2039 | | self.data_const_segment_cmd_index.?, |
| 2040 | | "__objc_classlist", |
| 2041 | | sect.size, |
| 2042 | | sect.@"align", |
| 2043 | | .{}, |
| 2044 | | ); |
| 2045 | | } |
| 2046 | | break :blk self.objc_classlist_section_index.?; |
| 2047 | | } else if (mem.eql(u8, sectname, "__objc_imageinfo")) { |
| 2048 | | if (self.objc_imageinfo_section_index == null) { |
| 2049 | | self.objc_imageinfo_section_index = try self.initSection( |
| 2050 | | self.data_const_segment_cmd_index.?, |
| 2051 | | "__objc_imageinfo", |
| 2052 | | sect.size, |
| 2053 | | sect.@"align", |
| 2054 | | .{}, |
| 2055 | | ); |
| 2056 | | } |
| 2057 | | break :blk self.objc_imageinfo_section_index.?; |
| 2058 | | } else if (mem.eql(u8, sectname, "__objc_const")) { |
| 2059 | | if (self.objc_const_section_index == null) { |
| 2060 | | self.objc_const_section_index = try self.initSection( |
| 2061 | | self.data_segment_cmd_index.?, |
| 2062 | | "__objc_const", |
| 2063 | | sect.size, |
| 2064 | | sect.@"align", |
| 2065 | | .{}, |
| 2066 | | ); |
| 2067 | | } |
| 2068 | | break :blk self.objc_const_section_index.?; |
| 2069 | | } else if (mem.eql(u8, sectname, "__objc_classrefs")) { |
| 2070 | | if (self.objc_classrefs_section_index == null) { |
| 2071 | | self.objc_classrefs_section_index = try self.initSection( |
| 2072 | | self.data_segment_cmd_index.?, |
| 2073 | | "__objc_classrefs", |
| 2074 | | sect.size, |
| 2075 | | sect.@"align", |
| 2076 | | .{}, |
| 2077 | | ); |
| 2078 | | } |
| 2079 | | break :blk self.objc_classrefs_section_index.?; |
| 2080 | | } else if (mem.eql(u8, sectname, "__objc_data")) { |
| 2081 | | if (self.objc_data_section_index == null) { |
| 2082 | | self.objc_data_section_index = try self.initSection( |
| 2083 | | self.data_segment_cmd_index.?, |
| 2084 | | "__objc_data", |
| 2085 | | sect.size, |
| 2086 | | sect.@"align", |
| 2087 | | .{}, |
| 2088 | | ); |
| 2089 | | } |
| 2090 | | break :blk self.objc_data_section_index.?; |
| 2091 | | } else if (mem.eql(u8, sectname, ".rustc")) { |
| 2092 | | if (self.rustc_section_index == null) { |
| 2093 | | self.rustc_section_index = try self.initSection( |
| 2094 | | self.data_segment_cmd_index.?, |
| 2095 | | ".rustc", |
| 2096 | | sect.size, |
| 2097 | | sect.@"align", |
| 2098 | | .{}, |
| 2099 | | ); |
| 2100 | | // We need to preserve the section size for rustc to properly |
| 2101 | | // decompress the metadata. |
| 2102 | | self.rustc_section_size = sect.size; |
| 2103 | | } |
| 2104 | | break :blk self.rustc_section_index.?; |
| 2105 | | } else { |
| 1777 | if (mem.eql(u8, sectname, "__const") or |
| 1778 | mem.eql(u8, sectname, "__cfstring") or |
| 1779 | mem.eql(u8, sectname, "__objc_classlist") or |
| 1780 | mem.eql(u8, sectname, "__objc_imageinfo")) |
| 1781 | { |
| 1782 | break :blk self.getSectionByName("__DATA_CONST", sectname) orelse |
| 1783 | try self.initSection( |
| 1784 | "__DATA_CONST", |
| 1785 | sectname, |
| 1786 | sect.size, |
| 1787 | sect.@"align", |
| 1788 | .{}, |
| 1789 | ); |
| 1790 | } else if (mem.eql(u8, sectname, "__data")) { |
| 2106 | 1791 | if (self.data_section_index == null) { |
| 2107 | 1792 | self.data_section_index = try self.initSection( |
| 2108 | | self.data_segment_cmd_index.?, |
| 2109 | | "__data", |
| 1793 | segname, |
| 1794 | sectname, |
| 2110 | 1795 | sect.size, |
| 2111 | 1796 | sect.@"align", |
| 2112 | 1797 | .{}, |
| ... | ... | @@ -2115,14 +1800,13 @@ pub fn getOutputSection(self: *MachO, sect: macho.section_64) !?u8 { |
| 2115 | 1800 | break :blk self.data_section_index.?; |
| 2116 | 1801 | } |
| 2117 | 1802 | } |
| 2118 | | |
| 2119 | | if (mem.eql(u8, "__LLVM", segname) and mem.eql(u8, "__asm", sectname)) { |
| 2120 | | log.debug("TODO LLVM asm section: type 0x{x}, name '{s},{s}'", .{ |
| 2121 | | sect.flags, segname, sectname, |
| 2122 | | }); |
| 2123 | | } |
| 2124 | | |
| 2125 | | break :blk null; |
| 1803 | break :blk self.getSectionByName(segname, sectname) orelse try self.initSection( |
| 1804 | segname, |
| 1805 | sectname, |
| 1806 | sect.size, |
| 1807 | sect.@"align", |
| 1808 | .{}, |
| 1809 | ); |
| 2126 | 1810 | }, |
| 2127 | 1811 | else => break :blk null, |
| 2128 | 1812 | } |
| ... | ... | @@ -2774,11 +2458,16 @@ fn createTentativeDefAtoms(self: *MachO) !void { |
| 2774 | 2458 | // text blocks for each tentative definition. |
| 2775 | 2459 | const size = sym.n_value; |
| 2776 | 2460 | const alignment = (sym.n_desc >> 8) & 0x0f; |
| 2461 | const n_sect = (try self.getOutputSection(.{ |
| 2462 | .segname = makeStaticString("__DATA"), |
| 2463 | .sectname = makeStaticString("__bss"), |
| 2464 | .flags = macho.S_ZEROFILL, |
| 2465 | })).?; |
| 2777 | 2466 | |
| 2778 | 2467 | sym.* = .{ |
| 2779 | 2468 | .n_strx = sym.n_strx, |
| 2780 | 2469 | .n_type = macho.N_SECT | macho.N_EXT, |
| 2781 | | .n_sect = 0, |
| 2470 | .n_sect = n_sect, |
| 2782 | 2471 | .n_desc = 0, |
| 2783 | 2472 | .n_value = 0, |
| 2784 | 2473 | }; |
| ... | ... | @@ -2786,7 +2475,7 @@ fn createTentativeDefAtoms(self: *MachO) !void { |
| 2786 | 2475 | const atom = try MachO.createEmptyAtom(gpa, global.sym_index, size, alignment); |
| 2787 | 2476 | atom.file = global.file; |
| 2788 | 2477 | |
| 2789 | | try self.allocateAtomCommon(atom, self.bss_section_index.?); |
| 2478 | try self.allocateAtomCommon(atom, n_sect); |
| 2790 | 2479 | |
| 2791 | 2480 | if (global.file) |file| { |
| 2792 | 2481 | const object = &self.objects.items[file]; |
| ... | ... | @@ -4174,7 +3863,8 @@ pub fn deleteExport(self: *MachO, exp: Export) void { |
| 4174 | 3863 | fn freeUnnamedConsts(self: *MachO, decl_index: Module.Decl.Index) void { |
| 4175 | 3864 | const unnamed_consts = self.unnamed_const_atoms.getPtr(decl_index) orelse return; |
| 4176 | 3865 | for (unnamed_consts.items) |atom| { |
| 4177 | | self.freeAtom(atom, self.text_const_section_index.?, true); |
| 3866 | const sect_id = atom.getSymbol(self).n_sect; |
| 3867 | self.freeAtom(atom, sect_id, true); |
| 4178 | 3868 | self.locals_free_list.append(self.base.allocator, atom.sym_index) catch {}; |
| 4179 | 3869 | self.locals.items[atom.sym_index].n_type = 0; |
| 4180 | 3870 | _ = self.atom_by_index_table.remove(atom.sym_index); |
| ... | ... | @@ -4307,7 +3997,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4307 | 3997 | }; |
| 4308 | 3998 | const needed_size = if (self.mode == .incremental) self.base.options.program_code_size_hint else 0; |
| 4309 | 3999 | self.text_section_index = try self.initSection( |
| 4310 | | self.text_segment_cmd_index.?, |
| 4000 | "__TEXT", |
| 4311 | 4001 | "__text", |
| 4312 | 4002 | needed_size, |
| 4313 | 4003 | alignment, |
| ... | ... | @@ -4330,7 +4020,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4330 | 4020 | }; |
| 4331 | 4021 | const needed_size = if (self.mode == .incremental) stub_size * self.base.options.symbol_count_hint else 0; |
| 4332 | 4022 | self.stubs_section_index = try self.initSection( |
| 4333 | | self.text_segment_cmd_index.?, |
| 4023 | "__TEXT", |
| 4334 | 4024 | "__stubs", |
| 4335 | 4025 | needed_size, |
| 4336 | 4026 | alignment, |
| ... | ... | @@ -4362,7 +4052,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4362 | 4052 | else |
| 4363 | 4053 | 0; |
| 4364 | 4054 | self.stub_helper_section_index = try self.initSection( |
| 4365 | | self.text_segment_cmd_index.?, |
| 4055 | "__TEXT", |
| 4366 | 4056 | "__stub_helper", |
| 4367 | 4057 | needed_size, |
| 4368 | 4058 | alignment, |
| ... | ... | @@ -4407,7 +4097,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4407 | 4097 | 0; |
| 4408 | 4098 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4409 | 4099 | self.got_section_index = try self.initSection( |
| 4410 | | self.data_const_segment_cmd_index.?, |
| 4100 | "__DATA_CONST", |
| 4411 | 4101 | "__got", |
| 4412 | 4102 | needed_size, |
| 4413 | 4103 | alignment, |
| ... | ... | @@ -4452,7 +4142,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4452 | 4142 | 0; |
| 4453 | 4143 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4454 | 4144 | self.la_symbol_ptr_section_index = try self.initSection( |
| 4455 | | self.data_segment_cmd_index.?, |
| 4145 | "__DATA", |
| 4456 | 4146 | "__la_symbol_ptr", |
| 4457 | 4147 | needed_size, |
| 4458 | 4148 | alignment, |
| ... | ... | @@ -4469,7 +4159,7 @@ fn populateMissingMetadata(self: *MachO) !void { |
| 4469 | 4159 | 0; |
| 4470 | 4160 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4471 | 4161 | self.data_section_index = try self.initSection( |
| 4472 | | self.data_segment_cmd_index.?, |
| 4162 | "__DATA", |
| 4473 | 4163 | "__data", |
| 4474 | 4164 | needed_size, |
| 4475 | 4165 | alignment, |
| ... | ... | @@ -4701,12 +4391,13 @@ const InitSectionOpts = struct { |
| 4701 | 4391 | |
| 4702 | 4392 | fn initSection( |
| 4703 | 4393 | self: *MachO, |
| 4704 | | segment_id: u8, |
| 4394 | segname: []const u8, |
| 4705 | 4395 | sectname: []const u8, |
| 4706 | 4396 | size: u64, |
| 4707 | 4397 | alignment: u32, |
| 4708 | 4398 | opts: InitSectionOpts, |
| 4709 | 4399 | ) !u8 { |
| 4400 | const segment_id = self.getSegmentByName(segname).?; |
| 4710 | 4401 | const seg = &self.segments.items[segment_id]; |
| 4711 | 4402 | const index = try self.insertSection(segment_id, .{ |
| 4712 | 4403 | .sectname = makeStaticString(sectname), |
| ... | ... | @@ -4779,42 +4470,13 @@ fn insertSection(self: *MachO, segment_index: u8, header: macho.section_64) !u8 |
| 4779 | 4470 | header.sectName(), |
| 4780 | 4471 | insertion_index, |
| 4781 | 4472 | }); |
| 4782 | | // TODO slim it down |
| 4783 | 4473 | for (&[_]*?u8{ |
| 4784 | | // __TEXT |
| 4785 | 4474 | &self.text_section_index, |
| 4786 | 4475 | &self.stubs_section_index, |
| 4787 | 4476 | &self.stub_helper_section_index, |
| 4788 | | &self.gcc_except_tab_section_index, |
| 4789 | | &self.cstring_section_index, |
| 4790 | | &self.ustring_section_index, |
| 4791 | | &self.text_const_section_index, |
| 4792 | | &self.objc_methlist_section_index, |
| 4793 | | &self.objc_methname_section_index, |
| 4794 | | &self.objc_methtype_section_index, |
| 4795 | | &self.objc_classname_section_index, |
| 4796 | | &self.eh_frame_section_index, |
| 4797 | | // __DATA_CONST |
| 4798 | 4477 | &self.got_section_index, |
| 4799 | | &self.mod_init_func_section_index, |
| 4800 | | &self.mod_term_func_section_index, |
| 4801 | | &self.data_const_section_index, |
| 4802 | | &self.objc_cfstring_section_index, |
| 4803 | | &self.objc_classlist_section_index, |
| 4804 | | &self.objc_imageinfo_section_index, |
| 4805 | | // __DATA |
| 4806 | | &self.rustc_section_index, |
| 4807 | 4478 | &self.la_symbol_ptr_section_index, |
| 4808 | | &self.objc_const_section_index, |
| 4809 | | &self.objc_selrefs_section_index, |
| 4810 | | &self.objc_classrefs_section_index, |
| 4811 | | &self.objc_data_section_index, |
| 4812 | 4479 | &self.data_section_index, |
| 4813 | | &self.tlv_section_index, |
| 4814 | | &self.tlv_ptrs_section_index, |
| 4815 | | &self.tlv_data_section_index, |
| 4816 | | &self.tlv_bss_section_index, |
| 4817 | | &self.bss_section_index, |
| 4818 | 4480 | }) |maybe_index| { |
| 4819 | 4481 | const index = maybe_index.* orelse continue; |
| 4820 | 4482 | if (insertion_index <= index) maybe_index.* = index + 1; |
| ... | ... | @@ -6017,7 +5679,7 @@ fn writeHeader(self: *MachO, ncmds: u32, sizeofcmds: u32) !void { |
| 6017 | 5679 | else => unreachable, |
| 6018 | 5680 | } |
| 6019 | 5681 | |
| 6020 | | if (self.tlv_section_index) |_| { |
| 5682 | if (self.getSectionByName("__DATA", "__thread_vars")) |_| { |
| 6021 | 5683 | header.flags |= macho.MH_HAS_TLV_DESCRIPTORS; |
| 6022 | 5684 | } |
| 6023 | 5685 | |
| ... | ... | @@ -6042,6 +5704,20 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| 6042 | 5704 | return buf; |
| 6043 | 5705 | } |
| 6044 | 5706 | |
| 5707 | fn getSegmentByName(self: MachO, segname: []const u8) ?u8 { |
| 5708 | for (self.segments.items) |seg, i| { |
| 5709 | if (mem.eql(u8, segname, seg.segName())) return @intCast(u8, i); |
| 5710 | } else return null; |
| 5711 | } |
| 5712 | |
| 5713 | pub fn getSectionByName(self: MachO, segname: []const u8, sectname: []const u8) ?u8 { |
| 5714 | // TODO investigate caching with a hashmap |
| 5715 | for (self.sections.items(.header)) |header, i| { |
| 5716 | if (mem.eql(u8, header.segName(), segname) and mem.eql(u8, header.sectName(), sectname)) |
| 5717 | return @intCast(u8, i); |
| 5718 | } else return null; |
| 5719 | } |
| 5720 | |
| 6045 | 5721 | fn getSectionIndexes(self: MachO, segment_index: u8) struct { start: u8, end: u8 } { |
| 6046 | 5722 | var start: u8 = 0; |
| 6047 | 5723 | const nsects = for (self.segments.items) |seg, i| { |