mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
macho: move nlist_64 type/flags helpers to std.macho
This commit is contained in:
parent
2873e19366
commit
86fe47235e
@ -744,6 +744,55 @@ pub const nlist_64 = extern struct {
|
||||
n_sect: u8,
|
||||
n_desc: u16,
|
||||
n_value: u64,
|
||||
|
||||
pub fn stab(sym: nlist_64) bool {
|
||||
return (N_STAB & sym.n_type) != 0;
|
||||
}
|
||||
|
||||
pub fn pext(sym: nlist_64) bool {
|
||||
return (N_PEXT & sym.n_type) != 0;
|
||||
}
|
||||
|
||||
pub fn ext(sym: nlist_64) bool {
|
||||
return (N_EXT & sym.n_type) != 0;
|
||||
}
|
||||
|
||||
pub fn sect(sym: nlist_64) bool {
|
||||
const type_ = N_TYPE & sym.n_type;
|
||||
return type_ == N_SECT;
|
||||
}
|
||||
|
||||
pub fn undf(sym: nlist_64) bool {
|
||||
const type_ = N_TYPE & sym.n_type;
|
||||
return type_ == N_UNDF;
|
||||
}
|
||||
|
||||
pub fn indr(sym: nlist_64) bool {
|
||||
const type_ = N_TYPE & sym.n_type;
|
||||
return type_ == N_INDR;
|
||||
}
|
||||
|
||||
pub fn abs(sym: nlist_64) bool {
|
||||
const type_ = N_TYPE & sym.n_type;
|
||||
return type_ == N_ABS;
|
||||
}
|
||||
|
||||
pub fn weakDef(sym: nlist_64) bool {
|
||||
return (sym.n_desc & N_WEAK_DEF) != 0;
|
||||
}
|
||||
|
||||
pub fn weakRef(sym: nlist_64) bool {
|
||||
return (sym.n_desc & N_WEAK_REF) != 0;
|
||||
}
|
||||
|
||||
pub fn discarded(sym: nlist_64) bool {
|
||||
return (sym.n_desc & N_DESC_DISCARDED) != 0;
|
||||
}
|
||||
|
||||
pub fn tentative(sym: nlist_64) bool {
|
||||
if (!sym.undf()) return false;
|
||||
return sym.n_value != 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// Format of a relocation entry of a Mach-O file. Modified from the 4.3BSD
|
||||
|
||||
@ -885,7 +885,7 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
|
||||
const sym_name = self.getString(sym.n_strx);
|
||||
const resolv = self.symbol_resolver.get(sym.n_strx) orelse unreachable;
|
||||
|
||||
if (symbolIsDiscarded(sym.*)) {
|
||||
if (sym.discarded()) {
|
||||
sym.* = .{
|
||||
.n_strx = 0,
|
||||
.n_type = macho.N_UNDF,
|
||||
@ -2445,21 +2445,21 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
|
||||
const sym_id = @intCast(u32, id);
|
||||
const sym_name = object.getString(sym.n_strx);
|
||||
|
||||
if (symbolIsStab(sym)) {
|
||||
if (sym.stab()) {
|
||||
log.err("unhandled symbol type: stab", .{});
|
||||
log.err(" symbol '{s}'", .{sym_name});
|
||||
log.err(" first definition in '{s}'", .{object.name});
|
||||
return error.UnhandledSymbolType;
|
||||
}
|
||||
|
||||
if (symbolIsIndr(sym)) {
|
||||
if (sym.indr()) {
|
||||
log.err("unhandled symbol type: indirect", .{});
|
||||
log.err(" symbol '{s}'", .{sym_name});
|
||||
log.err(" first definition in '{s}'", .{object.name});
|
||||
return error.UnhandledSymbolType;
|
||||
}
|
||||
|
||||
if (symbolIsAbs(sym)) {
|
||||
if (sym.abs()) {
|
||||
log.err("unhandled symbol type: absolute", .{});
|
||||
log.err(" symbol '{s}'", .{sym_name});
|
||||
log.err(" first definition in '{s}'", .{object.name});
|
||||
@ -2467,7 +2467,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
|
||||
}
|
||||
|
||||
const n_strx = try self.makeString(sym_name);
|
||||
if (symbolIsSect(sym)) {
|
||||
if (sym.sect()) {
|
||||
// Defined symbol regardless of scope lands in the locals symbol table.
|
||||
const local_sym_index = @intCast(u32, self.locals.items.len);
|
||||
try self.locals.append(self.base.allocator, .{
|
||||
@ -2482,7 +2482,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
|
||||
|
||||
// If the symbol's scope is not local aka translation unit, then we need work out
|
||||
// if we should save the symbol as a global, or potentially flag the error.
|
||||
if (!symbolIsExt(sym)) continue;
|
||||
if (!sym.ext()) continue;
|
||||
|
||||
const local = self.locals.items[local_sym_index];
|
||||
const resolv = self.symbol_resolver.getPtr(n_strx) orelse {
|
||||
@ -2507,18 +2507,16 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
|
||||
.global => {
|
||||
const global = &self.globals.items[resolv.where_index];
|
||||
|
||||
if (symbolIsTentative(global.*)) {
|
||||
if (global.tentative()) {
|
||||
assert(self.tentatives.swapRemove(resolv.where_index));
|
||||
} else if (!(symbolIsWeakDef(sym) or symbolIsPext(sym)) and
|
||||
!(symbolIsWeakDef(global.*) or symbolIsPext(global.*)))
|
||||
{
|
||||
} else if (!(sym.weakDef() or sym.pext()) and !(global.weakDef() or global.pext())) {
|
||||
log.err("symbol '{s}' defined multiple times", .{sym_name});
|
||||
if (resolv.file) |file| {
|
||||
log.err(" first definition in '{s}'", .{self.objects.items[file].name});
|
||||
}
|
||||
log.err(" next definition in '{s}'", .{object.name});
|
||||
return error.MultipleSymbolDefinitions;
|
||||
} else if (symbolIsWeakDef(sym) or symbolIsPext(sym)) continue; // Current symbol is weak, so skip it.
|
||||
} else if (sym.weakDef() or sym.pext()) continue; // Current symbol is weak, so skip it.
|
||||
|
||||
// Otherwise, update the resolver and the global symbol.
|
||||
global.n_type = sym.n_type;
|
||||
@ -2554,7 +2552,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
|
||||
.local_sym_index = local_sym_index,
|
||||
.file = object_id,
|
||||
};
|
||||
} else if (symbolIsTentative(sym)) {
|
||||
} else if (sym.tentative()) {
|
||||
// Symbol is a tentative definition.
|
||||
const resolv = self.symbol_resolver.getPtr(n_strx) orelse {
|
||||
const global_sym_index = @intCast(u32, self.globals.items.len);
|
||||
@ -2577,7 +2575,7 @@ fn resolveSymbolsInObject(self: *MachO, object_id: u16) !void {
|
||||
switch (resolv.where) {
|
||||
.global => {
|
||||
const global = &self.globals.items[resolv.where_index];
|
||||
if (!symbolIsTentative(global.*)) continue;
|
||||
if (!global.tentative()) continue;
|
||||
if (global.n_value >= sym.n_value) continue;
|
||||
|
||||
global.n_desc = sym.n_desc;
|
||||
@ -3575,9 +3573,9 @@ pub fn updateDeclExports(
|
||||
|
||||
const sym = &self.globals.items[resolv.where_index];
|
||||
|
||||
if (symbolIsTentative(sym.*)) {
|
||||
if (sym.tentative()) {
|
||||
assert(self.tentatives.swapRemove(resolv.where_index));
|
||||
} else if (!is_weak and !(symbolIsWeakDef(sym.*) or symbolIsPext(sym.*))) {
|
||||
} else if (!is_weak and !(sym.weakDef() or sym.pext())) {
|
||||
_ = try module.failed_exports.put(
|
||||
module.gpa,
|
||||
exp,
|
||||
@ -5316,58 +5314,9 @@ pub fn getString(self: *MachO, off: u32) []const u8 {
|
||||
return mem.sliceTo(@ptrCast([*:0]const u8, self.strtab.items.ptr + off), 0);
|
||||
}
|
||||
|
||||
pub fn symbolIsStab(sym: macho.nlist_64) bool {
|
||||
return (macho.N_STAB & sym.n_type) != 0;
|
||||
}
|
||||
|
||||
pub fn symbolIsPext(sym: macho.nlist_64) bool {
|
||||
return (macho.N_PEXT & sym.n_type) != 0;
|
||||
}
|
||||
|
||||
pub fn symbolIsExt(sym: macho.nlist_64) bool {
|
||||
return (macho.N_EXT & sym.n_type) != 0;
|
||||
}
|
||||
|
||||
pub fn symbolIsSect(sym: macho.nlist_64) bool {
|
||||
const type_ = macho.N_TYPE & sym.n_type;
|
||||
return type_ == macho.N_SECT;
|
||||
}
|
||||
|
||||
pub fn symbolIsUndf(sym: macho.nlist_64) bool {
|
||||
const type_ = macho.N_TYPE & sym.n_type;
|
||||
return type_ == macho.N_UNDF;
|
||||
}
|
||||
|
||||
pub fn symbolIsIndr(sym: macho.nlist_64) bool {
|
||||
const type_ = macho.N_TYPE & sym.n_type;
|
||||
return type_ == macho.N_INDR;
|
||||
}
|
||||
|
||||
pub fn symbolIsAbs(sym: macho.nlist_64) bool {
|
||||
const type_ = macho.N_TYPE & sym.n_type;
|
||||
return type_ == macho.N_ABS;
|
||||
}
|
||||
|
||||
pub fn symbolIsWeakDef(sym: macho.nlist_64) bool {
|
||||
return (sym.n_desc & macho.N_WEAK_DEF) != 0;
|
||||
}
|
||||
|
||||
pub fn symbolIsWeakRef(sym: macho.nlist_64) bool {
|
||||
return (sym.n_desc & macho.N_WEAK_REF) != 0;
|
||||
}
|
||||
|
||||
pub fn symbolIsDiscarded(sym: macho.nlist_64) bool {
|
||||
return (sym.n_desc & macho.N_DESC_DISCARDED) != 0;
|
||||
}
|
||||
|
||||
pub fn symbolIsTentative(sym: macho.nlist_64) bool {
|
||||
if (!symbolIsUndf(sym)) return false;
|
||||
return sym.n_value != 0;
|
||||
}
|
||||
|
||||
pub fn symbolIsTemp(sym: macho.nlist_64, sym_name: []const u8) bool {
|
||||
if (!symbolIsSect(sym)) return false;
|
||||
if (symbolIsExt(sym)) return false;
|
||||
if (!sym.sect()) return false;
|
||||
if (sym.ext()) return false;
|
||||
return mem.startsWith(u8, sym_name, "l") or mem.startsWith(u8, sym_name, "L");
|
||||
}
|
||||
|
||||
|
||||
@ -295,7 +295,7 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC
|
||||
|
||||
assert(subtractor == null);
|
||||
const sym = context.object.symtab.items[rel.r_symbolnum];
|
||||
if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
|
||||
if (sym.sect() and !sym.ext()) {
|
||||
subtractor = context.object.symbol_mapping.get(rel.r_symbolnum).?;
|
||||
} else {
|
||||
const sym_name = context.object.getString(sym.n_strx);
|
||||
@ -362,7 +362,7 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC
|
||||
const sym = context.object.symtab.items[rel.r_symbolnum];
|
||||
const sym_name = context.object.getString(sym.n_strx);
|
||||
|
||||
if (MachO.symbolIsSect(sym) and !MachO.symbolIsExt(sym)) {
|
||||
if (sym.sect() and !sym.ext()) {
|
||||
const sym_index = context.object.symbol_mapping.get(rel.r_symbolnum) orelse unreachable;
|
||||
break :target Relocation.Target{ .local = sym_index };
|
||||
}
|
||||
|
||||
@ -226,7 +226,7 @@ fn parseSymbols(self: *Dylib, allocator: *Allocator) !void {
|
||||
_ = try self.file.preadAll(strtab, symtab_cmd.stroff + self.library_offset);
|
||||
|
||||
for (slice) |sym| {
|
||||
const add_to_symtab = MachO.symbolIsExt(sym) and (MachO.symbolIsSect(sym) or MachO.symbolIsIndr(sym));
|
||||
const add_to_symtab = sym.ext() and (sym.sect() or sym.indr());
|
||||
|
||||
if (!add_to_symtab) continue;
|
||||
|
||||
|
||||
@ -338,8 +338,8 @@ const NlistWithIndex = struct {
|
||||
// afterwards by address in each group. Normally, dysymtab should
|
||||
// be enough to guarantee the sort, but turns out not every compiler
|
||||
// is kind enough to specify the symbols in the correct order.
|
||||
if (MachO.symbolIsSect(lhs.nlist)) {
|
||||
if (MachO.symbolIsSect(rhs.nlist)) {
|
||||
if (lhs.nlist.sect()) {
|
||||
if (rhs.nlist.sect()) {
|
||||
// Same group, sort by address.
|
||||
return lhs.nlist.n_value < rhs.nlist.n_value;
|
||||
} else {
|
||||
@ -414,7 +414,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: *Allocator, macho_file: *MachO)
|
||||
var iundefsym: usize = sorted_all_nlists.items.len;
|
||||
while (iundefsym > 0) : (iundefsym -= 1) {
|
||||
const nlist = sorted_all_nlists.items[iundefsym];
|
||||
if (MachO.symbolIsSect(nlist.nlist)) break;
|
||||
if (nlist.nlist.sect()) break;
|
||||
}
|
||||
break :blk iundefsym;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user