aboutsummaryrefslogtreecommitdiff
path: root/src/link/MachO/Symbol.zig
diff options
context:
space:
mode:
authorJakub Konka <kubkon@jakubkonka.com>2021-05-02 23:40:08 +0200
committerJakub Konka <kubkon@jakubkonka.com>2021-05-04 13:09:32 +0200
commit86ab6ca56c4e6d115b017eed40dc62815a6a8e3d (patch)
tree7d429b531800dfe8614ea4789686338d5fd9a5df /src/link/MachO/Symbol.zig
parentb6be28ddcc50bd4bf085294ffcb696e31a7a1de5 (diff)
downloadzig-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.zig111
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;
}