1
+ using System ;
2
+ using System . Collections . Generic ;
3
+
4
+ namespace LibCpp2IL . MachO
5
+ {
6
+ public class MachOExportTrie
7
+ {
8
+ public List < MachOExportEntry > Entries = new ( ) ;
9
+
10
+ private ClassReadingBinaryReader _reader ;
11
+ private long _basePtr ;
12
+
13
+ public MachOExportTrie ( ClassReadingBinaryReader reader )
14
+ {
15
+ _reader = reader ;
16
+ _basePtr = reader . BaseStream . Position ;
17
+
18
+ var children = ParseNode ( "" , 0 ) ;
19
+ while ( children . Count > 0 )
20
+ {
21
+ var current = children [ 0 ] ;
22
+ children . RemoveAt ( 0 ) ;
23
+ children . AddRange ( ParseNode ( current . Name , current . Offset ) ) ;
24
+ }
25
+ }
26
+
27
+ private List < Node > ParseNode ( string name , int offset )
28
+ {
29
+ var children = new List < Node > ( ) ;
30
+ _reader . BaseStream . Position = _basePtr + offset ;
31
+
32
+ var terminalSize = _reader . BaseStream . ReadLEB128Unsigned ( ) ;
33
+ var childrenIndex = _reader . BaseStream . Position + ( long ) terminalSize ;
34
+ if ( terminalSize != 0 )
35
+ {
36
+ var flags = ( ExportFlags ) _reader . BaseStream . ReadLEB128Unsigned ( ) ;
37
+ var address = 0L ;
38
+ var other = 0L ;
39
+ string ? importName = null ;
40
+
41
+ if ( ( flags & ExportFlags . ReExport ) != 0 )
42
+ {
43
+ other = _reader . BaseStream . ReadLEB128Signed ( ) ;
44
+ importName = _reader . ReadStringToNullAtCurrentPos ( ) ;
45
+ }
46
+ else
47
+ {
48
+ address = _reader . BaseStream . ReadLEB128Signed ( ) ;
49
+ if ( ( flags & ExportFlags . StubAndResolver ) != 0 )
50
+ other = _reader . BaseStream . ReadLEB128Signed ( ) ;
51
+ }
52
+
53
+ Entries . Add ( new ( name , address , ( long ) flags , other , importName ) ) ;
54
+ }
55
+
56
+ _reader . BaseStream . Position = childrenIndex ;
57
+ var numChildren = _reader . BaseStream . ReadLEB128Unsigned ( ) ;
58
+ for ( var i = 0ul ; i < numChildren ; i ++ )
59
+ {
60
+ var childName = _reader . ReadStringToNullAtCurrentPos ( ) ;
61
+ var childOffset = _reader . BaseStream . ReadLEB128Unsigned ( ) ;
62
+ children . Add ( new Node { Name = name + childName , Offset = ( int ) childOffset } ) ;
63
+ }
64
+
65
+ return children ;
66
+ }
67
+
68
+ [ Flags ]
69
+ private enum ExportFlags
70
+ {
71
+ KindRegular = 0 ,
72
+ KindThreadLocal = 1 ,
73
+ KindAbsolute = 2 ,
74
+ WeakDefinition = 4 ,
75
+ ReExport = 8 ,
76
+ StubAndResolver = 0x10
77
+ }
78
+
79
+ private struct Node
80
+ {
81
+ public string Name ;
82
+ public int Offset ;
83
+ }
84
+ }
85
+ }
0 commit comments