mirror of
https://github.com/ziglang/zig.git
synced 2025-01-24 19:07:35 +00:00
macho: clean up atom+symbol creation logic in ZigObject
This commit is contained in:
parent
e117e05768
commit
103c16c879
@ -52,8 +52,8 @@ pub fn init(self: *InternalObject, allocator: Allocator) !void {
|
||||
}
|
||||
|
||||
pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
|
||||
const createSymbol = struct {
|
||||
fn createSymbol(obj: *InternalObject, name: u32, args: struct {
|
||||
const newSymbolAssumeCapacity = struct {
|
||||
fn newSymbolAssumeCapacity(obj: *InternalObject, name: u32, args: struct {
|
||||
type: u8 = macho.N_UNDF | macho.N_EXT,
|
||||
desc: u16 = 0,
|
||||
}) Symbol.Index {
|
||||
@ -78,7 +78,7 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
|
||||
symbol.nlist_idx = nlist_idx;
|
||||
return index;
|
||||
}
|
||||
}.createSymbol;
|
||||
}.newSymbolAssumeCapacity;
|
||||
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
var nsyms = macho_file.base.comp.force_undefined_symbols.keys().len;
|
||||
@ -102,28 +102,28 @@ pub fn initSymbols(self: *InternalObject, macho_file: *MachO) !void {
|
||||
|
||||
try self.force_undefined.ensureTotalCapacityPrecise(gpa, macho_file.base.comp.force_undefined_symbols.keys().len);
|
||||
for (macho_file.base.comp.force_undefined_symbols.keys()) |name| {
|
||||
self.force_undefined.addOneAssumeCapacity().* = createSymbol(self, try self.addString(gpa, name), .{});
|
||||
self.force_undefined.addOneAssumeCapacity().* = newSymbolAssumeCapacity(self, try self.addString(gpa, name), .{});
|
||||
}
|
||||
|
||||
self.dyld_stub_binder_index = createSymbol(self, try self.addString(gpa, "dyld_stub_binder"), .{});
|
||||
self.objc_msg_send_index = createSymbol(self, try self.addString(gpa, "_objc_msgSend"), .{});
|
||||
self.dyld_stub_binder_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "dyld_stub_binder"), .{});
|
||||
self.objc_msg_send_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "_objc_msgSend"), .{});
|
||||
|
||||
if (!macho_file.base.isDynLib()) {
|
||||
self.entry_index = createSymbol(self, try self.addString(gpa, macho_file.entry_name orelse "_main"), .{});
|
||||
self.mh_execute_header_index = createSymbol(self, try self.addString(gpa, "__mh_execute_header"), .{
|
||||
self.entry_index = newSymbolAssumeCapacity(self, try self.addString(gpa, macho_file.entry_name orelse "_main"), .{});
|
||||
self.mh_execute_header_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__mh_execute_header"), .{
|
||||
.type = macho.N_SECT | macho.N_EXT,
|
||||
.desc = macho.REFERENCED_DYNAMICALLY,
|
||||
});
|
||||
} else {
|
||||
self.mh_dylib_header_index = createSymbol(self, try self.addString(gpa, "__mh_dylib_header"), .{
|
||||
self.mh_dylib_header_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "__mh_dylib_header"), .{
|
||||
.type = macho.N_SECT | macho.N_EXT,
|
||||
});
|
||||
}
|
||||
|
||||
self.dso_handle_index = createSymbol(self, try self.addString(gpa, "___dso_handle"), .{
|
||||
self.dso_handle_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "___dso_handle"), .{
|
||||
.type = macho.N_SECT | macho.N_EXT,
|
||||
});
|
||||
self.dyld_private_index = createSymbol(self, try self.addString(gpa, "dyld_private"), .{
|
||||
self.dyld_private_index = newSymbolAssumeCapacity(self, try self.addString(gpa, "dyld_private"), .{
|
||||
.type = macho.N_SECT,
|
||||
});
|
||||
}
|
||||
|
@ -141,34 +141,64 @@ pub fn deinit(self: *ZigObject, allocator: Allocator) void {
|
||||
}
|
||||
}
|
||||
|
||||
fn addNlist(self: *ZigObject, allocator: Allocator) !Symbol.Index {
|
||||
fn newSymbol(self: *ZigObject, allocator: Allocator, name: u32, args: struct {
|
||||
type: u8 = macho.N_UNDF | macho.N_EXT,
|
||||
desc: u16 = 0,
|
||||
}) !Symbol.Index {
|
||||
try self.symtab.ensureUnusedCapacity(allocator, 1);
|
||||
const index = @as(Symbol.Index, @intCast(self.symtab.addOneAssumeCapacity()));
|
||||
self.symtab.set(index, .{
|
||||
.nlist = MachO.null_sym,
|
||||
try self.symbols.ensureUnusedCapacity(allocator, 1);
|
||||
try self.symbols_extra.ensureUnusedCapacity(allocator, @sizeOf(Symbol.Extra));
|
||||
try self.globals.ensureUnusedCapacity(allocator, 1);
|
||||
|
||||
const index = self.addSymbolAssumeCapacity();
|
||||
const symbol = &self.symbols.items[index];
|
||||
symbol.name = name;
|
||||
symbol.extra = self.addSymbolExtraAssumeCapacity(.{});
|
||||
|
||||
const nlist_idx: u32 = @intCast(self.symtab.addOneAssumeCapacity());
|
||||
self.symtab.set(nlist_idx, .{
|
||||
.nlist = .{
|
||||
.n_strx = name,
|
||||
.n_type = args.type,
|
||||
.n_sect = 0,
|
||||
.n_desc = args.desc,
|
||||
.n_value = 0,
|
||||
},
|
||||
.size = 0,
|
||||
.atom = 0,
|
||||
});
|
||||
symbol.nlist_idx = nlist_idx;
|
||||
|
||||
self.globals.appendAssumeCapacity(0);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
pub fn createAtomForDecl(self: *ZigObject, allocator: Allocator, macho_file: *MachO) !Symbol.Index {
|
||||
const atom_index = try self.addAtom(allocator);
|
||||
const symbol_index = try self.addSymbol(allocator);
|
||||
const nlist_index = try self.addNlist(allocator);
|
||||
self.symtab.items(.atom)[nlist_index] = atom_index;
|
||||
try self.atoms_indexes.append(allocator, atom_index);
|
||||
const symbol = &self.symbols.items[symbol_index];
|
||||
symbol.atom_ref = .{ .index = atom_index, .file = self.index };
|
||||
symbol.nlist_idx = nlist_index;
|
||||
symbol.extra = try self.addSymbolExtra(allocator, .{});
|
||||
fn newAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Atom.Index {
|
||||
try self.atoms.ensureUnusedCapacity(allocator, 1);
|
||||
try self.atoms_extra.ensureUnusedCapacity(allocator, @sizeOf(Atom.Extra));
|
||||
try self.atoms_indexes.ensureUnusedCapacity(allocator, 1);
|
||||
try self.relocs.ensureUnusedCapacity(allocator, 1);
|
||||
|
||||
const index = self.addAtomAssumeCapacity();
|
||||
self.atoms_indexes.appendAssumeCapacity(index);
|
||||
const atom = self.getAtom(index).?;
|
||||
atom.name = name;
|
||||
|
||||
const relocs_index = @as(u32, @intCast(self.relocs.items.len));
|
||||
const relocs = try self.relocs.addOne(allocator);
|
||||
relocs.* = .{};
|
||||
const atom = self.getAtom(atom_index).?;
|
||||
self.relocs.addOneAssumeCapacity().* = .{};
|
||||
atom.addExtra(.{ .rel_index = relocs_index, .rel_count = 0 }, macho_file);
|
||||
try self.globals.append(allocator, 0);
|
||||
return symbol_index;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
fn newSymbolWithAtom(self: *ZigObject, allocator: Allocator, name: u32, macho_file: *MachO) !Symbol.Index {
|
||||
const atom_index = try self.newAtom(allocator, name, macho_file);
|
||||
const sym_index = try self.newSymbol(allocator, name, .{ .type = macho.N_SECT });
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
sym.atom_ref = .{ .index = atom_index, .file = self.index };
|
||||
self.symtab.items(.atom)[sym.nlist_idx] = atom_index;
|
||||
return sym_index;
|
||||
}
|
||||
|
||||
pub fn getAtomData(self: ZigObject, macho_file: *MachO, atom: Atom, buffer: []u8) !void {
|
||||
@ -1079,27 +1109,19 @@ fn createTlvInitializer(
|
||||
const gpa = macho_file.base.comp.gpa;
|
||||
const sym_name = try std.fmt.allocPrint(gpa, "{s}$tlv$init", .{name});
|
||||
defer gpa.free(sym_name);
|
||||
const off = try self.strtab.insert(gpa, sym_name);
|
||||
|
||||
const sym_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
const sym_index = try self.newSymbolWithAtom(gpa, off, macho_file);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
|
||||
const atom = sym.getAtom(macho_file).?;
|
||||
|
||||
sym.out_n_sect = sect_index;
|
||||
atom.out_n_sect = sect_index;
|
||||
|
||||
sym.value = 0;
|
||||
sym.name = try self.strtab.insert(gpa, sym_name);
|
||||
atom.flags.alive = true;
|
||||
atom.name = sym.name;
|
||||
nlist.n_strx = sym.name;
|
||||
nlist.n_sect = sect_index + 1;
|
||||
nlist.n_type = macho.N_SECT;
|
||||
nlist.n_value = 0;
|
||||
self.symtab.items(.size)[sym.nlist_idx] = code.len;
|
||||
|
||||
atom.alignment = alignment;
|
||||
atom.size = code.len;
|
||||
nlist.n_sect = sect_index + 1;
|
||||
self.symtab.items(.size)[sym.nlist_idx] = code.len;
|
||||
|
||||
const slice = macho_file.sections.slice();
|
||||
const header = slice.items(.header)[sect_index];
|
||||
@ -1293,7 +1315,8 @@ fn lowerConst(
|
||||
var code_buffer = std.ArrayList(u8).init(gpa);
|
||||
defer code_buffer.deinit();
|
||||
|
||||
const sym_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
const name_str_index = try self.strtab.insert(gpa, name);
|
||||
const sym_index = try self.newSymbolWithAtom(gpa, name_str_index, macho_file);
|
||||
|
||||
const res = try codegen.generateSymbol(&macho_file.base, pt, src_loc, val, &code_buffer, .{
|
||||
.none = {},
|
||||
@ -1306,19 +1329,14 @@ fn lowerConst(
|
||||
};
|
||||
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const name_str_index = try self.strtab.insert(gpa, name);
|
||||
sym.name = name_str_index;
|
||||
sym.out_n_sect = output_section_index;
|
||||
|
||||
const nlist = &self.symtab.items(.nlist)[sym.nlist_idx];
|
||||
nlist.n_strx = name_str_index;
|
||||
nlist.n_type = macho.N_SECT;
|
||||
nlist.n_sect = output_section_index + 1;
|
||||
self.symtab.items(.size)[sym.nlist_idx] = code.len;
|
||||
|
||||
const atom = sym.getAtom(macho_file).?;
|
||||
atom.flags.alive = true;
|
||||
atom.name = name_str_index;
|
||||
atom.alignment = required_alignment;
|
||||
atom.size = code.len;
|
||||
atom.out_n_sect = output_section_index;
|
||||
@ -1327,9 +1345,6 @@ fn lowerConst(
|
||||
// TODO rename and re-audit this method
|
||||
errdefer self.freeDeclMetadata(macho_file, sym_index);
|
||||
|
||||
sym.value = 0;
|
||||
nlist.n_value = 0;
|
||||
|
||||
const sect = macho_file.sections.items(.header)[output_section_index];
|
||||
const file_offset = sect.offset + atom.value;
|
||||
try macho_file.base.file.?.pwriteAll(code, file_offset);
|
||||
@ -1560,17 +1575,9 @@ pub fn getGlobalSymbol(self: *ZigObject, macho_file: *MachO, name: []const u8, l
|
||||
const off = try self.strtab.insert(gpa, sym_name);
|
||||
const lookup_gop = try self.globals_lookup.getOrPut(gpa, off);
|
||||
if (!lookup_gop.found_existing) {
|
||||
const sym_index = try self.addSymbol(gpa);
|
||||
const sym_index = try self.newSymbol(gpa, off, .{});
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const nlist_index = try self.addNlist(gpa);
|
||||
const nlist = &self.symtab.items(.nlist)[nlist_index];
|
||||
nlist.n_strx = off;
|
||||
nlist.n_type = macho.N_EXT;
|
||||
sym.name = off;
|
||||
sym.nlist_idx = nlist_index;
|
||||
sym.extra = try self.addSymbolExtra(gpa, .{});
|
||||
lookup_gop.value_ptr.* = nlist_index;
|
||||
try self.globals.append(gpa, 0);
|
||||
lookup_gop.value_ptr.* = sym.nlist_idx;
|
||||
}
|
||||
return lookup_gop.value_ptr.*;
|
||||
}
|
||||
@ -1584,10 +1591,10 @@ pub fn getOrCreateMetadataForDecl(
|
||||
const gop = try self.decls.getOrPut(gpa, decl_index);
|
||||
if (!gop.found_existing) {
|
||||
const any_non_single_threaded = macho_file.base.comp.config.any_non_single_threaded;
|
||||
const sym_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
const sym_index = try self.newSymbolWithAtom(gpa, 0, macho_file);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
const mod = macho_file.base.comp.module.?;
|
||||
const decl = mod.declPtr(decl_index);
|
||||
const sym = &self.symbols.items[sym_index];
|
||||
if (decl.getOwnedVariable(mod)) |variable| {
|
||||
if (variable.is_threadlocal and any_non_single_threaded) {
|
||||
sym.flags.tlv = true;
|
||||
@ -1627,7 +1634,7 @@ pub fn getOrCreateMetadataForLazySymbol(
|
||||
};
|
||||
switch (metadata.state.*) {
|
||||
.unused => {
|
||||
const symbol_index = try self.createAtomForDecl(gpa, macho_file);
|
||||
const symbol_index = try self.newSymbolWithAtom(gpa, 0, macho_file);
|
||||
const sym = &self.symbols.items[symbol_index];
|
||||
sym.flags.needs_zig_got = true;
|
||||
metadata.symbol_index.* = symbol_index;
|
||||
@ -1643,12 +1650,18 @@ pub fn getOrCreateMetadataForLazySymbol(
|
||||
}
|
||||
|
||||
fn addAtom(self: *ZigObject, allocator: Allocator) !Atom.Index {
|
||||
try self.atoms.ensureUnusedCapacity(allocator, 1);
|
||||
try self.atoms_extra.ensureUnusedCapacity(allocator, 1);
|
||||
return self.addAtomAssumeCapacity();
|
||||
}
|
||||
|
||||
fn addAtomAssumeCapacity(self: *ZigObject) Atom.Index {
|
||||
const atom_index: Atom.Index = @intCast(self.atoms.items.len);
|
||||
const atom = try self.atoms.addOne(allocator);
|
||||
const atom = self.atoms.addOneAssumeCapacity();
|
||||
atom.* = .{
|
||||
.file = self.index,
|
||||
.atom_index = atom_index,
|
||||
.extra = try self.addAtomExtra(allocator, .{}),
|
||||
.extra = self.addAtomExtraAssumeCapacity(.{}),
|
||||
};
|
||||
return atom_index;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user