aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-06-21 11:11:19 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-06-24 18:53:42 +0200
commit852e1ed23cb5cfdb687a52c39fa9c60be3159730 (patch)
tree2ba86d658697c66801b3f0fe6951e6288a110b4c /src
parent72f2f68938d626299e2bb5aa3b8932a45d4ae778 (diff)
downloadzig-852e1ed23cb5cfdb687a52c39fa9c60be3159730.tar.gz
zig-852e1ed23cb5cfdb687a52c39fa9c60be3159730.zip
zld+stage2: refactor creating segments and sections
Move the logic into default-init structs part of constructors in `SegmentCommand` struct in `commands.zig` module.
Diffstat (limited to 'src')
-rw-r--r--src/link/MachO.zig105
-rw-r--r--src/link/MachO/DebugSymbols.zig66
-rw-r--r--src/link/MachO/Stub.zig60
-rw-r--r--src/link/MachO/Zld.zig411
-rw-r--r--src/link/MachO/commands.zig74
5 files changed, 172 insertions, 544 deletions
diff --git a/src/link/MachO.zig b/src/link/MachO.zig
index c16957b97d..cc00cafe3e 100644
--- a/src/link/MachO.zig
+++ b/src/link/MachO.zig
@@ -1779,18 +1779,8 @@ pub fn populateMissingMetadata(self: *MachO) !void {
if (self.pagezero_segment_cmd_index == null) {
self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
try self.load_commands.append(self.base.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__PAGEZERO"),
- .vmaddr = 0,
+ .Segment = SegmentCommand.empty("__PAGEZERO", .{
.vmsize = 0x100000000, // size always set to 4GB
- .fileoff = 0,
- .filesize = 0,
- .maxprot = 0,
- .initprot = 0,
- .nsects = 0,
- .flags = 0,
}),
});
self.header_dirty = true;
@@ -1809,18 +1799,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });
try self.load_commands.append(self.base.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__TEXT"),
+ .Segment = SegmentCommand.empty("__TEXT", .{
.vmaddr = 0x100000000, // always starts at 4GB
.vmsize = needed_size,
- .fileoff = 0,
.filesize = needed_size,
.maxprot = maxprot,
.initprot = initprot,
- .nsects = 0,
- .flags = 0,
}),
});
self.header_dirty = true;
@@ -1841,19 +1825,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __text section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
- try text_segment.addSection(self.base.allocator, .{
- .sectname = makeStaticString("__text"),
- .segname = makeStaticString("__TEXT"),
+ try text_segment.addSection(self.base.allocator, "__text", "__TEXT", .{
.addr = text_segment.inner.vmaddr + off,
.size = @intCast(u32, needed_size),
.offset = @intCast(u32, off),
.@"align" = alignment,
- .reloff = 0,
- .nreloc = 0,
.flags = flags,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -1879,19 +1856,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __stubs section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
- try text_segment.addSection(self.base.allocator, .{
- .sectname = makeStaticString("__stubs"),
- .segname = makeStaticString("__TEXT"),
+ try text_segment.addSection(self.base.allocator, "__stubs", "__TEXT", .{
.addr = text_segment.inner.vmaddr + off,
.size = needed_size,
.offset = @intCast(u32, off),
.@"align" = alignment,
- .reloff = 0,
- .nreloc = 0,
.flags = flags,
- .reserved1 = 0,
.reserved2 = stub_size,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -1912,19 +1883,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __stub_helper section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
- try text_segment.addSection(self.base.allocator, .{
- .sectname = makeStaticString("__stub_helper"),
- .segname = makeStaticString("__TEXT"),
+ try text_segment.addSection(self.base.allocator, "__stub_helper", "__TEXT", .{
.addr = text_segment.inner.vmaddr + off,
.size = needed_size,
.offset = @intCast(u32, off),
.@"align" = alignment,
- .reloff = 0,
- .nreloc = 0,
.flags = flags,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -1941,18 +1905,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
try self.load_commands.append(self.base.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__DATA_CONST"),
+ .Segment = SegmentCommand.empty("__DATA_CONST", .{
.vmaddr = address_and_offset.address,
.vmsize = needed_size,
.fileoff = address_and_offset.offset,
.filesize = needed_size,
.maxprot = maxprot,
.initprot = initprot,
- .nsects = 0,
- .flags = 0,
}),
});
self.header_dirty = true;
@@ -1969,19 +1928,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __got section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
- try dc_segment.addSection(self.base.allocator, .{
- .sectname = makeStaticString("__got"),
- .segname = makeStaticString("__DATA_CONST"),
+ try dc_segment.addSection(self.base.allocator, "__got", "__DATA_CONST", .{
.addr = dc_segment.inner.vmaddr + off - dc_segment.inner.fileoff,
.size = needed_size,
.offset = @intCast(u32, off),
.@"align" = 3, // 2^3 = @sizeOf(u64)
- .reloff = 0,
- .nreloc = 0,
.flags = flags,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -1998,18 +1950,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
try self.load_commands.append(self.base.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__DATA"),
+ .Segment = SegmentCommand.empty("__DATA", .{
.vmaddr = address_and_offset.address,
.vmsize = needed_size,
.fileoff = address_and_offset.offset,
.filesize = needed_size,
.maxprot = maxprot,
.initprot = initprot,
- .nsects = 0,
- .flags = 0,
}),
});
self.header_dirty = true;
@@ -2026,19 +1973,12 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __la_symbol_ptr section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
- try data_segment.addSection(self.base.allocator, .{
- .sectname = makeStaticString("__la_symbol_ptr"),
- .segname = makeStaticString("__DATA"),
+ try data_segment.addSection(self.base.allocator, "__la_symbol_ptr", "__DATA", .{
.addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
.size = needed_size,
.offset = @intCast(u32, off),
.@"align" = 3, // 2^3 = @sizeOf(u64)
- .reloff = 0,
- .nreloc = 0,
.flags = flags,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -2047,26 +1987,17 @@ pub fn populateMissingMetadata(self: *MachO) !void {
const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
self.data_section_index = @intCast(u16, data_segment.sections.items.len);
- const flags = macho.S_REGULAR;
const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
log.debug("found __data section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
- try data_segment.addSection(self.base.allocator, .{
- .sectname = makeStaticString("__data"),
- .segname = makeStaticString("__DATA"),
+ try data_segment.addSection(self.base.allocator, "__data", "__DATA", .{
.addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
.size = needed_size,
.offset = @intCast(u32, off),
.@"align" = 3, // 2^3 = @sizeOf(u64)
- .reloff = 0,
- .nreloc = 0,
- .flags = flags,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -2081,18 +2012,11 @@ pub fn populateMissingMetadata(self: *MachO) !void {
log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset});
try self.load_commands.append(self.base.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__LINKEDIT"),
+ .Segment = SegmentCommand.empty("__LINKEDIT", .{
.vmaddr = address_and_offset.address,
- .vmsize = 0,
.fileoff = address_and_offset.offset,
- .filesize = 0,
.maxprot = maxprot,
.initprot = initprot,
- .nsects = 0,
- .flags = 0,
}),
});
self.header_dirty = true;
@@ -2450,13 +2374,6 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
return vaddr;
}
-pub fn makeStaticString(comptime bytes: []const u8) [16]u8 {
- var buf = [_]u8{0} ** 16;
- if (bytes.len > buf.len) @compileError("string too long; max 16 bytes");
- mem.copy(u8, &buf, bytes);
- return buf;
-}
-
fn makeString(self: *MachO, bytes: []const u8) !u32 {
if (self.string_table_directory.get(bytes)) |offset| {
log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset });
diff --git a/src/link/MachO/DebugSymbols.zig b/src/link/MachO/DebugSymbols.zig
index 2b10f3307b..c26ce889ae 100644
--- a/src/link/MachO/DebugSymbols.zig
+++ b/src/link/MachO/DebugSymbols.zig
@@ -19,7 +19,6 @@ const MachO = @import("../MachO.zig");
const SrcFn = MachO.SrcFn;
const TextBlock = MachO.TextBlock;
const padToIdeal = MachO.padToIdeal;
-const makeStaticString = MachO.makeStaticString;
usingnamespace @import("commands.zig");
@@ -212,18 +211,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
log.debug("found dSym __DWARF segment free space 0x{x} to 0x{x}", .{ off, off + needed_size });
try self.load_commands.append(allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__DWARF"),
+ .Segment = SegmentCommand.empty("__DWARF", .{
.vmaddr = vmaddr,
.vmsize = needed_size,
.fileoff = off,
.filesize = needed_size,
- .maxprot = 0,
- .initprot = 0,
- .nsects = 0,
- .flags = 0,
}),
});
self.header_dirty = true;
@@ -234,19 +226,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
self.debug_str_section_index = @intCast(u16, dwarf_segment.sections.items.len);
assert(self.debug_string_table.items.len == 0);
- try dwarf_segment.addSection(allocator, .{
- .sectname = makeStaticString("__debug_str"),
- .segname = makeStaticString("__DWARF"),
+ try dwarf_segment.addSection(allocator, "__debug_str", "__DWARF", .{
.addr = dwarf_segment.inner.vmaddr,
.size = @intCast(u32, self.debug_string_table.items.len),
.offset = @intCast(u32, dwarf_segment.inner.fileoff),
.@"align" = 1,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -262,19 +246,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
log.debug("found dSym __debug_info free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
- try dwarf_segment.addSection(allocator, .{
- .sectname = makeStaticString("__debug_info"),
- .segname = makeStaticString("__DWARF"),
+ try dwarf_segment.addSection(allocator, "__debug_info", "__DWARF", .{
.addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
.size = file_size_hint,
.offset = @intCast(u32, off),
.@"align" = p_align,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -290,19 +266,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
log.debug("found dSym __debug_abbrev free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
- try dwarf_segment.addSection(allocator, .{
- .sectname = makeStaticString("__debug_abbrev"),
- .segname = makeStaticString("__DWARF"),
+ try dwarf_segment.addSection(allocator, "__debug_abbrev", "__DWARF", .{
.addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
.size = file_size_hint,
.offset = @intCast(u32, off),
.@"align" = p_align,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -318,19 +286,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
log.debug("found dSym __debug_aranges free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
- try dwarf_segment.addSection(allocator, .{
- .sectname = makeStaticString("__debug_aranges"),
- .segname = makeStaticString("__DWARF"),
+ try dwarf_segment.addSection(allocator, "__debug_aranges", "__DWARF", .{
.addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
.size = file_size_hint,
.offset = @intCast(u32, off),
.@"align" = p_align,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -346,19 +306,11 @@ pub fn populateMissingMetadata(self: *DebugSymbols, allocator: *Allocator) !void
log.debug("found dSym __debug_line free space 0x{x} to 0x{x}", .{ off, off + file_size_hint });
- try dwarf_segment.addSection(allocator, .{
- .sectname = makeStaticString("__debug_line"),
- .segname = makeStaticString("__DWARF"),
+ try dwarf_segment.addSection(allocator, "__debug_line", "__DWARF", .{
.addr = dwarf_segment.inner.vmaddr + off - dwarf_segment.inner.fileoff,
.size = file_size_hint,
.offset = @intCast(u32, off),
.@"align" = p_align,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
self.header_dirty = true;
self.load_commands_dirty = true;
@@ -692,14 +644,10 @@ pub fn deinit(self: *DebugSymbols, allocator: *Allocator) void {
}
fn copySegmentCommand(self: *DebugSymbols, allocator: *Allocator, base_cmd: SegmentCommand) !SegmentCommand {
- var cmd = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
+ var cmd = SegmentCommand.empty("", .{
.cmdsize = base_cmd.inner.cmdsize,
- .segname = undefined,
.vmaddr = base_cmd.inner.vmaddr,
.vmsize = base_cmd.inner.vmsize,
- .fileoff = 0,
- .filesize = 0,
.maxprot = base_cmd.inner.maxprot,
.initprot = base_cmd.inner.initprot,
.nsects = base_cmd.inner.nsects,
diff --git a/src/link/MachO/Stub.zig b/src/link/MachO/Stub.zig
index 6111690a7d..d71c454c79 100644
--- a/src/link/MachO/Stub.zig
+++ b/src/link/MachO/Stub.zig
@@ -60,7 +60,7 @@ pub fn parse(self: *Stub) !void {
const lib_stub = self.lib_stub orelse return error.EmptyStubFile;
if (lib_stub.inner.len == 0) return error.EmptyStubFile;
- log.warn("parsing shared library from stub '{s}'", .{self.name.?});
+ log.debug("parsing shared library from stub '{s}'", .{self.name.?});
const umbrella_lib = lib_stub.inner[0];
self.id = .{
@@ -93,14 +93,26 @@ pub fn parse(self: *Stub) !void {
if (exp.objc_classes) |classes| {
for (classes) |sym_name| {
- log.warn(" | {s}", .{sym_name});
- const actual_sym_name = try std.fmt.allocPrint(
- self.allocator,
- "_OBJC_CLASS_$_{s}",
- .{sym_name},
- );
- if (self.symbols.contains(actual_sym_name)) continue;
- try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
+ log.debug(" | {s}", .{sym_name});
+ {
+ const actual_sym_name = try std.fmt.allocPrint(
+ self.allocator,
+ "_OBJC_CLASS_$_{s}",
+ .{sym_name},
+ );
+ if (self.symbols.contains(actual_sym_name)) continue;
+ try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
+ }
+
+ {
+ const actual_sym_name = try std.fmt.allocPrint(
+ self.allocator,
+ "_OBJC_METACLASS_$_{s}",
+ .{sym_name},
+ );
+ if (self.symbols.contains(actual_sym_name)) continue;
+ try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
+ }
}
}
}
@@ -118,16 +130,28 @@ pub fn parse(self: *Stub) !void {
}
if (stub.objc_classes) |classes| {
- log.warn(" | objc_classes", .{});
+ log.debug(" | objc_classes", .{});
for (classes) |sym_name| {
- log.warn(" | {s}", .{sym_name});
- const actual_sym_name = try std.fmt.allocPrint(
- self.allocator,
- "_OBJC_METACLASS_$_{s}",
- .{sym_name},
- );
- if (self.symbols.contains(actual_sym_name)) continue;
- try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
+ log.debug(" | {s}", .{sym_name});
+ {
+ const actual_sym_name = try std.fmt.allocPrint(
+ self.allocator,
+ "_OBJC_CLASS_$_{s}",
+ .{sym_name},
+ );
+ if (self.symbols.contains(actual_sym_name)) continue;
+ try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
+ }
+
+ {
+ const actual_sym_name = try std.fmt.allocPrint(
+ self.allocator,
+ "_OBJC_METACLASS_$_{s}",
+ .{sym_name},
+ );
+ if (self.symbols.contains(actual_sym_name)) continue;
+ try self.symbols.putNoClobber(self.allocator, actual_sym_name, {});
+ }
}
}
}
diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig
index 0a9d209c61..3f30379ca5 100644
--- a/src/link/MachO/Zld.zig
+++ b/src/link/MachO/Zld.zig
@@ -79,6 +79,8 @@ mod_init_func_section_index: ?u16 = null,
mod_term_func_section_index: ?u16 = null,
data_const_section_index: ?u16 = null,
+objc_cfstring_section_index: ?u16 = null,
+
// __DATA segment sections
tlv_section_index: ?u16 = null,
tlv_data_section_index: ?u16 = null,
@@ -515,39 +517,15 @@ fn updateMetadata(self: *Zld) !void {
if (self.text_const_section_index != null) continue;
self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__const"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try text_seg.addSection(self.allocator, "__const", "__TEXT", .{});
continue;
},
macho.S_CSTRING_LITERALS => {
if (self.cstring_section_index != null) continue;
self.cstring_section_index = @intCast(u16, text_seg.sections.items.len);
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__cstring"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try text_seg.addSection(self.allocator, "__cstring", "__TEXT", .{
.flags = macho.S_CSTRING_LITERALS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
continue;
},
@@ -555,19 +533,8 @@ fn updateMetadata(self: *Zld) !void {
if (self.mod_init_func_section_index != null) continue;
self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len);
- try data_const_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__mod_init_func"),
- .segname = makeStaticString("__DATA_CONST"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_const_seg.addSection(self.allocator, "__mod_init_func", "__DATA_CONST", .{
.flags = macho.S_MOD_INIT_FUNC_POINTERS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
continue;
},
@@ -575,19 +542,8 @@ fn updateMetadata(self: *Zld) !void {
if (self.mod_term_func_section_index != null) continue;
self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len);
- try data_const_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__mod_term_func"),
- .segname = makeStaticString("__DATA_CONST"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_const_seg.addSection(self.allocator, "__mod_term_func", "__DATA_CONST", .{
.flags = macho.S_MOD_TERM_FUNC_POINTERS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
continue;
},
@@ -596,37 +552,15 @@ fn updateMetadata(self: *Zld) !void {
if (self.common_section_index != null) continue;
self.common_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__common"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_seg.addSection(self.allocator, "__common", "__DATA", .{
.flags = macho.S_ZEROFILL,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
} else {
if (self.bss_section_index != null) continue;
self.bss_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__bss"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_seg.addSection(self.allocator, "__bss", "__DATA", .{
.flags = macho.S_ZEROFILL,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
}
continue;
@@ -635,19 +569,8 @@ fn updateMetadata(self: *Zld) !void {
if (self.tlv_section_index != null) continue;
self.tlv_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__thread_vars"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_seg.addSection(self.allocator, "__thread_vars", "__DATA", .{
.flags = macho.S_THREAD_LOCAL_VARIABLES,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
continue;
},
@@ -655,19 +578,8 @@ fn updateMetadata(self: *Zld) !void {
if (self.tlv_data_section_index != null) continue;
self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__thread_data"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_seg.addSection(self.allocator, "__thread_data", "__DATA", .{
.flags = macho.S_THREAD_LOCAL_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
continue;
},
@@ -675,19 +587,8 @@ fn updateMetadata(self: *Zld) !void {
if (self.tlv_bss_section_index != null) continue;
self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__thread_bss"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_seg.addSection(self.allocator, "__thread_bss", "__DATA", .{
.flags = macho.S_THREAD_LOCAL_ZEROFILL,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
continue;
},
@@ -698,20 +599,7 @@ fn updateMetadata(self: *Zld) !void {
if (self.eh_frame_section_index != null) continue;
self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len);
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__eh_frame"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try text_seg.addSection(self.allocator, "__eh_frame", "__TEXT", .{});
continue;
}
@@ -719,20 +607,7 @@ fn updateMetadata(self: *Zld) !void {
if (self.data_const_section_index != null) continue;
self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
- try data_const_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__const"),
- .segname = makeStaticString("__DATA_CONST"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
continue;
},
macho.S_REGULAR => {
@@ -740,19 +615,8 @@ fn updateMetadata(self: *Zld) !void {
if (self.text_section_index != null) continue;
self.text_section_index = @intCast(u16, text_seg.sections.items.len);
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__text"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try text_seg.addSection(self.allocator, "__text", "__TEXT", .{
.flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
continue;
}
@@ -771,56 +635,17 @@ fn updateMetadata(self: *Zld) !void {
if (self.ustring_section_index != null) continue;
self.ustring_section_index = @intCast(u16, text_seg.sections.items.len);
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__ustring"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try text_seg.addSection(self.allocator, "__ustring", "__TEXT", .{});
} else if (mem.eql(u8, sectname, "__gcc_except_tab")) {
if (self.gcc_except_tab_section_index != null) continue;
self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len);
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__gcc_except_tab"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try text_seg.addSection(self.allocator, "__gcc_except_tab", "__TEXT", .{});
} else {
if (self.text_const_section_index != null) continue;
self.text_const_section_index = @intCast(u16, text_seg.sections.items.len);
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__const"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try text_seg.addSection(self.allocator, "__const", "__TEXT", .{});
}
continue;
}
@@ -829,20 +654,7 @@ fn updateMetadata(self: *Zld) !void {
if (self.data_const_section_index != null) continue;
self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
- try data_const_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__const"),
- .segname = makeStaticString("__DATA_CONST"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
continue;
}
@@ -851,38 +663,17 @@ fn updateMetadata(self: *Zld) !void {
if (self.data_const_section_index != null) continue;
self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len);
- try data_const_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__const"),
- .segname = makeStaticString("__DATA_CONST"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{});
+ } else if (mem.eql(u8, sectname, "__cfstring")) {
+ if (self.objc_cfstring_section_index != null) continue;
+
+ self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len);
+ try data_const_seg.addSection(self.allocator, "__cfstring", "__DATA_CONST", .{});
} else {
if (self.data_section_index != null) continue;
self.data_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__data"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
- });
+ try data_seg.addSection(self.allocator, "__data", "__DATA", .{});
}
continue;
@@ -932,19 +723,8 @@ fn updateMetadata(self: *Zld) !void {
const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
const common_section_index = self.common_section_index orelse ind: {
self.common_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__common"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
- .@"align" = 0,
- .reloff = 0,
- .nreloc = 0,
+ try data_seg.addSection(self.allocator, "__common", "__DATA", .{
.flags = macho.S_ZEROFILL,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
break :ind self.common_section_index.?;
};
@@ -1136,6 +916,11 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection {
.seg = self.data_const_segment_cmd_index.?,
.sect = self.data_const_section_index.?,
};
+ } else if (mem.eql(u8, sectname, "__cfstring")) {
+ break :blk .{
+ .seg = self.data_const_segment_cmd_index.?,
+ .sect = self.objc_cfstring_section_index.?,
+ };
}
break :blk .{
.seg = self.data_segment_cmd_index.?,
@@ -1200,6 +985,7 @@ fn sortSections(self: *Zld) !void {
&self.mod_init_func_section_index,
&self.mod_term_func_section_index,
&self.data_const_section_index,
+ &self.objc_cfstring_section_index,
};
for (indices) |maybe_index| {
const new_index: u16 = if (maybe_index.*) |index| blk: {
@@ -2240,18 +2026,8 @@ fn populateMetadata(self: *Zld) !void {
if (self.pagezero_segment_cmd_index == null) {
self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
try self.load_commands.append(self.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__PAGEZERO"),
- .vmaddr = 0,
+ .Segment = SegmentCommand.empty("__PAGEZERO", .{
.vmsize = 0x100000000, // size always set to 4GB
- .fileoff = 0,
- .filesize = 0,
- .maxprot = 0,
- .initprot = 0,
- .nsects = 0,
- .flags = 0,
}),
});
}
@@ -2259,18 +2035,10 @@ fn populateMetadata(self: *Zld) !void {
if (self.text_segment_cmd_index == null) {
self.text_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
try self.load_commands.append(self.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__TEXT"),
+ .Segment = SegmentCommand.empty("__TEXT", .{
.vmaddr = 0x100000000, // always starts at 4GB
- .vmsize = 0,
- .fileoff = 0,
- .filesize = 0,
.maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
.initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE,
- .nsects = 0,
- .flags = 0,
}),
});
}
@@ -2283,19 +2051,9 @@ fn populateMetadata(self: *Zld) !void {
.aarch64 => 2,
else => unreachable, // unhandled architecture type
};
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__text"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
+ try text_seg.addSection(self.allocator, "__text", "__TEXT", .{
.@"align" = alignment,
- .reloff = 0,
- .nreloc = 0,
.flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
}
@@ -2312,19 +2070,10 @@ fn populateMetadata(self: *Zld) !void {
.aarch64 => 3 * @sizeOf(u32),
else => unreachable, // unhandled architecture type
};
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__stubs"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
- .size = 0,
- .offset = 0,
+ try text_seg.addSection(self.allocator, "__stubs", "__TEXT", .{
.@"align" = alignment,
- .reloff = 0,
- .nreloc = 0,
.flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
- .reserved1 = 0,
.reserved2 = stub_size,
- .reserved3 = 0,
});
}
@@ -2341,37 +2090,19 @@ fn populateMetadata(self: *Zld) !void {
.aarch64 => 6 * @sizeOf(u32),
else => unreachable,
};
- try text_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__stub_helper"),
- .segname = makeStaticString("__TEXT"),
- .addr = 0,
+ try text_seg.addSection(self.allocator, "__stub_helper", "__TEXT", .{
.size = stub_helper_size,
- .offset = 0,
.@"align" = alignment,
- .reloff = 0,
- .nreloc = 0,
.flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
}
if (self.data_const_segment_cmd_index == null) {
self.data_const_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
try self.load_commands.append(self.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__DATA_CONST"),
- .vmaddr = 0,
- .vmsize = 0,
- .fileoff = 0,
- .filesize = 0,
+ .Segment = SegmentCommand.empty("__DATA_CONST", .{
.maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
.initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
- .nsects = 0,
- .flags = 0,
}),
});
}
@@ -2379,37 +2110,18 @@ fn populateMetadata(self: *Zld) !void {
if (self.got_section_index == null) {
const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
self.got_section_index = @intCast(u16, data_const_seg.sections.items.len);
- try data_const_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__got"),
- .segname = makeStaticString("__DATA_CONST"),
- .addr = 0,
- .size = 0,
- .offset = 0,
+ try data_const_seg.addSection(self.allocator, "__got", "__DATA_CONST", .{
.@"align" = 3, // 2^3 = @sizeOf(u64)
- .reloff = 0,
- .nreloc = 0,
.flags = macho.S_NON_LAZY_SYMBOL_POINTERS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
}
if (self.data_segment_cmd_index == null) {
self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
try self.load_commands.append(self.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__DATA"),
- .vmaddr = 0,
- .vmsize = 0,
- .fileoff = 0,
- .filesize = 0,
+ .Segment = SegmentCommand.empty("__DATA", .{
.maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
.initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE,
- .nsects = 0,
- .flags = 0,
}),
});
}
@@ -2417,56 +2129,26 @@ fn populateMetadata(self: *Zld) !void {
if (self.la_symbol_ptr_section_index == null) {
const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
self.la_symbol_ptr_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__la_symbol_ptr"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
+ try data_seg.addSection(self.allocator, "__la_symbol_ptr", "__DATA", .{
.@"align" = 3, // 2^3 = @sizeOf(u64)
- .reloff = 0,
- .nreloc = 0,
.flags = macho.S_LAZY_SYMBOL_POINTERS,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
}
if (self.data_section_index == null) {
const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
self.data_section_index = @intCast(u16, data_seg.sections.items.len);
- try data_seg.addSection(self.allocator, .{
- .sectname = makeStaticString("__data"),
- .segname = makeStaticString("__DATA"),
- .addr = 0,
- .size = 0,
- .offset = 0,
+ try data_seg.addSection(self.allocator, "__data", "__DATA", .{
.@"align" = 3, // 2^3 = @sizeOf(u64)
- .reloff = 0,
- .nreloc = 0,
- .flags = macho.S_REGULAR,
- .reserved1 = 0,
- .reserved2 = 0,
- .reserved3 = 0,
});
}
if (self.linkedit_segment_cmd_index == null) {
self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
try self.load_commands.append(self.allocator, .{
- .Segment = SegmentCommand.empty(.{
- .cmd = macho.LC_SEGMENT_64,
- .cmdsize = @sizeOf(macho.segment_command_64),
- .segname = makeStaticString("__LINKEDIT"),
- .vmaddr = 0,
- .vmsize = 0,
- .fileoff = 0,
- .filesize = 0,
+ .Segment = SegmentCommand.empty("__LINKEDIT", .{
.maxprot = macho.VM_PROT_READ,
.initprot = macho.VM_PROT_READ,
- .nsects = 0,
- .flags = 0,
}),
});
}
@@ -3469,13 +3151,6 @@ fn writeHeader(self: *Zld) !void {
try self.file.?.pwriteAll(mem.asBytes(&header), 0);
}
-pub fn makeStaticString(bytes: []const u8) [16]u8 {
- var buf = [_]u8{0} ** 16;
- assert(bytes.len <= buf.len);
- mem.copy(u8, &buf, bytes);
- return buf;
-}
-
fn makeString(self: *Zld, bytes: []const u8) !u32 {
if (self.strtab_dir.get(bytes)) |offset| {
log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset });
diff --git a/src/link/MachO/commands.zig b/src/link/MachO/commands.zig
index 8bceb64f1e..6ad1964483 100644
--- a/src/link/MachO/commands.zig
+++ b/src/link/MachO/commands.zig
@@ -9,7 +9,6 @@ const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const MachO = @import("../MachO.zig");
-const makeStaticString = MachO.makeStaticString;
const padToIdeal = MachO.padToIdeal;
pub const LoadCommand = union(enum) {
@@ -187,12 +186,70 @@ pub const SegmentCommand = struct {
inner: macho.segment_command_64,
sections: std.ArrayListUnmanaged(macho.section_64) = .{},
- pub fn empty(inner: macho.segment_command_64) SegmentCommand {
- return .{ .inner = inner };
+ const SegmentOptions = struct {
+ cmdsize: u32 = @sizeOf(macho.segment_command_64),
+ vmaddr: u64 = 0,
+ vmsize: u64 = 0,
+ fileoff: u64 = 0,
+ filesize: u64 = 0,
+ maxprot: macho.vm_prot_t = macho.VM_PROT_NONE,
+ initprot: macho.vm_prot_t = macho.VM_PROT_NONE,
+ nsects: u32 = 0,
+ flags: u32 = 0,
+ };
+
+ pub fn empty(comptime segname: []const u8, opts: SegmentOptions) SegmentCommand {
+ return .{
+ .inner = .{
+ .cmd = macho.LC_SEGMENT_64,
+ .cmdsize = opts.cmdsize,
+ .segname = makeStaticString(segname),
+ .vmaddr = opts.vmaddr,
+ .vmsize = opts.vmsize,
+ .fileoff = opts.fileoff,
+ .filesize = opts.filesize,
+ .maxprot = opts.maxprot,
+ .initprot = opts.initprot,
+ .nsects = opts.nsects,
+ .flags = opts.flags,
+ },
+ };
}
- pub fn addSection(self: *SegmentCommand, alloc: *Allocator, section: macho.section_64) !void {
- try self.sections.append(alloc, section);
+ const SectionOptions = struct {
+ addr: u64 = 0,
+ size: u64 = 0,
+ offset: u32 = 0,
+ @"align": u32 = 0,
+ reloff: u32 = 0,
+ nreloc: u32 = 0,
+ flags: u32 = macho.S_REGULAR,
+ reserved1: u32 = 0,
+ reserved2: u32 = 0,
+ reserved3: u32 = 0,
+ };
+
+ pub fn addSection(
+ self: *SegmentCommand,
+ alloc: *Allocator,
+ comptime sectname: []const u8,
+ comptime segname: []const u8,
+ opts: SectionOptions,
+ ) !void {
+ try self.sections.append(alloc, .{
+ .sectname = makeStaticString(sectname),
+ .segname = makeStaticString(segname),
+ .addr = opts.addr,
+ .size = opts.size,
+ .offset = opts.offset,
+ .@"align" = opts.@"align",
+ .reloff = opts.reloff,
+ .nreloc = opts.nreloc,
+ .flags = opts.flags,
+ .reserved1 = opts.reserved1,
+ .reserved2 = opts.reserved2,
+ .reserved3 = opts.reserved3,
+ });
self.inner.cmdsize += @sizeOf(macho.section_64);
self.inner.nsects += 1;
}
@@ -338,6 +395,13 @@ pub fn createLoadDylibCommand(
return dylib_cmd;
}
+fn makeStaticString(bytes: []const u8) [16]u8 {
+ var buf = [_]u8{0} ** 16;
+ assert(bytes.len <= buf.len);
+ mem.copy(u8, &buf, bytes);
+ return buf;
+}
+
fn testRead(allocator: *Allocator, buffer: []const u8, expected: anytype) !void {
var stream = io.fixedBufferStream(buffer);
var given = try LoadCommand.read(allocator, stream.reader());