@@ -34,6 +34,7 @@ const std = @import("std");
3434const mem = std .mem ;
3535const leb = std .leb ;
3636const log = std .log .scoped (.link );
37+ const macho = std .macho ;
3738const testing = std .testing ;
3839const assert = std .debug .assert ;
3940const Allocator = mem .Allocator ;
@@ -61,10 +62,14 @@ pub const Edge = struct {
6162
6263pub const Node = struct {
6364 base : * Trie ,
64- /// Export flags associated with this exported symbol (if any).
65- export_flags : ? u64 = null ,
66- /// VM address offset wrt to the section this symbol is defined against (if any).
67- vmaddr_offset : ? u64 = null ,
65+ /// Terminal info associated with this node.
66+ /// If this node is not a terminal node, info is null.
67+ terminal_info : ? struct {
68+ /// Export flags associated with this exported symbol.
69+ export_flags : u64 ,
70+ /// VM address offset wrt to the section this symbol is defined against.
71+ vmaddr_offset : u64 ,
72+ } = null ,
6873 /// Offset of this node in the trie output byte stream.
6974 trie_offset : ? usize = null ,
7075 /// List of all edges originating from this node.
@@ -125,9 +130,15 @@ pub const Node = struct {
125130 var reader = stream .reader ();
126131 const node_size = try leb .readULEB128 (u64 , reader );
127132 if (node_size > 0 ) {
128- self .export_flags = try leb .readULEB128 (u64 , reader );
129- // TODO Parse flags.
130- self .vmaddr_offset = try leb .readULEB128 (u64 , reader );
133+ const export_flags = try leb .readULEB128 (u64 , reader );
134+ // TODO Parse special flags.
135+ assert (export_flags & macho .EXPORT_SYMBOL_FLAGS_REEXPORT == 0 and
136+ export_flags & macho .EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER == 0 );
137+ const vmaddr_offset = try leb .readULEB128 (u64 , reader );
138+ self .terminal_info = .{
139+ .export_flags = export_flags ,
140+ .vmaddr_offset = vmaddr_offset ,
141+ };
131142 }
132143 const nedges = try reader .readByte ();
133144 self .base .node_count += nedges ;
@@ -162,13 +173,16 @@ pub const Node = struct {
162173 /// In case this is not upheld, this method will panic.
163174 fn writeULEB128Mem (self : Node , buffer : * std .ArrayList (u8 )) ! void {
164175 assert (self .trie_offset != null ); // You need to call updateOffset first.
165- if (self .vmaddr_offset ) | offset | {
176+ if (self .terminal_info ) | info | {
166177 // Terminal node info: encode export flags and vmaddr offset of this symbol.
167178 var info_buf_len : usize = 0 ;
168179 var info_buf : [@sizeOf (u64 ) * 2 ]u8 = undefined ;
169180 var info_stream = std .io .fixedBufferStream (& info_buf );
170- try leb .writeULEB128 (info_stream .writer (), self .export_flags .? );
171- try leb .writeULEB128 (info_stream .writer (), offset );
181+ // TODO Implement for special flags.
182+ assert (info .export_flags & macho .EXPORT_SYMBOL_FLAGS_REEXPORT == 0 and
183+ info .export_flags & macho .EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER == 0 );
184+ try leb .writeULEB128 (info_stream .writer (), info .export_flags );
185+ try leb .writeULEB128 (info_stream .writer (), info .vmaddr_offset );
172186
173187 // Encode the size of the terminal node info.
174188 var size_buf : [@sizeOf (u64 )]u8 = undefined ;
@@ -208,9 +222,9 @@ pub const Node = struct {
208222 /// Updates offset of this node in the output byte stream.
209223 fn updateOffset (self : * Node , offset : usize ) UpdateResult {
210224 var node_size : usize = 0 ;
211- if (self .vmaddr_offset ) | vmaddr | {
212- node_size += sizeULEB128Mem (self .export_flags .? );
213- node_size += sizeULEB128Mem (vmaddr );
225+ if (self .terminal_info ) | info | {
226+ node_size += sizeULEB128Mem (info .export_flags );
227+ node_size += sizeULEB128Mem (info . vmaddr_offset );
214228 node_size += sizeULEB128Mem (node_size );
215229 } else {
216230 node_size += 1 ; // 0x0 for non-terminal nodes
@@ -263,8 +277,10 @@ pub fn put(self: *Trie, symbol: Symbol) !void {
263277 self .root = .{ .base = self };
264278 }
265279 const node = try self .root .? .put (symbol .name );
266- node .vmaddr_offset = symbol .vmaddr_offset ;
267- node .export_flags = symbol .export_flags ;
280+ node .terminal_info = .{
281+ .vmaddr_offset = symbol .vmaddr_offset ,
282+ .export_flags = symbol .export_flags ,
283+ };
268284}
269285
270286const FromByteStreamError = error {
0 commit comments