authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-21 11:11:19+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-24 18:53:42+02:00
log852e1ed23cb5cfdb687a52c39fa9c60be3159730
tree2ba86d658697c66801b3f0fe6951e6288a110b4c
parent72f2f68938d626299e2bb5aa3b8932a45d4ae778

zld+stage2: refactor creating segments and sections

Move the logic into default-init structs part of constructors in `SegmentCommand` struct in `commands.zig` module.

5 files changed, 172 insertions(+), 544 deletions(-)

src/link/MachO.zig+11-94
...@@ -1779,18 +1779,8 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1779,18 +1779,8 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1779 if (self.pagezero_segment_cmd_index == null) {1779 if (self.pagezero_segment_cmd_index == null) {
1780 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);1780 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
1781 try self.load_commands.append(self.base.allocator, .{1781 try self.load_commands.append(self.base.allocator, .{
1782 .Segment = SegmentCommand.empty(.{1782 .Segment = SegmentCommand.empty("__PAGEZERO", .{
1783 .cmd = macho.LC_SEGMENT_64,
1784 .cmdsize = @sizeOf(macho.segment_command_64),
1785 .segname = makeStaticString("__PAGEZERO"),
1786 .vmaddr = 0,
1787 .vmsize = 0x100000000, // size always set to 4GB1783 .vmsize = 0x100000000, // size always set to 4GB
1788 .fileoff = 0,
1789 .filesize = 0,
1790 .maxprot = 0,
1791 .initprot = 0,
1792 .nsects = 0,
1793 .flags = 0,
1794 }),1784 }),
1795 });1785 });
1796 self.header_dirty = true;1786 self.header_dirty = true;
...@@ -1809,18 +1799,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1809,18 +1799,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1809 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });1799 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });
18101800
1811 try self.load_commands.append(self.base.allocator, .{1801 try self.load_commands.append(self.base.allocator, .{
1812 .Segment = SegmentCommand.empty(.{1802 .Segment = SegmentCommand.empty("__TEXT", .{
1813 .cmd = macho.LC_SEGMENT_64,
1814 .cmdsize = @sizeOf(macho.segment_command_64),
1815 .segname = makeStaticString("__TEXT"),
1816 .vmaddr = 0x100000000, // always starts at 4GB1803 .vmaddr = 0x100000000, // always starts at 4GB
1817 .vmsize = needed_size,1804 .vmsize = needed_size,
1818 .fileoff = 0,
1819 .filesize = needed_size,1805 .filesize = needed_size,
1820 .maxprot = maxprot,1806 .maxprot = maxprot,
1821 .initprot = initprot,1807 .initprot = initprot,
1822 .nsects = 0,
1823 .flags = 0,
1824 }),1808 }),
1825 });1809 });
1826 self.header_dirty = true;1810 self.header_dirty = true;
...@@ -1841,19 +1825,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1841,19 +1825,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
18411825
1842 log.debug("found __text section free space 0x{x} to 0x{x}", .{ off, off + needed_size });1826 log.debug("found __text section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
18431827
1844 try text_segment.addSection(self.base.allocator, .{1828 try text_segment.addSection(self.base.allocator, "__text", "__TEXT", .{
1845 .sectname = makeStaticString("__text"),
1846 .segname = makeStaticString("__TEXT"),
1847 .addr = text_segment.inner.vmaddr + off,1829 .addr = text_segment.inner.vmaddr + off,
1848 .size = @intCast(u32, needed_size),1830 .size = @intCast(u32, needed_size),
1849 .offset = @intCast(u32, off),1831 .offset = @intCast(u32, off),
1850 .@"align" = alignment,1832 .@"align" = alignment,
1851 .reloff = 0,
1852 .nreloc = 0,
1853 .flags = flags,1833 .flags = flags,
1854 .reserved1 = 0,
1855 .reserved2 = 0,
1856 .reserved3 = 0,
1857 });1834 });
1858 self.header_dirty = true;1835 self.header_dirty = true;
1859 self.load_commands_dirty = true;1836 self.load_commands_dirty = true;
...@@ -1879,19 +1856,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1879,19 +1856,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
18791856
1880 log.debug("found __stubs section free space 0x{x} to 0x{x}", .{ off, off + needed_size });1857 log.debug("found __stubs section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
18811858
1882 try text_segment.addSection(self.base.allocator, .{1859 try text_segment.addSection(self.base.allocator, "__stubs", "__TEXT", .{
1883 .sectname = makeStaticString("__stubs"),
1884 .segname = makeStaticString("__TEXT"),
1885 .addr = text_segment.inner.vmaddr + off,1860 .addr = text_segment.inner.vmaddr + off,
1886 .size = needed_size,1861 .size = needed_size,
1887 .offset = @intCast(u32, off),1862 .offset = @intCast(u32, off),
1888 .@"align" = alignment,1863 .@"align" = alignment,
1889 .reloff = 0,
1890 .nreloc = 0,
1891 .flags = flags,1864 .flags = flags,
1892 .reserved1 = 0,
1893 .reserved2 = stub_size,1865 .reserved2 = stub_size,
1894 .reserved3 = 0,
1895 });1866 });
1896 self.header_dirty = true;1867 self.header_dirty = true;
1897 self.load_commands_dirty = true;1868 self.load_commands_dirty = true;
...@@ -1912,19 +1883,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1912,19 +1883,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
19121883
1913 log.debug("found __stub_helper section free space 0x{x} to 0x{x}", .{ off, off + needed_size });1884 log.debug("found __stub_helper section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
19141885
1915 try text_segment.addSection(self.base.allocator, .{1886 try text_segment.addSection(self.base.allocator, "__stub_helper", "__TEXT", .{
1916 .sectname = makeStaticString("__stub_helper"),
1917 .segname = makeStaticString("__TEXT"),
1918 .addr = text_segment.inner.vmaddr + off,1887 .addr = text_segment.inner.vmaddr + off,
1919 .size = needed_size,1888 .size = needed_size,
1920 .offset = @intCast(u32, off),1889 .offset = @intCast(u32, off),
1921 .@"align" = alignment,1890 .@"align" = alignment,
1922 .reloff = 0,
1923 .nreloc = 0,
1924 .flags = flags,1891 .flags = flags,
1925 .reserved1 = 0,
1926 .reserved2 = 0,
1927 .reserved3 = 0,
1928 });1892 });
1929 self.header_dirty = true;1893 self.header_dirty = true;
1930 self.load_commands_dirty = true;1894 self.load_commands_dirty = true;
...@@ -1941,18 +1905,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1941,18 +1905,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1941 log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });1905 log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
19421906
1943 try self.load_commands.append(self.base.allocator, .{1907 try self.load_commands.append(self.base.allocator, .{
1944 .Segment = SegmentCommand.empty(.{1908 .Segment = SegmentCommand.empty("__DATA_CONST", .{
1945 .cmd = macho.LC_SEGMENT_64,
1946 .cmdsize = @sizeOf(macho.segment_command_64),
1947 .segname = makeStaticString("__DATA_CONST"),
1948 .vmaddr = address_and_offset.address,1909 .vmaddr = address_and_offset.address,
1949 .vmsize = needed_size,1910 .vmsize = needed_size,
1950 .fileoff = address_and_offset.offset,1911 .fileoff = address_and_offset.offset,
1951 .filesize = needed_size,1912 .filesize = needed_size,
1952 .maxprot = maxprot,1913 .maxprot = maxprot,
1953 .initprot = initprot,1914 .initprot = initprot,
1954 .nsects = 0,
1955 .flags = 0,
1956 }),1915 }),
1957 });1916 });
1958 self.header_dirty = true;1917 self.header_dirty = true;
...@@ -1969,19 +1928,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1969,19 +1928,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
19691928
1970 log.debug("found __got section free space 0x{x} to 0x{x}", .{ off, off + needed_size });1929 log.debug("found __got section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
19711930
1972 try dc_segment.addSection(self.base.allocator, .{1931 try dc_segment.addSection(self.base.allocator, "__got", "__DATA_CONST", .{
1973 .sectname = makeStaticString("__got"),
1974 .segname = makeStaticString("__DATA_CONST"),
1975 .addr = dc_segment.inner.vmaddr + off - dc_segment.inner.fileoff,1932 .addr = dc_segment.inner.vmaddr + off - dc_segment.inner.fileoff,
1976 .size = needed_size,1933 .size = needed_size,
1977 .offset = @intCast(u32, off),1934 .offset = @intCast(u32, off),
1978 .@"align" = 3, // 2^3 = @sizeOf(u64)1935 .@"align" = 3, // 2^3 = @sizeOf(u64)
1979 .reloff = 0,
1980 .nreloc = 0,
1981 .flags = flags,1936 .flags = flags,
1982 .reserved1 = 0,
1983 .reserved2 = 0,
1984 .reserved3 = 0,
1985 });1937 });
1986 self.header_dirty = true;1938 self.header_dirty = true;
1987 self.load_commands_dirty = true;1939 self.load_commands_dirty = true;
...@@ -1998,18 +1950,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -1998,18 +1950,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
1998 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });1950 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
19991951
2000 try self.load_commands.append(self.base.allocator, .{1952 try self.load_commands.append(self.base.allocator, .{
2001 .Segment = SegmentCommand.empty(.{1953 .Segment = SegmentCommand.empty("__DATA", .{
2002 .cmd = macho.LC_SEGMENT_64,
2003 .cmdsize = @sizeOf(macho.segment_command_64),
2004 .segname = makeStaticString("__DATA"),
2005 .vmaddr = address_and_offset.address,1954 .vmaddr = address_and_offset.address,
2006 .vmsize = needed_size,1955 .vmsize = needed_size,
2007 .fileoff = address_and_offset.offset,1956 .fileoff = address_and_offset.offset,
2008 .filesize = needed_size,1957 .filesize = needed_size,
2009 .maxprot = maxprot,1958 .maxprot = maxprot,
2010 .initprot = initprot,1959 .initprot = initprot,
2011 .nsects = 0,
2012 .flags = 0,
2013 }),1960 }),
2014 });1961 });
2015 self.header_dirty = true;1962 self.header_dirty = true;
...@@ -2026,19 +1973,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -2026,19 +1973,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
20261973
2027 log.debug("found __la_symbol_ptr section free space 0x{x} to 0x{x}", .{ off, off + needed_size });1974 log.debug("found __la_symbol_ptr section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
20281975
2029 try data_segment.addSection(self.base.allocator, .{1976 try data_segment.addSection(self.base.allocator, "__la_symbol_ptr", "__DATA", .{
2030 .sectname = makeStaticString("__la_symbol_ptr"),
2031 .segname = makeStaticString("__DATA"),
2032 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,1977 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
2033 .size = needed_size,1978 .size = needed_size,
2034 .offset = @intCast(u32, off),1979 .offset = @intCast(u32, off),
2035 .@"align" = 3, // 2^3 = @sizeOf(u64)1980 .@"align" = 3, // 2^3 = @sizeOf(u64)
2036 .reloff = 0,
2037 .nreloc = 0,
2038 .flags = flags,1981 .flags = flags,
2039 .reserved1 = 0,
2040 .reserved2 = 0,
2041 .reserved3 = 0,
2042 });1982 });
2043 self.header_dirty = true;1983 self.header_dirty = true;
2044 self.load_commands_dirty = true;1984 self.load_commands_dirty = true;
...@@ -2047,26 +1987,17 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -2047,26 +1987,17 @@ pub fn populateMissingMetadata(self: *MachO) !void {
2047 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;1987 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2048 self.data_section_index = @intCast(u16, data_segment.sections.items.len);1988 self.data_section_index = @intCast(u16, data_segment.sections.items.len);
20491989
2050 const flags = macho.S_REGULAR;
2051 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;1990 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
2052 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);1991 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
2053 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.1992 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
20541993
2055 log.debug("found __data section free space 0x{x} to 0x{x}", .{ off, off + needed_size });1994 log.debug("found __data section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
20561995
2057 try data_segment.addSection(self.base.allocator, .{1996 try data_segment.addSection(self.base.allocator, "__data", "__DATA", .{
2058 .sectname = makeStaticString("__data"),
2059 .segname = makeStaticString("__DATA"),
2060 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,1997 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
2061 .size = needed_size,1998 .size = needed_size,
2062 .offset = @intCast(u32, off),1999 .offset = @intCast(u32, off),
2063 .@"align" = 3, // 2^3 = @sizeOf(u64)2000 .@"align" = 3, // 2^3 = @sizeOf(u64)
2064 .reloff = 0,
2065 .nreloc = 0,
2066 .flags = flags,
2067 .reserved1 = 0,
2068 .reserved2 = 0,
2069 .reserved3 = 0,
2070 });2001 });
2071 self.header_dirty = true;2002 self.header_dirty = true;
2072 self.load_commands_dirty = true;2003 self.load_commands_dirty = true;
...@@ -2081,18 +2012,11 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -2081,18 +2012,11 @@ pub fn populateMissingMetadata(self: *MachO) !void {
2081 log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset});2012 log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset});
20822013
2083 try self.load_commands.append(self.base.allocator, .{2014 try self.load_commands.append(self.base.allocator, .{
2084 .Segment = SegmentCommand.empty(.{2015 .Segment = SegmentCommand.empty("__LINKEDIT", .{
2085 .cmd = macho.LC_SEGMENT_64,
2086 .cmdsize = @sizeOf(macho.segment_command_64),
2087 .segname = makeStaticString("__LINKEDIT"),
2088 .vmaddr = address_and_offset.address,2016 .vmaddr = address_and_offset.address,
2089 .vmsize = 0,
2090 .fileoff = address_and_offset.offset,2017 .fileoff = address_and_offset.offset,
2091 .filesize = 0,
2092 .maxprot = maxprot,2018 .maxprot = maxprot,
2093 .initprot = initprot,2019 .initprot = initprot,
2094 .nsects = 0,
2095 .flags = 0,
2096 }),2020 }),
2097 });2021 });
2098 self.header_dirty = true;2022 self.header_dirty = true;
...@@ -2450,13 +2374,6 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,...@@ -2450,13 +2374,6 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
2450 return vaddr;2374 return vaddr;
2451}2375}
24522376
2453pub fn makeStaticString(comptime bytes: []const u8) [16]u8 {
2454 var buf = [_]u8{0} ** 16;
2455 if (bytes.len > buf.len) @compileError("string too long; max 16 bytes");
2456 mem.copy(u8, &buf, bytes);
2457 return buf;
2458}
2459
2460fn makeString(self: *MachO, bytes: []const u8) !u32 {2377fn makeString(self: *MachO, bytes: []const u8) !u32 {
2461 if (self.string_table_directory.get(bytes)) |offset| {2378 if (self.string_table_directory.get(bytes)) |offset| {
2462 log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset });2379 log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset });
src/link/MachO/DebugSymbols.zig+7-59
...@@ -19,7 +19,6 @@ const MachO = @import("../MachO.zig");...@@ -19,7 +19,6 @@ const MachO = @import("../MachO.zig");
19const SrcFn = MachO.SrcFn;19const SrcFn = MachO.SrcFn;
20const TextBlock = MachO.TextBlock;20const TextBlock = MachO.TextBlock;
21const padToIdeal = MachO.padToIdeal;21const padToIdeal = MachO.padToIdeal;
22const makeStaticString = MachO.makeStaticString;
2322
24usingnamespace @import("commands.zig");23usingnamespace @import("commands.zig");
2524
...@@ -212,18 +211,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -212,18 +211,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
212 log.debug("found dSym __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });211 log.debug("found dSym __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });
213212
214 try self.load_commands.append(allocator, .{213 try self.load_commands.append(allocator, .{
215 .Segment = SegmentCommand.empty(.{214 .Segment = SegmentCommand.empty("__DWARF", .{
216 .cmd = macho.LC_SEGMENT_64,
217 .cmdsize = @sizeOf(macho.segment_command_64),
218 .segname = makeStaticString("__DWARF"),
219 .vmaddr = vmaddr,215 .vmaddr = vmaddr,
220 .vmsize = needed_size,216 .vmsize = needed_size,
221 .fileoff = off,217 .fileoff = off,
222 .filesize = needed_size,218 .filesize = needed_size,
223 .maxprot = 0,
224 .initprot = 0,
225 .nsects = 0,
226 .flags = 0,
227 }),219 }),
228 });220 });
229 self.header_dirty = true;221 self.header_dirty = true;
...@@ -234,19 +226,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -234,19 +226,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
234 self.debug_str_section_index = @intCast(u16, dwarf_segment.sections.items.len);226 self.debug_str_section_index = @intCast(u16, dwarf_segment.sections.items.len);
235 assert(self.debug_string_table.items.len == 0);227 assert(self.debug_string_table.items.len == 0);
236228
237 try dwarf_segment.addSection(allocator, .{229 try dwarf_segment.addSection(allocator, "__debug_str", "__DWARF", .{
238 .sectname = makeStaticString("__debug_str"),
239 .segname = makeStaticString("__DWARF"),
240 .addr = dwarf_segment.inner.vmaddr,230 .addr = dwarf_segment.inner.vmaddr,
241 .size = @intCast(u32, self.debug_string_table.items.len),231 .size = @intCast(u32, self.debug_string_table.items.len),
242 .offset = @intCast(u32, dwarf_segment.inner.fileoff),232 .offset = @intCast(u32, dwarf_segment.inner.fileoff),
243 .@"align" = 1,233 .@"align" = 1,
244 .reloff = 0,
245 .nreloc = 0,
246 .flags = macho.S_REGULAR,
247 .reserved1 = 0,
248 .reserved2 = 0,
249 .reserved3 = 0,
250 });234 });
251 self.header_dirty = true;235 self.header_dirty = true;
252 self.load_commands_dirty = true;236 self.load_commands_dirty = true;
...@@ -262,19 +246,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -262,19 +246,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
262246
263 log.debug("found dSym __debug_info free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });247 log.debug("found dSym __debug_info free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
264248
265 try dwarf_segment.addSection(allocator, .{249 try dwarf_segment.addSection(allocator, "__debug_info", "__DWARF", .{
266 .sectname = makeStaticString("__debug_info"),
267 .segname = makeStaticString("__DWARF"),
268 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,250 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
269 .size = file_size_hint,251 .size = file_size_hint,
270 .offset = @intCast(u32, off),252 .offset = @intCast(u32, off),
271 .@"align" = p_align,253 .@"align" = p_align,
272 .reloff = 0,
273 .nreloc = 0,
274 .flags = macho.S_REGULAR,
275 .reserved1 = 0,
276 .reserved2 = 0,
277 .reserved3 = 0,
278 });254 });
279 self.header_dirty = true;255 self.header_dirty = true;
280 self.load_commands_dirty = true;256 self.load_commands_dirty = true;
...@@ -290,19 +266,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -290,19 +266,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
290266
291 log.debug("found dSym __debug_abbrev free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });267 log.debug("found dSym __debug_abbrev free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
292268
293 try dwarf_segment.addSection(allocator, .{269 try dwarf_segment.addSection(allocator, "__debug_abbrev", "__DWARF", .{
294 .sectname = makeStaticString("__debug_abbrev"),
295 .segname = makeStaticString("__DWARF"),
296 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,270 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
297 .size = file_size_hint,271 .size = file_size_hint,
298 .offset = @intCast(u32, off),272 .offset = @intCast(u32, off),
299 .@"align" = p_align,273 .@"align" = p_align,
300 .reloff = 0,
301 .nreloc = 0,
302 .flags = macho.S_REGULAR,
303 .reserved1 = 0,
304 .reserved2 = 0,
305 .reserved3 = 0,
306 });274 });
307 self.header_dirty = true;275 self.header_dirty = true;
308 self.load_commands_dirty = true;276 self.load_commands_dirty = true;
...@@ -318,19 +286,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -318,19 +286,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
318286
319 log.debug("found dSym __debug_aranges free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });287 log.debug("found dSym __debug_aranges free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
320288
321 try dwarf_segment.addSection(allocator, .{289 try dwarf_segment.addSection(allocator, "__debug_aranges", "__DWARF", .{
322 .sectname = makeStaticString("__debug_aranges"),
323 .segname = makeStaticString("__DWARF"),
324 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,290 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
325 .size = file_size_hint,291 .size = file_size_hint,
326 .offset = @intCast(u32, off),292 .offset = @intCast(u32, off),
327 .@"align" = p_align,293 .@"align" = p_align,
328 .reloff = 0,
329 .nreloc = 0,
330 .flags = macho.S_REGULAR,
331 .reserved1 = 0,
332 .reserved2 = 0,
333 .reserved3 = 0,
334 });294 });
335 self.header_dirty = true;295 self.header_dirty = true;
336 self.load_commands_dirty = true;296 self.load_commands_dirty = true;
...@@ -346,19 +306,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void...@@ -346,19 +306,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
346306
347 log.debug("found dSym __debug_line free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });307 log.debug("found dSym __debug_line free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
348308
349 try dwarf_segment.addSection(allocator, .{309 try dwarf_segment.addSection(allocator, "__debug_line", "__DWARF", .{
350 .sectname = makeStaticString("__debug_line"),
351 .segname = makeStaticString("__DWARF"),
352 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,310 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
353 .size = file_size_hint,311 .size = file_size_hint,
354 .offset = @intCast(u32, off),312 .offset = @intCast(u32, off),
355 .@"align" = p_align,313 .@"align" = p_align,
356 .reloff = 0,
357 .nreloc = 0,
358 .flags = macho.S_REGULAR,
359 .reserved1 = 0,
360 .reserved2 = 0,
361 .reserved3 = 0,
362 });314 });
363 self.header_dirty = true;315 self.header_dirty = true;
364 self.load_commands_dirty = true;316 self.load_commands_dirty = true;
...@@ -692,14 +644,10 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {...@@ -692,14 +644,10 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
692}644}
693645
694fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !SegmentCommand {646fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !SegmentCommand {
695 var cmd = SegmentCommand.empty(.{647 var cmd = SegmentCommand.empty("", .{
696 .cmd = macho.LC_SEGMENT_64,
697 .cmdsize = base_cmd.inner.cmdsize,648 .cmdsize = base_cmd.inner.cmdsize,
698 .segname = undefined,
699 .vmaddr = base_cmd.inner.vmaddr,649 .vmaddr = base_cmd.inner.vmaddr,
700 .vmsize = base_cmd.inner.vmsize,650 .vmsize = base_cmd.inner.vmsize,
701 .fileoff = 0,
702 .filesize = 0,
703 .maxprot = base_cmd.inner.maxprot,651 .maxprot = base_cmd.inner.maxprot,
704 .initprot = base_cmd.inner.initprot,652 .initprot = base_cmd.inner.initprot,
705 .nsects = base_cmd.inner.nsects,653 .nsects = base_cmd.inner.nsects,
src/link/MachO/Stub.zig+42-18
...@@ -60,7 +60,7 @@ pub fn parse(self: *Stub) !void {...@@ -60,7 +60,7 @@ pub fn parse(self: *Stub) !void {
60 const lib_stub = self.lib_stub orelse return error.EmptyStubFile;60 const lib_stub = self.lib_stub orelse return error.EmptyStubFile;
61 if (lib_stub.inner.len == 0) return error.EmptyStubFile;61 if (lib_stub.inner.len == 0) return error.EmptyStubFile;
6262
63 log.warn("parsing shared library from stub '{s}'", .{self.name.?});63 log.debug("parsing shared library from stub '{s}'", .{self.name.?});
6464
65 const umbrella_lib = lib_stub.inner[0];65 const umbrella_lib = lib_stub.inner[0];
66 self.id = .{66 self.id = .{
...@@ -93,14 +93,26 @@ pub fn parse(self: *Stub) !void {...@@ -93,14 +93,26 @@ pub fn parse(self: *Stub) !void {
9393
94 if (exp.objc_classes) |classes| {94 if (exp.objc_classes) |classes| {
95 for (classes) |sym_name| {95 for (classes) |sym_name| {
96 log.warn(" | {s}", .{sym_name});96 log.debug(" | {s}", .{sym_name});
97 const actual_sym_name = try std.fmt.allocPrint(97 {
98 self.allocator,98 const actual_sym_name = try std.fmt.allocPrint(
99 "_OBJC_CLASS_$_{s}",99 self.allocator,
100 .{sym_name},100 "_OBJC_CLASS_$_{s}",
101 );101 .{sym_name},
102 if (self.symbols.contains(actual_sym_name)) continue;102 );
103 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});103 if (self.symbols.contains(actual_sym_name)) continue;
104 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
105 }
106
107 {
108 const actual_sym_name = try std.fmt.allocPrint(
109 self.allocator,
110 "_OBJC_METACLASS_$_{s}",
111 .{sym_name},
112 );
113 if (self.symbols.contains(actual_sym_name)) continue;
114 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
115 }
104 }116 }
105 }117 }
106 }118 }
...@@ -118,16 +130,28 @@ pub fn parse(self: *Stub) !void {...@@ -118,16 +130,28 @@ pub fn parse(self: *Stub) !void {
118 }130 }
119131
120 if (stub.objc_classes) |classes| {132 if (stub.objc_classes) |classes| {
121 log.warn(" | objc_classes", .{});133 log.debug(" | objc_classes", .{});
122 for (classes) |sym_name| {134 for (classes) |sym_name| {
123 log.warn(" | {s}", .{sym_name});135 log.debug(" | {s}", .{sym_name});
124 const actual_sym_name = try std.fmt.allocPrint(136 {
125 self.allocator,137 const actual_sym_name = try std.fmt.allocPrint(
126 "_OBJC_METACLASS_$_{s}",138 self.allocator,
127 .{sym_name},139 "_OBJC_CLASS_$_{s}",
128 );140 .{sym_name},
129 if (self.symbols.contains(actual_sym_name)) continue;141 );
130 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});142 if (self.symbols.contains(actual_sym_name)) continue;
143 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
144 }
145
146 {
147 const actual_sym_name = try std.fmt.allocPrint(
148 self.allocator,
149 "_OBJC_METACLASS_$_{s}",
150 .{sym_name},
151 );
152 if (self.symbols.contains(actual_sym_name)) continue;
153 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
154 }
131 }155 }
132 }156 }
133 }157 }
src/link/MachO/Zld.zig+43-368
...@@ -79,6 +79,8 @@ mod_init_func_section_index: ?u16 = null,...@@ -79,6 +79,8 @@ mod_init_func_section_index: ?u16 = null,
79mod_term_func_section_index: ?u16 = null,79mod_term_func_section_index: ?u16 = null,
80data_const_section_index: ?u16 = null,80data_const_section_index: ?u16 = null,
8181
82objc_cfstring_section_index: ?u16 = null,
83
82// __DATA segment sections84// __DATA segment sections
83tlv_section_index: ?u16 = null,85tlv_section_index: ?u16 = null,
84tlv_data_section_index: ?u16 = null,86tlv_data_section_index: ?u16 = null,
...@@ -515,39 +517,15 @@ fn updateMetadata(self: *Zld) !void {...@@ -515,39 +517,15 @@ fn updateMetadata(self: *Zld) !void {
515 if (self.text_const_section_index != null) continue;517 if (self.text_const_section_index != null) continue;
516518
517 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);519 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);
518 try text_seg.addSection(self.allocator, .{520 try text_seg.addSection(self.allocator, "__const", "__TEXT", .{});
519 .sectname = makeStaticString("__const"),
520 .segname = makeStaticString("__TEXT"),
521 .addr = 0,
522 .size = 0,
523 .offset = 0,
524 .@"align" = 0,
525 .reloff = 0,
526 .nreloc = 0,
527 .flags = macho.S_REGULAR,
528 .reserved1 = 0,
529 .reserved2 = 0,
530 .reserved3 = 0,
531 });
532 continue;521 continue;
533 },522 },
534 macho.S_CSTRING_LITERALS => {523 macho.S_CSTRING_LITERALS => {
535 if (self.cstring_section_index != null) continue;524 if (self.cstring_section_index != null) continue;
536525
537 self.cstring_section_index = @intCast(u16, text_seg.sections.items.len);526 self.cstring_section_index = @intCast(u16, text_seg.sections.items.len);
538 try text_seg.addSection(self.allocator, .{527 try text_seg.addSection(self.allocator, "__cstring", "__TEXT", .{
539 .sectname = makeStaticString("__cstring"),
540 .segname = makeStaticString("__TEXT"),
541 .addr = 0,
542 .size = 0,
543 .offset = 0,
544 .@"align" = 0,
545 .reloff = 0,
546 .nreloc = 0,
547 .flags = macho.S_CSTRING_LITERALS,528 .flags = macho.S_CSTRING_LITERALS,
548 .reserved1 = 0,
549 .reserved2 = 0,
550 .reserved3 = 0,
551 });529 });
552 continue;530 continue;
553 },531 },
...@@ -555,19 +533,8 @@ fn updateMetadata(self: *Zld) !void {...@@ -555,19 +533,8 @@ fn updateMetadata(self: *Zld) !void {
555 if (self.mod_init_func_section_index != null) continue;533 if (self.mod_init_func_section_index != null) continue;
556534
557 self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len);535 self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len);
558 try data_const_seg.addSection(self.allocator, .{536 try data_const_seg.addSection(self.allocator, "__mod_init_func", "__DATA_CONST", .{
559 .sectname = makeStaticString("__mod_init_func"),
560 .segname = makeStaticString("__DATA_CONST"),
561 .addr = 0,
562 .size = 0,
563 .offset = 0,
564 .@"align" = 0,
565 .reloff = 0,
566 .nreloc = 0,
567 .flags = macho.S_MOD_INIT_FUNC_POINTERS,537 .flags = macho.S_MOD_INIT_FUNC_POINTERS,
568 .reserved1 = 0,
569 .reserved2 = 0,
570 .reserved3 = 0,
571 });538 });
572 continue;539 continue;
573 },540 },
...@@ -575,19 +542,8 @@ fn updateMetadata(self: *Zld) !void {...@@ -575,19 +542,8 @@ fn updateMetadata(self: *Zld) !void {
575 if (self.mod_term_func_section_index != null) continue;542 if (self.mod_term_func_section_index != null) continue;
576543
577 self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len);544 self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len);
578 try data_const_seg.addSection(self.allocator, .{545 try data_const_seg.addSection(self.allocator, "__mod_term_func", "__DATA_CONST", .{
579 .sectname = makeStaticString("__mod_term_func"),
580 .segname = makeStaticString("__DATA_CONST"),
581 .addr = 0,
582 .size = 0,
583 .offset = 0,
584 .@"align" = 0,
585 .reloff = 0,
586 .nreloc = 0,
587 .flags = macho.S_MOD_TERM_FUNC_POINTERS,546 .flags = macho.S_MOD_TERM_FUNC_POINTERS,
588 .reserved1 = 0,
589 .reserved2 = 0,
590 .reserved3 = 0,
591 });547 });
592 continue;548 continue;
593 },549 },
...@@ -596,37 +552,15 @@ fn updateMetadata(self: *Zld) !void {...@@ -596,37 +552,15 @@ fn updateMetadata(self: *Zld) !void {
596 if (self.common_section_index != null) continue;552 if (self.common_section_index != null) continue;
597553
598 self.common_section_index = @intCast(u16, data_seg.sections.items.len);554 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
599 try data_seg.addSection(self.allocator, .{555 try data_seg.addSection(self.allocator, "__common", "__DATA", .{
600 .sectname = makeStaticString("__common"),
601 .segname = makeStaticString("__DATA"),
602 .addr = 0,
603 .size = 0,
604 .offset = 0,
605 .@"align" = 0,
606 .reloff = 0,
607 .nreloc = 0,
608 .flags = macho.S_ZEROFILL,556 .flags = macho.S_ZEROFILL,
609 .reserved1 = 0,
610 .reserved2 = 0,
611 .reserved3 = 0,
612 });557 });
613 } else {558 } else {
614 if (self.bss_section_index != null) continue;559 if (self.bss_section_index != null) continue;
615560
616 self.bss_section_index = @intCast(u16, data_seg.sections.items.len);561 self.bss_section_index = @intCast(u16, data_seg.sections.items.len);
617 try data_seg.addSection(self.allocator, .{562 try data_seg.addSection(self.allocator, "__bss", "__DATA", .{
618 .sectname = makeStaticString("__bss"),
619 .segname = makeStaticString("__DATA"),
620 .addr = 0,
621 .size = 0,
622 .offset = 0,
623 .@"align" = 0,
624 .reloff = 0,
625 .nreloc = 0,
626 .flags = macho.S_ZEROFILL,563 .flags = macho.S_ZEROFILL,
627 .reserved1 = 0,
628 .reserved2 = 0,
629 .reserved3 = 0,
630 });564 });
631 }565 }
632 continue;566 continue;
...@@ -635,19 +569,8 @@ fn updateMetadata(self: *Zld) !void {...@@ -635,19 +569,8 @@ fn updateMetadata(self: *Zld) !void {
635 if (self.tlv_section_index != null) continue;569 if (self.tlv_section_index != null) continue;
636570
637 self.tlv_section_index = @intCast(u16, data_seg.sections.items.len);571 self.tlv_section_index = @intCast(u16, data_seg.sections.items.len);
638 try data_seg.addSection(self.allocator, .{572 try data_seg.addSection(self.allocator, "__thread_vars", "__DATA", .{
639 .sectname = makeStaticString("__thread_vars"),
640 .segname = makeStaticString("__DATA"),
641 .addr = 0,
642 .size = 0,
643 .offset = 0,
644 .@"align" = 0,
645 .reloff = 0,
646 .nreloc = 0,
647 .flags = macho.S_THREAD_LOCAL_VARIABLES,573 .flags = macho.S_THREAD_LOCAL_VARIABLES,
648 .reserved1 = 0,
649 .reserved2 = 0,
650 .reserved3 = 0,
651 });574 });
652 continue;575 continue;
653 },576 },
...@@ -655,19 +578,8 @@ fn updateMetadata(self: *Zld) !void {...@@ -655,19 +578,8 @@ fn updateMetadata(self: *Zld) !void {
655 if (self.tlv_data_section_index != null) continue;578 if (self.tlv_data_section_index != null) continue;
656579
657 self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len);580 self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len);
658 try data_seg.addSection(self.allocator, .{581 try data_seg.addSection(self.allocator, "__thread_data", "__DATA", .{
659 .sectname = makeStaticString("__thread_data"),
660 .segname = makeStaticString("__DATA"),
661 .addr = 0,
662 .size = 0,
663 .offset = 0,
664 .@"align" = 0,
665 .reloff = 0,
666 .nreloc = 0,
667 .flags = macho.S_THREAD_LOCAL_REGULAR,582 .flags = macho.S_THREAD_LOCAL_REGULAR,
668 .reserved1 = 0,
669 .reserved2 = 0,
670 .reserved3 = 0,
671 });583 });
672 continue;584 continue;
673 },585 },
...@@ -675,19 +587,8 @@ fn updateMetadata(self: *Zld) !void {...@@ -675,19 +587,8 @@ fn updateMetadata(self: *Zld) !void {
675 if (self.tlv_bss_section_index != null) continue;587 if (self.tlv_bss_section_index != null) continue;
676588
677 self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len);589 self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len);
678 try data_seg.addSection(self.allocator, .{590 try data_seg.addSection(self.allocator, "__thread_bss", "__DATA", .{
679 .sectname = makeStaticString("__thread_bss"),
680 .segname = makeStaticString("__DATA"),
681 .addr = 0,
682 .size = 0,
683 .offset = 0,
684 .@"align" = 0,
685 .reloff = 0,
686 .nreloc = 0,
687 .flags = macho.S_THREAD_LOCAL_ZEROFILL,591 .flags = macho.S_THREAD_LOCAL_ZEROFILL,
688 .reserved1 = 0,
689 .reserved2 = 0,
690 .reserved3 = 0,
691 });592 });
692 continue;593 continue;
693 },594 },
...@@ -698,20 +599,7 @@ fn updateMetadata(self: *Zld) !void {...@@ -698,20 +599,7 @@ fn updateMetadata(self: *Zld) !void {
698 if (self.eh_frame_section_index != null) continue;599 if (self.eh_frame_section_index != null) continue;
699600
700 self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len);601 self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len);
701 try text_seg.addSection(self.allocator, .{602 try text_seg.addSection(self.allocator, "__eh_frame", "__TEXT", .{});
702 .sectname = makeStaticString("__eh_frame"),
703 .segname = makeStaticString("__TEXT"),
704 .addr = 0,
705 .size = 0,
706 .offset = 0,
707 .@"align" = 0,
708 .reloff = 0,
709 .nreloc = 0,
710 .flags = macho.S_REGULAR,
711 .reserved1 = 0,
712 .reserved2 = 0,
713 .reserved3 = 0,
714 });
715 continue;603 continue;
716 }604 }
717605
...@@ -719,20 +607,7 @@ fn updateMetadata(self: *Zld) !void {...@@ -719,20 +607,7 @@ fn updateMetadata(self: *Zld) !void {
719 if (self.data_const_section_index != null) continue;607 if (self.data_const_section_index != null) continue;
720608
721 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);609 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
722 try data_const_seg.addSection(self.allocator, .{610 try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
723 .sectname = makeStaticString("__const"),
724 .segname = makeStaticString("__DATA_CONST"),
725 .addr = 0,
726 .size = 0,
727 .offset = 0,
728 .@"align" = 0,
729 .reloff = 0,
730 .nreloc = 0,
731 .flags = macho.S_REGULAR,
732 .reserved1 = 0,
733 .reserved2 = 0,
734 .reserved3 = 0,
735 });
736 continue;611 continue;
737 },612 },
738 macho.S_REGULAR => {613 macho.S_REGULAR => {
...@@ -740,19 +615,8 @@ fn updateMetadata(self: *Zld) !void {...@@ -740,19 +615,8 @@ fn updateMetadata(self: *Zld) !void {
740 if (self.text_section_index != null) continue;615 if (self.text_section_index != null) continue;
741616
742 self.text_section_index = @intCast(u16, text_seg.sections.items.len);617 self.text_section_index = @intCast(u16, text_seg.sections.items.len);
743 try text_seg.addSection(self.allocator, .{618 try text_seg.addSection(self.allocator, "__text", "__TEXT", .{
744 .sectname = makeStaticString("__text"),
745 .segname = makeStaticString("__TEXT"),
746 .addr = 0,
747 .size = 0,
748 .offset = 0,
749 .@"align" = 0,
750 .reloff = 0,
751 .nreloc = 0,
752 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,619 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
753 .reserved1 = 0,
754 .reserved2 = 0,
755 .reserved3 = 0,
756 });620 });
757 continue;621 continue;
758 }622 }
...@@ -771,56 +635,17 @@ fn updateMetadata(self: *Zld) !void {...@@ -771,56 +635,17 @@ fn updateMetadata(self: *Zld) !void {
771 if (self.ustring_section_index != null) continue;635 if (self.ustring_section_index != null) continue;
772636
773 self.ustring_section_index = @intCast(u16, text_seg.sections.items.len);637 self.ustring_section_index = @intCast(u16, text_seg.sections.items.len);
774 try text_seg.addSection(self.allocator, .{638 try text_seg.addSection(self.allocator, "__ustring", "__TEXT", .{});
775 .sectname = makeStaticString("__ustring"),
776 .segname = makeStaticString("__TEXT"),
777 .addr = 0,
778 .size = 0,
779 .offset = 0,
780 .@"align" = 0,
781 .reloff = 0,
782 .nreloc = 0,
783 .flags = macho.S_REGULAR,
784 .reserved1 = 0,
785 .reserved2 = 0,
786 .reserved3 = 0,
787 });
788 } else if (mem.eql(u8, sectname, "__gcc_except_tab")) {639 } else if (mem.eql(u8, sectname, "__gcc_except_tab")) {
789 if (self.gcc_except_tab_section_index != null) continue;640 if (self.gcc_except_tab_section_index != null) continue;
790641
791 self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len);642 self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len);
792 try text_seg.addSection(self.allocator, .{643 try text_seg.addSection(self.allocator, "__gcc_except_tab", "__TEXT", .{});
793 .sectname = makeStaticString("__gcc_except_tab"),
794 .segname = makeStaticString("__TEXT"),
795 .addr = 0,
796 .size = 0,
797 .offset = 0,
798 .@"align" = 0,
799 .reloff = 0,
800 .nreloc = 0,
801 .flags = macho.S_REGULAR,
802 .reserved1 = 0,
803 .reserved2 = 0,
804 .reserved3 = 0,
805 });
806 } else {644 } else {
807 if (self.text_const_section_index != null) continue;645 if (self.text_const_section_index != null) continue;
808646
809 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);647 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);
810 try text_seg.addSection(self.allocator, .{648 try text_seg.addSection(self.allocator, "__const", "__TEXT", .{});
811 .sectname = makeStaticString("__const"),
812 .segname = makeStaticString("__TEXT"),
813 .addr = 0,
814 .size = 0,
815 .offset = 0,
816 .@"align" = 0,
817 .reloff = 0,
818 .nreloc = 0,
819 .flags = macho.S_REGULAR,
820 .reserved1 = 0,
821 .reserved2 = 0,
822 .reserved3 = 0,
823 });
824 }649 }
825 continue;650 continue;
826 }651 }
...@@ -829,20 +654,7 @@ fn updateMetadata(self: *Zld) !void {...@@ -829,20 +654,7 @@ fn updateMetadata(self: *Zld) !void {
829 if (self.data_const_section_index != null) continue;654 if (self.data_const_section_index != null) continue;
830655
831 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);656 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
832 try data_const_seg.addSection(self.allocator, .{657 try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
833 .sectname = makeStaticString("__const"),
834 .segname = makeStaticString("__DATA_CONST"),
835 .addr = 0,
836 .size = 0,
837 .offset = 0,
838 .@"align" = 0,
839 .reloff = 0,
840 .nreloc = 0,
841 .flags = macho.S_REGULAR,
842 .reserved1 = 0,
843 .reserved2 = 0,
844 .reserved3 = 0,
845 });
846 continue;658 continue;
847 }659 }
848660
...@@ -851,38 +663,17 @@ fn updateMetadata(self: *Zld) !void {...@@ -851,38 +663,17 @@ fn updateMetadata(self: *Zld) !void {
851 if (self.data_const_section_index != null) continue;663 if (self.data_const_section_index != null) continue;
852664
853 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);665 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
854 try data_const_seg.addSection(self.allocator, .{666 try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
855 .sectname = makeStaticString("__const"),667 } else if (mem.eql(u8, sectname, "__cfstring")) {
856 .segname = makeStaticString("__DATA_CONST"),668 if (self.objc_cfstring_section_index != null) continue;
857 .addr = 0,669
858 .size = 0,670 self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len);
859 .offset = 0,671 try data_const_seg.addSection(self.allocator, "__cfstring", "__DATA_CONST", .{});
860 .@"align" = 0,
861 .reloff = 0,
862 .nreloc = 0,
863 .flags = macho.S_REGULAR,
864 .reserved1 = 0,
865 .reserved2 = 0,
866 .reserved3 = 0,
867 });
868 } else {672 } else {
869 if (self.data_section_index != null) continue;673 if (self.data_section_index != null) continue;
870674
871 self.data_section_index = @intCast(u16, data_seg.sections.items.len);675 self.data_section_index = @intCast(u16, data_seg.sections.items.len);
872 try data_seg.addSection(self.allocator, .{676 try data_seg.addSection(self.allocator, "__data", "__DATA", .{});
873 .sectname = makeStaticString("__data"),
874 .segname = makeStaticString("__DATA"),
875 .addr = 0,
876 .size = 0,
877 .offset = 0,
878 .@"align" = 0,
879 .reloff = 0,
880 .nreloc = 0,
881 .flags = macho.S_REGULAR,
882 .reserved1 = 0,
883 .reserved2 = 0,
884 .reserved3 = 0,
885 });
886 }677 }
887678
888 continue;679 continue;
...@@ -932,19 +723,8 @@ fn updateMetadata(self: *Zld) !void {...@@ -932,19 +723,8 @@ fn updateMetadata(self: *Zld) !void {
932 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;723 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
933 const common_section_index = self.common_section_index orelse ind: {724 const common_section_index = self.common_section_index orelse ind: {
934 self.common_section_index = @intCast(u16, data_seg.sections.items.len);725 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
935 try data_seg.addSection(self.allocator, .{726 try data_seg.addSection(self.allocator, "__common", "__DATA", .{
936 .sectname = makeStaticString("__common"),
937 .segname = makeStaticString("__DATA"),
938 .addr = 0,
939 .size = 0,
940 .offset = 0,
941 .@"align" = 0,
942 .reloff = 0,
943 .nreloc = 0,
944 .flags = macho.S_ZEROFILL,727 .flags = macho.S_ZEROFILL,
945 .reserved1 = 0,
946 .reserved2 = 0,
947 .reserved3 = 0,
948 });728 });
949 break :ind self.common_section_index.?;729 break :ind self.common_section_index.?;
950 };730 };
...@@ -1136,6 +916,11 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection {...@@ -1136,6 +916,11 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection {
1136 .seg = self.data_const_segment_cmd_index.?,916 .seg = self.data_const_segment_cmd_index.?,
1137 .sect = self.data_const_section_index.?,917 .sect = self.data_const_section_index.?,
1138 };918 };
919 } else if (mem.eql(u8, sectname, "__cfstring")) {
920 break :blk .{
921 .seg = self.data_const_segment_cmd_index.?,
922 .sect = self.objc_cfstring_section_index.?,
923 };
1139 }924 }
1140 break :blk .{925 break :blk .{
1141 .seg = self.data_segment_cmd_index.?,926 .seg = self.data_segment_cmd_index.?,
...@@ -1200,6 +985,7 @@ fn sortSections(self: *Zld) !void {...@@ -1200,6 +985,7 @@ fn sortSections(self: *Zld) !void {
1200 &self.mod_init_func_section_index,985 &self.mod_init_func_section_index,
1201 &self.mod_term_func_section_index,986 &self.mod_term_func_section_index,
1202 &self.data_const_section_index,987 &self.data_const_section_index,
988 &self.objc_cfstring_section_index,
1203 };989 };
1204 for (indices) |maybe_index| {990 for (indices) |maybe_index| {
1205 const new_index: u16 = if (maybe_index.*) |index| blk: {991 const new_index: u16 = if (maybe_index.*) |index| blk: {
...@@ -2240,18 +2026,8 @@ fn populateMetadata(self: *Zld) !void {...@@ -2240,18 +2026,8 @@ fn populateMetadata(self: *Zld) !void {
2240 if (self.pagezero_segment_cmd_index == null) {2026 if (self.pagezero_segment_cmd_index == null) {
2241 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2027 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
2242 try self.load_commands.append(self.allocator, .{2028 try self.load_commands.append(self.allocator, .{
2243 .Segment = SegmentCommand.empty(.{2029 .Segment = SegmentCommand.empty("__PAGEZERO", .{
2244 .cmd = macho.LC_SEGMENT_64,
2245 .cmdsize = @sizeOf(macho.segment_command_64),
2246 .segname = makeStaticString("__PAGEZERO"),
2247 .vmaddr = 0,
2248 .vmsize = 0x100000000, // size always set to 4GB2030 .vmsize = 0x100000000, // size always set to 4GB
2249 .fileoff = 0,
2250 .filesize = 0,
2251 .maxprot = 0,
2252 .initprot = 0,
2253 .nsects = 0,
2254 .flags = 0,
2255 }),2031 }),
2256 });2032 });
2257 }2033 }
...@@ -2259,18 +2035,10 @@ fn populateMetadata(self: *Zld) !void {...@@ -2259,18 +2035,10 @@ fn populateMetadata(self: *Zld) !void {
2259 if (self.text_segment_cmd_index == null) {2035 if (self.text_segment_cmd_index == null) {
2260 self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2036 self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
2261 try self.load_commands.append(self.allocator, .{2037 try self.load_commands.append(self.allocator, .{
2262 .Segment = SegmentCommand.empty(.{2038 .Segment = SegmentCommand.empty("__TEXT", .{
2263 .cmd = macho.LC_SEGMENT_64,
2264 .cmdsize = @sizeOf(macho.segment_command_64),
2265 .segname = makeStaticString("__TEXT"),
2266 .vmaddr = 0x100000000, // always starts at 4GB2039 .vmaddr = 0x100000000, // always starts at 4GB
2267 .vmsize = 0,
2268 .fileoff = 0,
2269 .filesize = 0,
2270 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,2040 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
2271 .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,2041 .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
2272 .nsects = 0,
2273 .flags = 0,
2274 }),2042 }),
2275 });2043 });
2276 }2044 }
...@@ -2283,19 +2051,9 @@ fn populateMetadata(self: *Zld) !void {...@@ -2283,19 +2051,9 @@ fn populateMetadata(self: *Zld) !void {
2283 .aarch64 => 2,2051 .aarch64 => 2,
2284 else => unreachable, // unhandled architecture type2052 else => unreachable, // unhandled architecture type
2285 };2053 };
2286 try text_seg.addSection(self.allocator, .{2054 try text_seg.addSection(self.allocator, "__text", "__TEXT", .{
2287 .sectname = makeStaticString("__text"),
2288 .segname = makeStaticString("__TEXT"),
2289 .addr = 0,
2290 .size = 0,
2291 .offset = 0,
2292 .@"align" = alignment,2055 .@"align" = alignment,
2293 .reloff = 0,
2294 .nreloc = 0,
2295 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,2056 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2296 .reserved1 = 0,
2297 .reserved2 = 0,
2298 .reserved3 = 0,
2299 });2057 });
2300 }2058 }
23012059
...@@ -2312,19 +2070,10 @@ fn populateMetadata(self: *Zld) !void {...@@ -2312,19 +2070,10 @@ fn populateMetadata(self: *Zld) !void {
2312 .aarch64 => 3 * @sizeOf(u32),2070 .aarch64 => 3 * @sizeOf(u32),
2313 else => unreachable, // unhandled architecture type2071 else => unreachable, // unhandled architecture type
2314 };2072 };
2315 try text_seg.addSection(self.allocator, .{2073 try text_seg.addSection(self.allocator, "__stubs", "__TEXT", .{
2316 .sectname = makeStaticString("__stubs"),
2317 .segname = makeStaticString("__TEXT"),
2318 .addr = 0,
2319 .size = 0,
2320 .offset = 0,
2321 .@"align" = alignment,2074 .@"align" = alignment,
2322 .reloff = 0,
2323 .nreloc = 0,
2324 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,2075 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2325 .reserved1 = 0,
2326 .reserved2 = stub_size,2076 .reserved2 = stub_size,
2327 .reserved3 = 0,
2328 });2077 });
2329 }2078 }
23302079
...@@ -2341,37 +2090,19 @@ fn populateMetadata(self: *Zld) !void {...@@ -2341,37 +2090,19 @@ fn populateMetadata(self: *Zld) !void {
2341 .aarch64 => 6 * @sizeOf(u32),2090 .aarch64 => 6 * @sizeOf(u32),
2342 else => unreachable,2091 else => unreachable,
2343 };2092 };
2344 try text_seg.addSection(self.allocator, .{2093 try text_seg.addSection(self.allocator, "__stub_helper", "__TEXT", .{
2345 .sectname = makeStaticString("__stub_helper"),
2346 .segname = makeStaticString("__TEXT"),
2347 .addr = 0,
2348 .size = stub_helper_size,2094 .size = stub_helper_size,
2349 .offset = 0,
2350 .@"align" = alignment,2095 .@"align" = alignment,
2351 .reloff = 0,
2352 .nreloc = 0,
2353 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,2096 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2354 .reserved1 = 0,
2355 .reserved2 = 0,
2356 .reserved3 = 0,
2357 });2097 });
2358 }2098 }
23592099
2360 if (self.data_const_segment_cmd_index == null) {2100 if (self.data_const_segment_cmd_index == null) {
2361 self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2101 self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
2362 try self.load_commands.append(self.allocator, .{2102 try self.load_commands.append(self.allocator, .{
2363 .Segment = SegmentCommand.empty(.{2103 .Segment = SegmentCommand.empty("__DATA_CONST", .{
2364 .cmd = macho.LC_SEGMENT_64,
2365 .cmdsize = @sizeOf(macho.segment_command_64),
2366 .segname = makeStaticString("__DATA_CONST"),
2367 .vmaddr = 0,
2368 .vmsize = 0,
2369 .fileoff = 0,
2370 .filesize = 0,
2371 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,2104 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2372 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,2105 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2373 .nsects = 0,
2374 .flags = 0,
2375 }),2106 }),
2376 });2107 });
2377 }2108 }
...@@ -2379,37 +2110,18 @@ fn populateMetadata(self: *Zld) !void {...@@ -2379,37 +2110,18 @@ fn populateMetadata(self: *Zld) !void {
2379 if (self.got_section_index == null) {2110 if (self.got_section_index == null) {
2380 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;2111 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
2381 self.got_section_index = @intCast(u16, data_const_seg.sections.items.len);2112 self.got_section_index = @intCast(u16, data_const_seg.sections.items.len);
2382 try data_const_seg.addSection(self.allocator, .{2113 try data_const_seg.addSection(self.allocator, "__got", "__DATA_CONST", .{
2383 .sectname = makeStaticString("__got"),
2384 .segname = makeStaticString("__DATA_CONST"),
2385 .addr = 0,
2386 .size = 0,
2387 .offset = 0,
2388 .@"align" = 3, // 2^3 = @sizeOf(u64)2114 .@"align" = 3, // 2^3 = @sizeOf(u64)
2389 .reloff = 0,
2390 .nreloc = 0,
2391 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,2115 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
2392 .reserved1 = 0,
2393 .reserved2 = 0,
2394 .reserved3 = 0,
2395 });2116 });
2396 }2117 }
23972118
2398 if (self.data_segment_cmd_index == null) {2119 if (self.data_segment_cmd_index == null) {
2399 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2120 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
2400 try self.load_commands.append(self.allocator, .{2121 try self.load_commands.append(self.allocator, .{
2401 .Segment = SegmentCommand.empty(.{2122 .Segment = SegmentCommand.empty("__DATA", .{
2402 .cmd = macho.LC_SEGMENT_64,
2403 .cmdsize = @sizeOf(macho.segment_command_64),
2404 .segname = makeStaticString("__DATA"),
2405 .vmaddr = 0,
2406 .vmsize = 0,
2407 .fileoff = 0,
2408 .filesize = 0,
2409 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,2123 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2410 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,2124 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2411 .nsects = 0,
2412 .flags = 0,
2413 }),2125 }),
2414 });2126 });
2415 }2127 }
...@@ -2417,56 +2129,26 @@ fn populateMetadata(self: *Zld) !void {...@@ -2417,56 +2129,26 @@ fn populateMetadata(self: *Zld) !void {
2417 if (self.la_symbol_ptr_section_index == null) {2129 if (self.la_symbol_ptr_section_index == null) {
2418 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;2130 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2419 self.la_symbol_ptr_section_index = @intCast(u16, data_seg.sections.items.len);2131 self.la_symbol_ptr_section_index = @intCast(u16, data_seg.sections.items.len);
2420 try data_seg.addSection(self.allocator, .{2132 try data_seg.addSection(self.allocator, "__la_symbol_ptr", "__DATA", .{
2421 .sectname = makeStaticString("__la_symbol_ptr"),
2422 .segname = makeStaticString("__DATA"),
2423 .addr = 0,
2424 .size = 0,
2425 .offset = 0,
2426 .@"align" = 3, // 2^3 = @sizeOf(u64)2133 .@"align" = 3, // 2^3 = @sizeOf(u64)
2427 .reloff = 0,
2428 .nreloc = 0,
2429 .flags = macho.S_LAZY_SYMBOL_POINTERS,2134 .flags = macho.S_LAZY_SYMBOL_POINTERS,
2430 .reserved1 = 0,
2431 .reserved2 = 0,
2432 .reserved3 = 0,
2433 });2135 });
2434 }2136 }
24352137
2436 if (self.data_section_index == null) {2138 if (self.data_section_index == null) {
2437 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;2139 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
2438 self.data_section_index = @intCast(u16, data_seg.sections.items.len);2140 self.data_section_index = @intCast(u16, data_seg.sections.items.len);
2439 try data_seg.addSection(self.allocator, .{2141 try data_seg.addSection(self.allocator, "__data", "__DATA", .{
2440 .sectname = makeStaticString("__data"),
2441 .segname = makeStaticString("__DATA"),
2442 .addr = 0,
2443 .size = 0,
2444 .offset = 0,
2445 .@"align" = 3, // 2^3 = @sizeOf(u64)2142 .@"align" = 3, // 2^3 = @sizeOf(u64)
2446 .reloff = 0,
2447 .nreloc = 0,
2448 .flags = macho.S_REGULAR,
2449 .reserved1 = 0,
2450 .reserved2 = 0,
2451 .reserved3 = 0,
2452 });2143 });
2453 }2144 }
24542145
2455 if (self.linkedit_segment_cmd_index == null) {2146 if (self.linkedit_segment_cmd_index == null) {
2456 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);2147 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
2457 try self.load_commands.append(self.allocator, .{2148 try self.load_commands.append(self.allocator, .{
2458 .Segment = SegmentCommand.empty(.{2149 .Segment = SegmentCommand.empty("__LINKEDIT", .{
2459 .cmd = macho.LC_SEGMENT_64,
2460 .cmdsize = @sizeOf(macho.segment_command_64),
2461 .segname = makeStaticString("__LINKEDIT"),
2462 .vmaddr = 0,
2463 .vmsize = 0,
2464 .fileoff = 0,
2465 .filesize = 0,
2466 .maxprot = macho.VM_PROT_READ,2150 .maxprot = macho.VM_PROT_READ,
2467 .initprot = macho.VM_PROT_READ,2151 .initprot = macho.VM_PROT_READ,
2468 .nsects = 0,
2469 .flags = 0,
2470 }),2152 }),
2471 });2153 });
2472 }2154 }
...@@ -3469,13 +3151,6 @@ fn writeHeader(self: *Zld) !void {...@@ -3469,13 +3151,6 @@ fn writeHeader(self: *Zld) !void {
3469 try self.file.?.pwriteAll(mem.asBytes(&header), 0);3151 try self.file.?.pwriteAll(mem.asBytes(&header), 0);
3470}3152}
34713153
3472pub fn makeStaticString(bytes: []const u8) [16]u8 {
3473 var buf = [_]u8{0} ** 16;
3474 assert(bytes.len <= buf.len);
3475 mem.copy(u8, &buf, bytes);
3476 return buf;
3477}
3478
3479fn makeString(self: *Zld, bytes: []const u8) !u32 {3154fn makeString(self: *Zld, bytes: []const u8) !u32 {
3480 if (self.strtab_dir.get(bytes)) |offset| {3155 if (self.strtab_dir.get(bytes)) |offset| {
3481 log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset });3156 log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset });
src/link/MachO/commands.zig+69-5
...@@ -9,7 +9,6 @@ const assert = std.debug.assert;...@@ -9,7 +9,6 @@ const assert = std.debug.assert;
99
10const Allocator = std.mem.Allocator;10const Allocator = std.mem.Allocator;
11const MachO = @import("../MachO.zig");11const MachO = @import("../MachO.zig");
12const makeStaticString = MachO.makeStaticString;
13const padToIdeal = MachO.padToIdeal;12const padToIdeal = MachO.padToIdeal;
1413
15pub const LoadCommand = union(enum) {14pub const LoadCommand = union(enum) {
...@@ -187,12 +186,70 @@ pub const SegmentCommand = struct {...@@ -187,12 +186,70 @@ pub const SegmentCommand = struct {
187 inner: macho.segment_command_64,186 inner: macho.segment_command_64,
188 sections: std.ArrayListUnmanaged(macho.section_64) = .{},187 sections: std.ArrayListUnmanaged(macho.section_64) = .{},
189188
190 pub fn empty(inner: macho.segment_command_64) SegmentCommand {189 const SegmentOptions = struct {
191 return .{ .inner = inner };190 cmdsize: u32 = @sizeOf(macho.segment_command_64),
191 vmaddr: u64 = 0,
192 vmsize: u64 = 0,
193 fileoff: u64 = 0,
194 filesize: u64 = 0,
195 maxprot: macho.vm_prot_t = macho.VM_PROT_NONE,
196 initprot: macho.vm_prot_t = macho.VM_PROT_NONE,
197 nsects: u32 = 0,
198 flags: u32 = 0,
199 };
200
201 pub fn empty(comptime segname: []const u8, opts: SegmentOptions) SegmentCommand {
202 return .{
203 .inner = .{
204 .cmd = macho.LC_SEGMENT_64,
205 .cmdsize = opts.cmdsize,
206 .segname = makeStaticString(segname),
207 .vmaddr = opts.vmaddr,
208 .vmsize = opts.vmsize,
209 .fileoff = opts.fileoff,
210 .filesize = opts.filesize,
211 .maxprot = opts.maxprot,
212 .initprot = opts.initprot,
213 .nsects = opts.nsects,
214 .flags = opts.flags,
215 },
216 };
192 }217 }
193218
194 pub fn addSection(self: *SegmentCommand, alloc: *Allocator, section: macho.section_64) !void {219 const SectionOptions = struct {
195 try self.sections.append(alloc, section);220 addr: u64 = 0,
221 size: u64 = 0,
222 offset: u32 = 0,
223 @"align": u32 = 0,
224 reloff: u32 = 0,
225 nreloc: u32 = 0,
226 flags: u32 = macho.S_REGULAR,
227 reserved1: u32 = 0,
228 reserved2: u32 = 0,
229 reserved3: u32 = 0,
230 };
231
232 pub fn addSection(
233 self: *SegmentCommand,
234 alloc: *Allocator,
235 comptime sectname: []const u8,
236 comptime segname: []const u8,
237 opts: SectionOptions,
238 ) !void {
239 try self.sections.append(alloc, .{
240 .sectname = makeStaticString(sectname),
241 .segname = makeStaticString(segname),
242 .addr = opts.addr,
243 .size = opts.size,
244 .offset = opts.offset,
245 .@"align" = opts.@"align",
246 .reloff = opts.reloff,
247 .nreloc = opts.nreloc,
248 .flags = opts.flags,
249 .reserved1 = opts.reserved1,
250 .reserved2 = opts.reserved2,
251 .reserved3 = opts.reserved3,
252 });
196 self.inner.cmdsize += @sizeOf(macho.section_64);253 self.inner.cmdsize += @sizeOf(macho.section_64);
197 self.inner.nsects += 1;254 self.inner.nsects += 1;
198 }255 }
...@@ -338,6 +395,13 @@ pub fn createLoadDylibCommand(...@@ -338,6 +395,13 @@ pub fn createLoadDylibCommand(
338 return dylib_cmd;395 return dylib_cmd;
339}396}
340397
398fn makeStaticString(bytes: []const u8) [16]u8 {
399 var buf = [_]u8{0} ** 16;
400 assert(bytes.len <= buf.len);
401 mem.copy(u8, &buf, bytes);
402 return buf;
403}
404
341fn testRead(allocator: *Allocator, buffer: []const u8, expected: anytype) !void {405fn testRead(allocator: *Allocator, buffer: []const u8, expected: anytype) !void {
342 var stream = io.fixedBufferStream(buffer);406 var stream = io.fixedBufferStream(buffer);
343 var given = try LoadCommand.read(allocator, stream.reader());407 var given = try LoadCommand.read(allocator, stream.reader());