mirror of
https://github.com/ziglang/zig.git
synced 2026-02-19 07:48:31 +00:00
First hacked together, working MachO exe!
This commit is contained in:
parent
635984abc7
commit
5a7105401c
@ -262,6 +262,12 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
||||
dysymtab.iundefsym = nlocals + nglobals;
|
||||
dysymtab.nundefsym = nundefs;
|
||||
}
|
||||
{
|
||||
// update LC_MAIN with entry offset
|
||||
const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
|
||||
const main_cmd = &self.load_commands.items[self.main_cmd_index.?].EntryPoint;
|
||||
main_cmd.entryoff = self.entry_addr.? - text_segment.vmaddr;
|
||||
}
|
||||
{
|
||||
var last_cmd_offset: usize = @sizeOf(macho.mach_header_64);
|
||||
for (self.load_commands.items) |cmd| {
|
||||
@ -817,8 +823,6 @@ pub fn updateDeclExports(
|
||||
.Strong => blk: {
|
||||
if (mem.eql(u8, exp.options.name, "_start")) {
|
||||
self.entry_addr = decl_sym.n_value;
|
||||
const cmd = &self.load_commands.items[self.main_cmd_index.?].EntryPoint;
|
||||
cmd.entryoff = decl_sym.n_value;
|
||||
}
|
||||
break :blk macho.REFERENCE_FLAG_DEFINED;
|
||||
},
|
||||
@ -985,8 +989,9 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
||||
.reserved3 = 0,
|
||||
});
|
||||
|
||||
data_segment.vmsize = file_size;
|
||||
data_segment.filesize = file_size;
|
||||
const segment_size = mem.alignForwardGeneric(u64, file_size, 0x1000);
|
||||
data_segment.vmsize = segment_size;
|
||||
data_segment.filesize = segment_size;
|
||||
data_segment.fileoff = off;
|
||||
|
||||
log.debug("initial got section {}\n", .{self.sections.items[self.got_section_index.?]});
|
||||
@ -1131,6 +1136,24 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
||||
.n_value = 0,
|
||||
});
|
||||
}
|
||||
{
|
||||
const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
|
||||
const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo;
|
||||
if (dyld_info.export_off == 0) {
|
||||
const nsyms = self.base.options.symbol_count_hint;
|
||||
const file_size = @sizeOf(u64) * nsyms;
|
||||
const off = @intCast(u32, self.findFreeSpace(file_size, 0x1000));
|
||||
log.debug("found export trie free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
||||
dyld_info.export_off = off;
|
||||
dyld_info.export_size = @intCast(u32, file_size);
|
||||
|
||||
const segment_size = mem.alignForwardGeneric(u64, file_size, 0x1000);
|
||||
linkedit.vmsize = 4 * segment_size;
|
||||
linkedit.fileoff = off;
|
||||
|
||||
log.debug("updated linkedit segment {}\n", .{linkedit});
|
||||
}
|
||||
}
|
||||
{
|
||||
const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
|
||||
const symtab = &self.load_commands.items[self.symtab_cmd_index.?].Symtab;
|
||||
@ -1141,12 +1164,6 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
||||
log.debug("found symbol table free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
||||
symtab.symoff = off;
|
||||
symtab.nsyms = @intCast(u32, nsyms);
|
||||
|
||||
linkedit.vmsize += file_size;
|
||||
linkedit.fileoff = off;
|
||||
linkedit.filesize += file_size;
|
||||
|
||||
log.debug("updated linkedit segment {}\n", .{linkedit});
|
||||
}
|
||||
if (symtab.stroff == 0) {
|
||||
try self.string_table.append(self.base.allocator, 0);
|
||||
@ -1155,11 +1172,6 @@ pub fn populateMissingMetadata(self: *MachO) !void {
|
||||
log.debug("found string table free space 0x{x} to 0x{x}\n", .{ off, off + file_size });
|
||||
symtab.stroff = off;
|
||||
symtab.strsize = file_size;
|
||||
|
||||
linkedit.vmsize += file_size;
|
||||
linkedit.filesize += file_size;
|
||||
|
||||
log.debug("updated linkedit segment {}\n", .{linkedit});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1291,6 +1303,15 @@ fn detectAllocCollision(self: *MachO, start: u64, size: u64) ?u64 {
|
||||
return test_end;
|
||||
}
|
||||
}
|
||||
if (self.dyld_info_cmd_index) |dyld_info_index| {
|
||||
const dyld_info = self.load_commands.items[dyld_info_index].DyldInfo;
|
||||
const tight_size = dyld_info.export_size;
|
||||
const increased_size = satMul(tight_size, alloc_num) / alloc_den;
|
||||
const test_end = dyld_info.export_off + increased_size;
|
||||
if (end > dyld_info.export_off and start < test_end) {
|
||||
return test_end;
|
||||
}
|
||||
}
|
||||
if (self.symtab_cmd_index) |symtab_index| {
|
||||
const symtab = self.load_commands.items[symtab_index].Symtab;
|
||||
{
|
||||
@ -1324,6 +1345,10 @@ fn allocatedSize(self: *MachO, start: u64) u64 {
|
||||
if (section.offset <= start) continue;
|
||||
if (section.offset < min_pos) min_pos = section.offset;
|
||||
}
|
||||
if (self.dyld_info_cmd_index) |dyld_info_index| {
|
||||
const dyld_info = self.load_commands.items[dyld_info_index].DyldInfo;
|
||||
if (dyld_info.export_off > start and dyld_info.export_off < min_pos) min_pos = dyld_info.export_off;
|
||||
}
|
||||
if (self.symtab_cmd_index) |symtab_index| {
|
||||
const symtab = self.load_commands.items[symtab_index].Symtab;
|
||||
if (symtab.symoff > start and symtab.symoff < min_pos) min_pos = symtab.symoff;
|
||||
@ -1380,7 +1405,7 @@ fn writeAllUndefSymbols(self: *MachO) !void {
|
||||
}
|
||||
|
||||
fn writeExportTrie(self: *MachO) !void {
|
||||
// TODO
|
||||
// TODO implement mechanism for generating a prefix tree of the exported symbols
|
||||
// single branch export trie
|
||||
var buf = [_]u8{0} ** 24;
|
||||
buf[0] = 0; // root node
|
||||
@ -1388,10 +1413,16 @@ fn writeExportTrie(self: *MachO) !void {
|
||||
mem.copy(u8, buf[2..], "_start");
|
||||
buf[8] = 0;
|
||||
buf[9] = 9 + 1;
|
||||
const written = try std.debug.leb.writeULEB128Mem(buf[12..], self.entry_addr.?);
|
||||
|
||||
const text_segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment;
|
||||
const addr = self.entry_addr.? - text_segment.vmaddr;
|
||||
const written = try std.debug.leb.writeULEB128Mem(buf[12..], addr);
|
||||
buf[10] = @intCast(u8, written) + 1;
|
||||
buf[11] = 0;
|
||||
log.debug("WAT = {}, {x}\n", .{ written, buf[0..] });
|
||||
|
||||
const dyld_info = &self.load_commands.items[self.dyld_info_cmd_index.?].DyldInfo;
|
||||
try self.base.file.?.pwriteAll(buf[0..], dyld_info.export_off);
|
||||
}
|
||||
|
||||
fn writeStringTable(self: *MachO) !void {
|
||||
@ -1409,6 +1440,10 @@ fn writeStringTable(self: *MachO) !void {
|
||||
log.debug("writing string table from 0x{x} to 0x{x}\n", .{ symtab.stroff, symtab.stroff + symtab.strsize });
|
||||
|
||||
try self.base.file.?.pwriteAll(self.string_table.items, symtab.stroff);
|
||||
|
||||
// FIXME
|
||||
const linkedit = &self.load_commands.items[self.linkedit_segment_cmd_index.?].Segment;
|
||||
linkedit.filesize = symtab.stroff + symtab.strsize - linkedit.fileoff;
|
||||
}
|
||||
|
||||
/// Writes Mach-O file header.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user