diff options
| author | Jakub Konka <kubkon@jakubkonka.com> | 2021-05-02 23:40:08 +0200 |
|---|---|---|
| committer | Jakub Konka <kubkon@jakubkonka.com> | 2021-05-04 13:09:32 +0200 |
| commit | 86ab6ca56c4e6d115b017eed40dc62815a6a8e3d (patch) | |
| tree | 7d429b531800dfe8614ea4789686338d5fd9a5df /src/link/MachO/Symbol.zig | |
| parent | b6be28ddcc50bd4bf085294ffcb696e31a7a1de5 (diff) | |
| download | zig-86ab6ca56c4e6d115b017eed40dc62815a6a8e3d.tar.gz zig-86ab6ca56c4e6d115b017eed40dc62815a6a8e3d.zip | |
zld: rewrite Object to include pointers to Symbols
Diffstat (limited to 'src/link/MachO/Symbol.zig')
| -rw-r--r-- | src/link/MachO/Symbol.zig | 111 |
1 files changed, 81 insertions, 30 deletions
diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig index 9e6c2bf68a..a907146e25 100644 --- a/src/link/MachO/Symbol.zig +++ b/src/link/MachO/Symbol.zig @@ -2,31 +2,93 @@ const Symbol = @This(); const std = @import("std"); const macho = std.macho; +const mem = std.mem; -const Allocator = std.mem.Allocator; +const Allocator = mem.Allocator; +const Object = @import("Object.zig"); -pub const Tag = enum { - local, - weak, - strong, - import, - undef, +pub const Type = enum { + regular, + proxy, + unresolved, }; -tag: Tag, +/// Symbol type. +@"type": Type, + +/// Symbol name. Owned slice. name: []u8, -address: u64, -section: u8, -/// Index of file where to locate this symbol. -/// Depending on context, this is either an object file, or a dylib. -file: ?u16 = null, +pub const Regular = struct { + base: Symbol, + + /// Linkage type. + linkage: Linkage, + + /// Symbol address. + address: u64, + + /// Section ID where the symbol resides. + section: u8, + + /// Whether the symbol is a weak ref. + weak_ref: bool, + + /// File where to locate this symbol. + file: *Object, + + /// Debug stab if defined. + stab: ?struct { + /// Stab kind + kind: enum { + function, + global, + static, + }, -/// Index of this symbol within the file's symbol table. -index: ?u32 = null, + /// Size of the stab. + size: u64, + } = null, -pub fn deinit(self: *Symbol, allocator: *Allocator) void { - allocator.free(self.name); + pub const base_type: Symbol.Type = .regular; + + pub const Linkage = enum { + translation_unit, + linkage_unit, + global, + }; +}; + +pub const Proxy = struct { + base: Symbol, + + /// Dylib ordinal. + dylib: u16, + + pub const base_type: Symbol.Type = .proxy; +}; + +pub const Unresolved = struct { + base: Symbol, + + /// Alias of. + alias: ?*Symbol = null, + + /// File where this symbol was referenced. + file: *Object, + + pub const base_type: Symbol.Type = .unresolved; +}; + +pub fn deinit(base: *Symbol, allocator: *Allocator) void { + allocator.free(base.name); +} + +pub fn cast(base: *Symbol, comptime T: type) ?*T { + if (base.@"type" != T.base_type) { + return null; + } + return @fieldParentPtr(T, "base", base); } pub fn isStab(sym: macho.nlist_64) bool { @@ -55,17 +117,6 @@ pub fn isWeakDef(sym: macho.nlist_64) bool { return (sym.n_desc & macho.N_WEAK_DEF) != 0; } -/// Symbol is local if it is defined and not an extern. -pub fn isLocal(sym: macho.nlist_64) bool { - return isSect(sym) and !isExt(sym); -} - -/// Symbol is global if it is defined and an extern. -pub fn isGlobal(sym: macho.nlist_64) bool { - return isSect(sym) and isExt(sym); -} - -/// Symbol is undefined if it is not defined and an extern. -pub fn isUndef(sym: macho.nlist_64) bool { - return isUndf(sym) and isExt(sym); +pub fn isWeakRef(sym: macho.nlist_64) bool { + return (sym.n_desc & macho.N_WEAK_REF) != 0; } |
