mirror of
https://github.com/ziglang/zig.git
synced 2026-01-05 21:13:24 +00:00
zld+stage2: refactor creating segments and sections
Move the logic into default-init structs part of constructors in `SegmentCommand` struct in `commands.zig` module.
This commit is contained in:
parent
72f2f68938
commit
852e1ed23c
@ -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 });
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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, {});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 });
|
||||
|
||||
@ -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());
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user