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 {
17791779 if (self.pagezero_segment_cmd_index == null) {
17801780 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
17811781 try self.load_commands.append(self.base.allocator, .{
1782 .Segment = SegmentCommand.empty(.{
1783 .cmd = macho.LC_SEGMENT_64,
1784 .cmdsize = @sizeOf(macho.segment_command_64),
1785 .segname = makeStaticString("__PAGEZERO"),
1786 .vmaddr = 0,
1782 .Segment = SegmentCommand.empty("__PAGEZERO", .{
17871783 .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,
17941784 }),
17951785 });
17961786 self.header_dirty = true;
......@@ -1809,18 +1799,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
18091799 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });
18101800
18111801 try self.load_commands.append(self.base.allocator, .{
1812 .Segment = SegmentCommand.empty(.{
1813 .cmd = macho.LC_SEGMENT_64,
1814 .cmdsize = @sizeOf(macho.segment_command_64),
1815 .segname = makeStaticString("__TEXT"),
1802 .Segment = SegmentCommand.empty("__TEXT", .{
18161803 .vmaddr = 0x100000000, // always starts at 4GB
18171804 .vmsize = needed_size,
1818 .fileoff = 0,
18191805 .filesize = needed_size,
18201806 .maxprot = maxprot,
18211807 .initprot = initprot,
1822 .nsects = 0,
1823 .flags = 0,
18241808 }),
18251809 });
18261810 self.header_dirty = true;
......@@ -1841,19 +1825,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
18411825
18421826 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, .{
1845 .sectname = makeStaticString("__text"),
1846 .segname = makeStaticString("__TEXT"),
1828 try text_segment.addSection(self.base.allocator, "__text", "__TEXT", .{
18471829 .addr = text_segment.inner.vmaddr + off,
18481830 .size = @intCast(u32, needed_size),
18491831 .offset = @intCast(u32, off),
18501832 .@"align" = alignment,
1851 .reloff = 0,
1852 .nreloc = 0,
18531833 .flags = flags,
1854 .reserved1 = 0,
1855 .reserved2 = 0,
1856 .reserved3 = 0,
18571834 });
18581835 self.header_dirty = true;
18591836 self.load_commands_dirty = true;
......@@ -1879,19 +1856,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
18791856
18801857 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, .{
1883 .sectname = makeStaticString("__stubs"),
1884 .segname = makeStaticString("__TEXT"),
1859 try text_segment.addSection(self.base.allocator, "__stubs", "__TEXT", .{
18851860 .addr = text_segment.inner.vmaddr + off,
18861861 .size = needed_size,
18871862 .offset = @intCast(u32, off),
18881863 .@"align" = alignment,
1889 .reloff = 0,
1890 .nreloc = 0,
18911864 .flags = flags,
1892 .reserved1 = 0,
18931865 .reserved2 = stub_size,
1894 .reserved3 = 0,
18951866 });
18961867 self.header_dirty = true;
18971868 self.load_commands_dirty = true;
......@@ -1912,19 +1883,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
19121883
19131884 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, .{
1916 .sectname = makeStaticString("__stub_helper"),
1917 .segname = makeStaticString("__TEXT"),
1886 try text_segment.addSection(self.base.allocator, "__stub_helper", "__TEXT", .{
19181887 .addr = text_segment.inner.vmaddr + off,
19191888 .size = needed_size,
19201889 .offset = @intCast(u32, off),
19211890 .@"align" = alignment,
1922 .reloff = 0,
1923 .nreloc = 0,
19241891 .flags = flags,
1925 .reserved1 = 0,
1926 .reserved2 = 0,
1927 .reserved3 = 0,
19281892 });
19291893 self.header_dirty = true;
19301894 self.load_commands_dirty = true;
......@@ -1941,18 +1905,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
19411905 log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
19421906
19431907 try self.load_commands.append(self.base.allocator, .{
1944 .Segment = SegmentCommand.empty(.{
1945 .cmd = macho.LC_SEGMENT_64,
1946 .cmdsize = @sizeOf(macho.segment_command_64),
1947 .segname = makeStaticString("__DATA_CONST"),
1908 .Segment = SegmentCommand.empty("__DATA_CONST", .{
19481909 .vmaddr = address_and_offset.address,
19491910 .vmsize = needed_size,
19501911 .fileoff = address_and_offset.offset,
19511912 .filesize = needed_size,
19521913 .maxprot = maxprot,
19531914 .initprot = initprot,
1954 .nsects = 0,
1955 .flags = 0,
19561915 }),
19571916 });
19581917 self.header_dirty = true;
......@@ -1969,19 +1928,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
19691928
19701929 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, .{
1973 .sectname = makeStaticString("__got"),
1974 .segname = makeStaticString("__DATA_CONST"),
1931 try dc_segment.addSection(self.base.allocator, "__got", "__DATA_CONST", .{
19751932 .addr = dc_segment.inner.vmaddr + off - dc_segment.inner.fileoff,
19761933 .size = needed_size,
19771934 .offset = @intCast(u32, off),
19781935 .@"align" = 3, // 2^3 = @sizeOf(u64)
1979 .reloff = 0,
1980 .nreloc = 0,
19811936 .flags = flags,
1982 .reserved1 = 0,
1983 .reserved2 = 0,
1984 .reserved3 = 0,
19851937 });
19861938 self.header_dirty = true;
19871939 self.load_commands_dirty = true;
......@@ -1998,18 +1950,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
19981950 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
19991951
20001952 try self.load_commands.append(self.base.allocator, .{
2001 .Segment = SegmentCommand.empty(.{
2002 .cmd = macho.LC_SEGMENT_64,
2003 .cmdsize = @sizeOf(macho.segment_command_64),
2004 .segname = makeStaticString("__DATA"),
1953 .Segment = SegmentCommand.empty("__DATA", .{
20051954 .vmaddr = address_and_offset.address,
20061955 .vmsize = needed_size,
20071956 .fileoff = address_and_offset.offset,
20081957 .filesize = needed_size,
20091958 .maxprot = maxprot,
20101959 .initprot = initprot,
2011 .nsects = 0,
2012 .flags = 0,
20131960 }),
20141961 });
20151962 self.header_dirty = true;
......@@ -2026,19 +1973,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
20261973
20271974 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, .{
2030 .sectname = makeStaticString("__la_symbol_ptr"),
2031 .segname = makeStaticString("__DATA"),
1976 try data_segment.addSection(self.base.allocator, "__la_symbol_ptr", "__DATA", .{
20321977 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
20331978 .size = needed_size,
20341979 .offset = @intCast(u32, off),
20351980 .@"align" = 3, // 2^3 = @sizeOf(u64)
2036 .reloff = 0,
2037 .nreloc = 0,
20381981 .flags = flags,
2039 .reserved1 = 0,
2040 .reserved2 = 0,
2041 .reserved3 = 0,
20421982 });
20431983 self.header_dirty = true;
20441984 self.load_commands_dirty = true;
......@@ -2047,26 +1987,17 @@ pub fn populateMissingMetadata(self: *MachO) !void {
20471987 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
20481988 self.data_section_index = @intCast(u16, data_segment.sections.items.len);
20491989
2050 const flags = macho.S_REGULAR;
20511990 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
20521991 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
20531992 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
20541993
20551994 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, .{
2058 .sectname = makeStaticString("__data"),
2059 .segname = makeStaticString("__DATA"),
1996 try data_segment.addSection(self.base.allocator, "__data", "__DATA", .{
20601997 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
20611998 .size = needed_size,
20621999 .offset = @intCast(u32, off),
20632000 .@"align" = 3, // 2^3 = @sizeOf(u64)
2064 .reloff = 0,
2065 .nreloc = 0,
2066 .flags = flags,
2067 .reserved1 = 0,
2068 .reserved2 = 0,
2069 .reserved3 = 0,
20702001 });
20712002 self.header_dirty = true;
20722003 self.load_commands_dirty = true;
......@@ -2081,18 +2012,11 @@ pub fn populateMissingMetadata(self: *MachO) !void {
20812012 log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset});
20822013
20832014 try self.load_commands.append(self.base.allocator, .{
2084 .Segment = SegmentCommand.empty(.{
2085 .cmd = macho.LC_SEGMENT_64,
2086 .cmdsize = @sizeOf(macho.segment_command_64),
2087 .segname = makeStaticString("__LINKEDIT"),
2015 .Segment = SegmentCommand.empty("__LINKEDIT", .{
20882016 .vmaddr = address_and_offset.address,
2089 .vmsize = 0,
20902017 .fileoff = address_and_offset.offset,
2091 .filesize = 0,
20922018 .maxprot = maxprot,
20932019 .initprot = initprot,
2094 .nsects = 0,
2095 .flags = 0,
20962020 }),
20972021 });
20982022 self.header_dirty = true;
......@@ -2450,13 +2374,6 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
24502374 return vaddr;
24512375}
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
24602377fn makeString(self: *MachO, bytes: []const u8) !u32 {
24612378 if (self.string_table_directory.get(bytes)) |offset| {
24622379 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");
1919const SrcFn = MachO.SrcFn;
2020const TextBlock = MachO.TextBlock;
2121const padToIdeal = MachO.padToIdeal;
22const makeStaticString = MachO.makeStaticString;
2322
2423usingnamespace @import("commands.zig");
2524
......@@ -212,18 +211,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
212211 log.debug("found dSym __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });
213212
214213 try self.load_commands.append(allocator, .{
215 .Segment = SegmentCommand.empty(.{
216 .cmd = macho.LC_SEGMENT_64,
217 .cmdsize = @sizeOf(macho.segment_command_64),
218 .segname = makeStaticString("__DWARF"),
214 .Segment = SegmentCommand.empty("__DWARF", .{
219215 .vmaddr = vmaddr,
220216 .vmsize = needed_size,
221217 .fileoff = off,
222218 .filesize = needed_size,
223 .maxprot = 0,
224 .initprot = 0,
225 .nsects = 0,
226 .flags = 0,
227219 }),
228220 });
229221 self.header_dirty = true;
......@@ -234,19 +226,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
234226 self.debug_str_section_index = @intCast(u16, dwarf_segment.sections.items.len);
235227 assert(self.debug_string_table.items.len == 0);
236228
237 try dwarf_segment.addSection(allocator, .{
238 .sectname = makeStaticString("__debug_str"),
239 .segname = makeStaticString("__DWARF"),
229 try dwarf_segment.addSection(allocator, "__debug_str", "__DWARF", .{
240230 .addr = dwarf_segment.inner.vmaddr,
241231 .size = @intCast(u32, self.debug_string_table.items.len),
242232 .offset = @intCast(u32, dwarf_segment.inner.fileoff),
243233 .@"align" = 1,
244 .reloff = 0,
245 .nreloc = 0,
246 .flags = macho.S_REGULAR,
247 .reserved1 = 0,
248 .reserved2 = 0,
249 .reserved3 = 0,
250234 });
251235 self.header_dirty = true;
252236 self.load_commands_dirty = true;
......@@ -262,19 +246,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
262246
263247 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, .{
266 .sectname = makeStaticString("__debug_info"),
267 .segname = makeStaticString("__DWARF"),
249 try dwarf_segment.addSection(allocator, "__debug_info", "__DWARF", .{
268250 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
269251 .size = file_size_hint,
270252 .offset = @intCast(u32, off),
271253 .@"align" = p_align,
272 .reloff = 0,
273 .nreloc = 0,
274 .flags = macho.S_REGULAR,
275 .reserved1 = 0,
276 .reserved2 = 0,
277 .reserved3 = 0,
278254 });
279255 self.header_dirty = true;
280256 self.load_commands_dirty = true;
......@@ -290,19 +266,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
290266
291267 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, .{
294 .sectname = makeStaticString("__debug_abbrev"),
295 .segname = makeStaticString("__DWARF"),
269 try dwarf_segment.addSection(allocator, "__debug_abbrev", "__DWARF", .{
296270 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
297271 .size = file_size_hint,
298272 .offset = @intCast(u32, off),
299273 .@"align" = p_align,
300 .reloff = 0,
301 .nreloc = 0,
302 .flags = macho.S_REGULAR,
303 .reserved1 = 0,
304 .reserved2 = 0,
305 .reserved3 = 0,
306274 });
307275 self.header_dirty = true;
308276 self.load_commands_dirty = true;
......@@ -318,19 +286,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
318286
319287 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, .{
322 .sectname = makeStaticString("__debug_aranges"),
323 .segname = makeStaticString("__DWARF"),
289 try dwarf_segment.addSection(allocator, "__debug_aranges", "__DWARF", .{
324290 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
325291 .size = file_size_hint,
326292 .offset = @intCast(u32, off),
327293 .@"align" = p_align,
328 .reloff = 0,
329 .nreloc = 0,
330 .flags = macho.S_REGULAR,
331 .reserved1 = 0,
332 .reserved2 = 0,
333 .reserved3 = 0,
334294 });
335295 self.header_dirty = true;
336296 self.load_commands_dirty = true;
......@@ -346,19 +306,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
346306
347307 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, .{
350 .sectname = makeStaticString("__debug_line"),
351 .segname = makeStaticString("__DWARF"),
309 try dwarf_segment.addSection(allocator, "__debug_line", "__DWARF", .{
352310 .addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
353311 .size = file_size_hint,
354312 .offset = @intCast(u32, off),
355313 .@"align" = p_align,
356 .reloff = 0,
357 .nreloc = 0,
358 .flags = macho.S_REGULAR,
359 .reserved1 = 0,
360 .reserved2 = 0,
361 .reserved3 = 0,
362314 });
363315 self.header_dirty = true;
364316 self.load_commands_dirty = true;
......@@ -692,14 +644,10 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
692644}
693645
694646fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !SegmentCommand {
695 var cmd = SegmentCommand.empty(.{
696 .cmd = macho.LC_SEGMENT_64,
647 var cmd = SegmentCommand.empty("", .{
697648 .cmdsize = base_cmd.inner.cmdsize,
698 .segname = undefined,
699649 .vmaddr = base_cmd.inner.vmaddr,
700650 .vmsize = base_cmd.inner.vmsize,
701 .fileoff = 0,
702 .filesize = 0,
703651 .maxprot = base_cmd.inner.maxprot,
704652 .initprot = base_cmd.inner.initprot,
705653 .nsects = base_cmd.inner.nsects,
src/link/MachO/Stub.zig+42-18
......@@ -60,7 +60,7 @@ pub fn parse(self: *Stub) !void {
6060 const lib_stub = self.lib_stub orelse return error.EmptyStubFile;
6161 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
6565 const umbrella_lib = lib_stub.inner[0];
6666 self.id = .{
......@@ -93,14 +93,26 @@ pub fn parse(self: *Stub) !void {
9393
9494 if (exp.objc_classes) |classes| {
9595 for (classes) |sym_name| {
96 log.warn(" | {s}", .{sym_name});
97 const actual_sym_name = try std.fmt.allocPrint(
98 self.allocator,
99 "_OBJC_CLASS_$_{s}",
100 .{sym_name},
101 );
102 if (self.symbols.contains(actual_sym_name)) continue;
103 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
96 log.debug(" | {s}", .{sym_name});
97 {
98 const actual_sym_name = try std.fmt.allocPrint(
99 self.allocator,
100 "_OBJC_CLASS_$_{s}",
101 .{sym_name},
102 );
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 }
104116 }
105117 }
106118 }
......@@ -118,16 +130,28 @@ pub fn parse(self: *Stub) !void {
118130 }
119131
120132 if (stub.objc_classes) |classes| {
121 log.warn(" | objc_classes", .{});
133 log.debug(" | objc_classes", .{});
122134 for (classes) |sym_name| {
123 log.warn(" | {s}", .{sym_name});
124 const actual_sym_name = try std.fmt.allocPrint(
125 self.allocator,
126 "_OBJC_METACLASS_$_{s}",
127 .{sym_name},
128 );
129 if (self.symbols.contains(actual_sym_name)) continue;
130 try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
135 log.debug(" | {s}", .{sym_name});
136 {
137 const actual_sym_name = try std.fmt.allocPrint(
138 self.allocator,
139 "_OBJC_CLASS_$_{s}",
140 .{sym_name},
141 );
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 }
131155 }
132156 }
133157 }
src/link/MachO/Zld.zig+43-368
......@@ -79,6 +79,8 @@ mod_init_func_section_index: ?u16 = null,
7979mod_term_func_section_index: ?u16 = null,
8080data_const_section_index: ?u16 = null,
8181
82objc_cfstring_section_index: ?u16 = null,
83
8284// __DATA segment sections
8385tlv_section_index: ?u16 = null,
8486tlv_data_section_index: ?u16 = null,
......@@ -515,39 +517,15 @@ fn updateMetadata(self: *Zld) !void {
515517 if (self.text_const_section_index != null) continue;
516518
517519 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);
518 try text_seg.addSection(self.allocator, .{
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 });
520 try text_seg.addSection(self.allocator, "__const", "__TEXT", .{});
532521 continue;
533522 },
534523 macho.S_CSTRING_LITERALS => {
535524 if (self.cstring_section_index != null) continue;
536525
537526 self.cstring_section_index = @intCast(u16, text_seg.sections.items.len);
538 try text_seg.addSection(self.allocator, .{
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,
527 try text_seg.addSection(self.allocator, "__cstring", "__TEXT", .{
547528 .flags = macho.S_CSTRING_LITERALS,
548 .reserved1 = 0,
549 .reserved2 = 0,
550 .reserved3 = 0,
551529 });
552530 continue;
553531 },
......@@ -555,19 +533,8 @@ fn updateMetadata(self: *Zld) !void {
555533 if (self.mod_init_func_section_index != null) continue;
556534
557535 self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len);
558 try data_const_seg.addSection(self.allocator, .{
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,
536 try data_const_seg.addSection(self.allocator, "__mod_init_func", "__DATA_CONST", .{
567537 .flags = macho.S_MOD_INIT_FUNC_POINTERS,
568 .reserved1 = 0,
569 .reserved2 = 0,
570 .reserved3 = 0,
571538 });
572539 continue;
573540 },
......@@ -575,19 +542,8 @@ fn updateMetadata(self: *Zld) !void {
575542 if (self.mod_term_func_section_index != null) continue;
576543
577544 self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len);
578 try data_const_seg.addSection(self.allocator, .{
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,
545 try data_const_seg.addSection(self.allocator, "__mod_term_func", "__DATA_CONST", .{
587546 .flags = macho.S_MOD_TERM_FUNC_POINTERS,
588 .reserved1 = 0,
589 .reserved2 = 0,
590 .reserved3 = 0,
591547 });
592548 continue;
593549 },
......@@ -596,37 +552,15 @@ fn updateMetadata(self: *Zld) !void {
596552 if (self.common_section_index != null) continue;
597553
598554 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
599 try data_seg.addSection(self.allocator, .{
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,
555 try data_seg.addSection(self.allocator, "__common", "__DATA", .{
608556 .flags = macho.S_ZEROFILL,
609 .reserved1 = 0,
610 .reserved2 = 0,
611 .reserved3 = 0,
612557 });
613558 } else {
614559 if (self.bss_section_index != null) continue;
615560
616561 self.bss_section_index = @intCast(u16, data_seg.sections.items.len);
617 try data_seg.addSection(self.allocator, .{
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,
562 try data_seg.addSection(self.allocator, "__bss", "__DATA", .{
626563 .flags = macho.S_ZEROFILL,
627 .reserved1 = 0,
628 .reserved2 = 0,
629 .reserved3 = 0,
630564 });
631565 }
632566 continue;
......@@ -635,19 +569,8 @@ fn updateMetadata(self: *Zld) !void {
635569 if (self.tlv_section_index != null) continue;
636570
637571 self.tlv_section_index = @intCast(u16, data_seg.sections.items.len);
638 try data_seg.addSection(self.allocator, .{
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,
572 try data_seg.addSection(self.allocator, "__thread_vars", "__DATA", .{
647573 .flags = macho.S_THREAD_LOCAL_VARIABLES,
648 .reserved1 = 0,
649 .reserved2 = 0,
650 .reserved3 = 0,
651574 });
652575 continue;
653576 },
......@@ -655,19 +578,8 @@ fn updateMetadata(self: *Zld) !void {
655578 if (self.tlv_data_section_index != null) continue;
656579
657580 self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len);
658 try data_seg.addSection(self.allocator, .{
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,
581 try data_seg.addSection(self.allocator, "__thread_data", "__DATA", .{
667582 .flags = macho.S_THREAD_LOCAL_REGULAR,
668 .reserved1 = 0,
669 .reserved2 = 0,
670 .reserved3 = 0,
671583 });
672584 continue;
673585 },
......@@ -675,19 +587,8 @@ fn updateMetadata(self: *Zld) !void {
675587 if (self.tlv_bss_section_index != null) continue;
676588
677589 self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len);
678 try data_seg.addSection(self.allocator, .{
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,
590 try data_seg.addSection(self.allocator, "__thread_bss", "__DATA", .{
687591 .flags = macho.S_THREAD_LOCAL_ZEROFILL,
688 .reserved1 = 0,
689 .reserved2 = 0,
690 .reserved3 = 0,
691592 });
692593 continue;
693594 },
......@@ -698,20 +599,7 @@ fn updateMetadata(self: *Zld) !void {
698599 if (self.eh_frame_section_index != null) continue;
699600
700601 self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len);
701 try text_seg.addSection(self.allocator, .{
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 });
602 try text_seg.addSection(self.allocator, "__eh_frame", "__TEXT", .{});
715603 continue;
716604 }
717605
......@@ -719,20 +607,7 @@ fn updateMetadata(self: *Zld) !void {
719607 if (self.data_const_section_index != null) continue;
720608
721609 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
722 try data_const_seg.addSection(self.allocator, .{
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 });
610 try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
736611 continue;
737612 },
738613 macho.S_REGULAR => {
......@@ -740,19 +615,8 @@ fn updateMetadata(self: *Zld) !void {
740615 if (self.text_section_index != null) continue;
741616
742617 self.text_section_index = @intCast(u16, text_seg.sections.items.len);
743 try text_seg.addSection(self.allocator, .{
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,
618 try text_seg.addSection(self.allocator, "__text", "__TEXT", .{
752619 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
753 .reserved1 = 0,
754 .reserved2 = 0,
755 .reserved3 = 0,
756620 });
757621 continue;
758622 }
......@@ -771,56 +635,17 @@ fn updateMetadata(self: *Zld) !void {
771635 if (self.ustring_section_index != null) continue;
772636
773637 self.ustring_section_index = @intCast(u16, text_seg.sections.items.len);
774 try text_seg.addSection(self.allocator, .{
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 });
638 try text_seg.addSection(self.allocator, "__ustring", "__TEXT", .{});
788639 } else if (mem.eql(u8, sectname, "__gcc_except_tab")) {
789640 if (self.gcc_except_tab_section_index != null) continue;
790641
791642 self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len);
792 try text_seg.addSection(self.allocator, .{
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 });
643 try text_seg.addSection(self.allocator, "__gcc_except_tab", "__TEXT", .{});
806644 } else {
807645 if (self.text_const_section_index != null) continue;
808646
809647 self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);
810 try text_seg.addSection(self.allocator, .{
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 });
648 try text_seg.addSection(self.allocator, "__const", "__TEXT", .{});
824649 }
825650 continue;
826651 }
......@@ -829,20 +654,7 @@ fn updateMetadata(self: *Zld) !void {
829654 if (self.data_const_section_index != null) continue;
830655
831656 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
832 try data_const_seg.addSection(self.allocator, .{
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 });
657 try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
846658 continue;
847659 }
848660
......@@ -851,38 +663,17 @@ fn updateMetadata(self: *Zld) !void {
851663 if (self.data_const_section_index != null) continue;
852664
853665 self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
854 try data_const_seg.addSection(self.allocator, .{
855 .sectname = makeStaticString("__const"),
856 .segname = makeStaticString("__DATA_CONST"),
857 .addr = 0,
858 .size = 0,
859 .offset = 0,
860 .@"align" = 0,
861 .reloff = 0,
862 .nreloc = 0,
863 .flags = macho.S_REGULAR,
864 .reserved1 = 0,
865 .reserved2 = 0,
866 .reserved3 = 0,
867 });
666 try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
667 } else if (mem.eql(u8, sectname, "__cfstring")) {
668 if (self.objc_cfstring_section_index != null) continue;
669
670 self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len);
671 try data_const_seg.addSection(self.allocator, "__cfstring", "__DATA_CONST", .{});
868672 } else {
869673 if (self.data_section_index != null) continue;
870674
871675 self.data_section_index = @intCast(u16, data_seg.sections.items.len);
872 try data_seg.addSection(self.allocator, .{
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 });
676 try data_seg.addSection(self.allocator, "__data", "__DATA", .{});
886677 }
887678
888679 continue;
......@@ -932,19 +723,8 @@ fn updateMetadata(self: *Zld) !void {
932723 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
933724 const common_section_index = self.common_section_index orelse ind: {
934725 self.common_section_index = @intCast(u16, data_seg.sections.items.len);
935 try data_seg.addSection(self.allocator, .{
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,
726 try data_seg.addSection(self.allocator, "__common", "__DATA", .{
944727 .flags = macho.S_ZEROFILL,
945 .reserved1 = 0,
946 .reserved2 = 0,
947 .reserved3 = 0,
948728 });
949729 break :ind self.common_section_index.?;
950730 };
......@@ -1136,6 +916,11 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection {
1136916 .seg = self.data_const_segment_cmd_index.?,
1137917 .sect = self.data_const_section_index.?,
1138918 };
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 };
1139924 }
1140925 break :blk .{
1141926 .seg = self.data_segment_cmd_index.?,
......@@ -1200,6 +985,7 @@ fn sortSections(self: *Zld) !void {
1200985 &self.mod_init_func_section_index,
1201986 &self.mod_term_func_section_index,
1202987 &self.data_const_section_index,
988 &self.objc_cfstring_section_index,
1203989 };
1204990 for (indices) |maybe_index| {
1205991 const new_index: u16 = if (maybe_index.*) |index| blk: {
......@@ -2240,18 +2026,8 @@ fn populateMetadata(self: *Zld) !void {
22402026 if (self.pagezero_segment_cmd_index == null) {
22412027 self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
22422028 try self.load_commands.append(self.allocator, .{
2243 .Segment = SegmentCommand.empty(.{
2244 .cmd = macho.LC_SEGMENT_64,
2245 .cmdsize = @sizeOf(macho.segment_command_64),
2246 .segname = makeStaticString("__PAGEZERO"),
2247 .vmaddr = 0,
2029 .Segment = SegmentCommand.empty("__PAGEZERO", .{
22482030 .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,
22552031 }),
22562032 });
22572033 }
......@@ -2259,18 +2035,10 @@ fn populateMetadata(self: *Zld) !void {
22592035 if (self.text_segment_cmd_index == null) {
22602036 self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
22612037 try self.load_commands.append(self.allocator, .{
2262 .Segment = SegmentCommand.empty(.{
2263 .cmd = macho.LC_SEGMENT_64,
2264 .cmdsize = @sizeOf(macho.segment_command_64),
2265 .segname = makeStaticString("__TEXT"),
2038 .Segment = SegmentCommand.empty("__TEXT", .{
22662039 .vmaddr = 0x100000000, // always starts at 4GB
2267 .vmsize = 0,
2268 .fileoff = 0,
2269 .filesize = 0,
22702040 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
22712041 .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
2272 .nsects = 0,
2273 .flags = 0,
22742042 }),
22752043 });
22762044 }
......@@ -2283,19 +2051,9 @@ fn populateMetadata(self: *Zld) !void {
22832051 .aarch64 => 2,
22842052 else => unreachable, // unhandled architecture type
22852053 };
2286 try text_seg.addSection(self.allocator, .{
2287 .sectname = makeStaticString("__text"),
2288 .segname = makeStaticString("__TEXT"),
2289 .addr = 0,
2290 .size = 0,
2291 .offset = 0,
2054 try text_seg.addSection(self.allocator, "__text", "__TEXT", .{
22922055 .@"align" = alignment,
2293 .reloff = 0,
2294 .nreloc = 0,
22952056 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2296 .reserved1 = 0,
2297 .reserved2 = 0,
2298 .reserved3 = 0,
22992057 });
23002058 }
23012059
......@@ -2312,19 +2070,10 @@ fn populateMetadata(self: *Zld) !void {
23122070 .aarch64 => 3 * @sizeOf(u32),
23132071 else => unreachable, // unhandled architecture type
23142072 };
2315 try text_seg.addSection(self.allocator, .{
2316 .sectname = makeStaticString("__stubs"),
2317 .segname = makeStaticString("__TEXT"),
2318 .addr = 0,
2319 .size = 0,
2320 .offset = 0,
2073 try text_seg.addSection(self.allocator, "__stubs", "__TEXT", .{
23212074 .@"align" = alignment,
2322 .reloff = 0,
2323 .nreloc = 0,
23242075 .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2325 .reserved1 = 0,
23262076 .reserved2 = stub_size,
2327 .reserved3 = 0,
23282077 });
23292078 }
23302079
......@@ -2341,37 +2090,19 @@ fn populateMetadata(self: *Zld) !void {
23412090 .aarch64 => 6 * @sizeOf(u32),
23422091 else => unreachable,
23432092 };
2344 try text_seg.addSection(self.allocator, .{
2345 .sectname = makeStaticString("__stub_helper"),
2346 .segname = makeStaticString("__TEXT"),
2347 .addr = 0,
2093 try text_seg.addSection(self.allocator, "__stub_helper", "__TEXT", .{
23482094 .size = stub_helper_size,
2349 .offset = 0,
23502095 .@"align" = alignment,
2351 .reloff = 0,
2352 .nreloc = 0,
23532096 .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
2354 .reserved1 = 0,
2355 .reserved2 = 0,
2356 .reserved3 = 0,
23572097 });
23582098 }
23592099
23602100 if (self.data_const_segment_cmd_index == null) {
23612101 self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
23622102 try self.load_commands.append(self.allocator, .{
2363 .Segment = SegmentCommand.empty(.{
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,
2103 .Segment = SegmentCommand.empty("__DATA_CONST", .{
23712104 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
23722105 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2373 .nsects = 0,
2374 .flags = 0,
23752106 }),
23762107 });
23772108 }
......@@ -2379,37 +2110,18 @@ fn populateMetadata(self: *Zld) !void {
23792110 if (self.got_section_index == null) {
23802111 const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
23812112 self.got_section_index = @intCast(u16, data_const_seg.sections.items.len);
2382 try data_const_seg.addSection(self.allocator, .{
2383 .sectname = makeStaticString("__got"),
2384 .segname = makeStaticString("__DATA_CONST"),
2385 .addr = 0,
2386 .size = 0,
2387 .offset = 0,
2113 try data_const_seg.addSection(self.allocator, "__got", "__DATA_CONST", .{
23882114 .@"align" = 3, // 2^3 = @sizeOf(u64)
2389 .reloff = 0,
2390 .nreloc = 0,
23912115 .flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
2392 .reserved1 = 0,
2393 .reserved2 = 0,
2394 .reserved3 = 0,
23952116 });
23962117 }
23972118
23982119 if (self.data_segment_cmd_index == null) {
23992120 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
24002121 try self.load_commands.append(self.allocator, .{
2401 .Segment = SegmentCommand.empty(.{
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,
2122 .Segment = SegmentCommand.empty("__DATA", .{
24092123 .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
24102124 .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
2411 .nsects = 0,
2412 .flags = 0,
24132125 }),
24142126 });
24152127 }
......@@ -2417,56 +2129,26 @@ fn populateMetadata(self: *Zld) !void {
24172129 if (self.la_symbol_ptr_section_index == null) {
24182130 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
24192131 self.la_symbol_ptr_section_index = @intCast(u16, data_seg.sections.items.len);
2420 try data_seg.addSection(self.allocator, .{
2421 .sectname = makeStaticString("__la_symbol_ptr"),
2422 .segname = makeStaticString("__DATA"),
2423 .addr = 0,
2424 .size = 0,
2425 .offset = 0,
2132 try data_seg.addSection(self.allocator, "__la_symbol_ptr", "__DATA", .{
24262133 .@"align" = 3, // 2^3 = @sizeOf(u64)
2427 .reloff = 0,
2428 .nreloc = 0,
24292134 .flags = macho.S_LAZY_SYMBOL_POINTERS,
2430 .reserved1 = 0,
2431 .reserved2 = 0,
2432 .reserved3 = 0,
24332135 });
24342136 }
24352137
24362138 if (self.data_section_index == null) {
24372139 const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
24382140 self.data_section_index = @intCast(u16, data_seg.sections.items.len);
2439 try data_seg.addSection(self.allocator, .{
2440 .sectname = makeStaticString("__data"),
2441 .segname = makeStaticString("__DATA"),
2442 .addr = 0,
2443 .size = 0,
2444 .offset = 0,
2141 try data_seg.addSection(self.allocator, "__data", "__DATA", .{
24452142 .@"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,
24522143 });
24532144 }
24542145
24552146 if (self.linkedit_segment_cmd_index == null) {
24562147 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
24572148 try self.load_commands.append(self.allocator, .{
2458 .Segment = SegmentCommand.empty(.{
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,
2149 .Segment = SegmentCommand.empty("__LINKEDIT", .{
24662150 .maxprot = macho.VM_PROT_READ,
24672151 .initprot = macho.VM_PROT_READ,
2468 .nsects = 0,
2469 .flags = 0,
24702152 }),
24712153 });
24722154 }
......@@ -3469,13 +3151,6 @@ fn writeHeader(self: *Zld) !void {
34693151 try self.file.?.pwriteAll(mem.asBytes(&header), 0);
34703152}
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
34793154fn makeString(self: *Zld, bytes: []const u8) !u32 {
34803155 if (self.strtab_dir.get(bytes)) |offset| {
34813156 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;
99
1010const Allocator = std.mem.Allocator;
1111const MachO = @import("../MachO.zig");
12const makeStaticString = MachO.makeStaticString;
1312const padToIdeal = MachO.padToIdeal;
1413
1514pub const LoadCommand = union(enum) {
......@@ -187,12 +186,70 @@ pub const SegmentCommand = struct {
187186 inner: macho.segment_command_64,
188187 sections: std.ArrayListUnmanaged(macho.section_64) = .{},
189188
190 pub fn empty(inner: macho.segment_command_64) SegmentCommand {
191 return .{ .inner = inner };
189 const SegmentOptions = struct {
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 };
192217 }
193218
194 pub fn addSection(self: *SegmentCommand, alloc: *Allocator, section: macho.section_64) !void {
195 try self.sections.append(alloc, section);
219 const SectionOptions = struct {
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 });
196253 self.inner.cmdsize += @sizeOf(macho.section_64);
197254 self.inner.nsects += 1;
198255 }
......@@ -338,6 +395,13 @@ pub fn createLoadDylibCommand(
338395 return dylib_cmd;
339396}
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
341405fn testRead(allocator: *Allocator, buffer: []const u8, expected: anytype) !void {
342406 var stream = io.fixedBufferStream(buffer);
343407 var given = try LoadCommand.read(allocator, stream.reader());