Commit 737a8bf204
Changed files (2)
src
src/link/MachO.zig
@@ -149,19 +149,27 @@ const LIB_SYSTEM_NAME: [*:0]const u8 = "System";
const LIB_SYSTEM_PATH: [*:0]const u8 = DEFAULT_LIB_SEARCH_PATH ++ "/libSystem.B.dylib";
pub const TextBlock = struct {
- /// Index into the symbol table
- symbol_table_index: ?u32,
+ /// Each decl always gets a local symbol with the fully qualified name.
+ /// The vaddr and size are found here directly.
+ /// The file offset is found by computing the vaddr offset from the section vaddr
+ /// the symbol references, and adding that to the file offset of the section.
+ /// If this field is 0, it means the codegen size = 0 and there is no symbol or
+ /// offset table entry.
+ local_sym_index: u32,
/// Index into offset table
- offset_table_index: ?u32,
+ /// This field is undefined for symbols with size = 0.
+ offset_table_index: u32,
/// Size of this text block
+ /// Unlike in Elf, we need to store the size of this symbol as part of
+ /// the TextBlock since macho.nlist_64 lacks this information.
size: u64,
/// Points to the previous and next neighbours
prev: ?*TextBlock,
next: ?*TextBlock,
pub const empty = TextBlock{
- .symbol_table_index = null,
- .offset_table_index = null,
+ .local_sym_index = 0,
+ .offset_table_index = undefined,
.size = 0,
.prev = null,
.next = null,
@@ -190,6 +198,15 @@ pub fn openPath(allocator: *Allocator, sub_path: []const u8, options: link.Optio
self.base.file = file;
+ // Index 0 is always a null symbol.
+ try self.local_symbols.append(allocator, .{
+ .n_strx = 0,
+ .n_type = 0,
+ .n_sect = 0,
+ .n_desc = 0,
+ .n_value = 0,
+ });
+
switch (options.output_mode) {
.Exe => {},
.Obj => {},
@@ -717,26 +734,26 @@ pub fn deinit(self: *MachO) void {
}
pub fn allocateDeclIndexes(self: *MachO, decl: *Module.Decl) !void {
- if (decl.link.macho.symbol_table_index) |_| return;
+ if (decl.link.macho.local_sym_index != 0) return;
try self.local_symbols.ensureCapacity(self.base.allocator, self.local_symbols.items.len + 1);
try self.offset_table.ensureCapacity(self.base.allocator, self.offset_table.items.len + 1);
log.debug("allocating symbol index {} for {}\n", .{ self.local_symbols.items.len, decl.name });
- decl.link.macho.symbol_table_index = @intCast(u32, self.local_symbols.items.len);
+ decl.link.macho.local_sym_index = @intCast(u32, self.local_symbols.items.len);
_ = self.local_symbols.addOneAssumeCapacity();
decl.link.macho.offset_table_index = @intCast(u32, self.offset_table.items.len);
_ = self.offset_table.addOneAssumeCapacity();
- self.local_symbols.items[decl.link.macho.symbol_table_index.?] = .{
+ self.local_symbols.items[decl.link.macho.local_sym_index] = .{
.n_strx = 0,
.n_type = 0,
.n_sect = 0,
.n_desc = 0,
.n_value = 0,
};
- self.offset_table.items[decl.link.macho.offset_table_index.?] = 0;
+ self.offset_table.items[decl.link.macho.offset_table_index] = 0;
}
pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
@@ -761,7 +778,7 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
log.debug("generated code {}\n", .{code});
const required_alignment = typed_value.ty.abiAlignment(self.base.options.target);
- const symbol = &self.local_symbols.items[decl.link.macho.symbol_table_index.?];
+ const symbol = &self.local_symbols.items[decl.link.macho.local_sym_index];
const decl_name = mem.spanZ(decl.name);
const name_str_index = try self.makeString(decl_name);
@@ -776,10 +793,10 @@ pub fn updateDecl(self: *MachO, module: *Module, decl: *Module.Decl) !void {
.n_desc = 0,
.n_value = addr,
};
- self.offset_table.items[decl.link.macho.offset_table_index.?] = addr;
+ self.offset_table.items[decl.link.macho.offset_table_index] = addr;
- try self.writeSymbol(decl.link.macho.symbol_table_index.?);
- try self.writeOffsetTableEntry(decl.link.macho.offset_table_index.?);
+ try self.writeSymbol(decl.link.macho.local_sym_index);
+ try self.writeOffsetTableEntry(decl.link.macho.offset_table_index);
const text_section = self.sections.items[self.text_section_index.?];
const section_offset = symbol.n_value - text_section.addr;
@@ -805,8 +822,8 @@ pub fn updateDeclExports(
defer tracy.end();
try self.global_symbols.ensureCapacity(self.base.allocator, self.global_symbols.items.len + exports.len);
- if (decl.link.macho.symbol_table_index == null) return;
- const decl_sym = &self.local_symbols.items[decl.link.macho.symbol_table_index.?];
+ if (decl.link.macho.local_sym_index == 0) return;
+ const decl_sym = &self.local_symbols.items[decl.link.macho.local_sym_index];
for (exports) |exp| {
if (exp.options.section) |section_name| {
@@ -867,7 +884,8 @@ pub fn updateDeclExports(
pub fn freeDecl(self: *MachO, decl: *Module.Decl) void {}
pub fn getDeclVAddr(self: *MachO, decl: *const Module.Decl) u64 {
- return self.local_symbols.items[decl.link.macho.symbol_table_index.?].n_value;
+ assert(decl.link.macho.local_sym_index != 0);
+ return self.local_symbols.items[decl.link.macho.local_sym_index].n_value;
}
pub fn populateMissingMetadata(self: *MachO) !void {
@@ -1126,17 +1144,6 @@ pub fn populateMissingMetadata(self: *MachO) !void {
});
self.cmd_table_dirty = true;
}
- if (self.dyld_stub_binder_index == null) {
- self.dyld_stub_binder_index = @intCast(u16, self.undef_symbols.items.len);
- const name = try self.makeString("dyld_stub_binder");
- try self.undef_symbols.append(self.base.allocator, .{
- .n_strx = name,
- .n_type = macho.N_UNDF | macho.N_EXT,
- .n_sect = 0,
- .n_desc = macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY | macho.N_SYMBOL_RESOLVER,
- .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;
@@ -1175,6 +1182,17 @@ pub fn populateMissingMetadata(self: *MachO) !void {
symtab.strsize = file_size;
}
}
+ if (self.dyld_stub_binder_index == null) {
+ self.dyld_stub_binder_index = @intCast(u16, self.undef_symbols.items.len);
+ const name = try self.makeString("dyld_stub_binder");
+ try self.undef_symbols.append(self.base.allocator, .{
+ .n_strx = name,
+ .n_type = macho.N_UNDF | macho.N_EXT,
+ .n_sect = 0,
+ .n_desc = macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY | macho.N_SYMBOL_RESOLVER,
+ .n_value = 0,
+ });
+ }
}
fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 {
@@ -1184,7 +1202,7 @@ fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64,
var block_placement: ?*TextBlock = null;
const addr = blk: {
if (self.last_text_block) |last| {
- const last_symbol = self.local_symbols.items[last.symbol_table_index.?];
+ const last_symbol = self.local_symbols.items[last.local_sym_index];
// TODO pad out with NOPs and reenable
// const ideal_capacity = last.size * alloc_num / alloc_den;
// const ideal_capacity_end_addr = last_symbol.n_value + ideal_capacity;
src/codegen.zig
@@ -1532,7 +1532,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
const func = func_val.func;
const got = &macho_file.sections.items[macho_file.got_section_index.?];
- const got_addr = got.addr + func.owner_decl.link.macho.offset_table_index.? * @sizeOf(u64);
+ const got_addr = got.addr + func.owner_decl.link.macho.offset_table_index * @sizeOf(u64);
// Here, we store the got address in %rax, and then call %rax
// movabsq [addr], %rax
try self.genSetReg(inst.base.src, .rax, .{ .memory = got_addr });
@@ -2591,7 +2591,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
} else if (self.bin_file.cast(link.File.MachO)) |macho_file| {
const decl = payload.decl;
const got = &macho_file.sections.items[macho_file.got_section_index.?];
- const got_addr = got.addr + decl.link.macho.offset_table_index.? * ptr_bytes;
+ const got_addr = got.addr + decl.link.macho.offset_table_index * ptr_bytes;
return MCValue{ .memory = got_addr };
} else if (self.bin_file.cast(link.File.Coff)) |coff_file| {
const decl = payload.decl;