Skip to content

Commit a579f8a

Browse files
committed
macho: add generic terminal info nullable struct to a node
1 parent 4c3e6c5 commit a579f8a

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

src/link/MachO/Trie.zig

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const std = @import("std");
3434
const mem = std.mem;
3535
const leb = std.leb;
3636
const log = std.log.scoped(.link);
37+
const macho = std.macho;
3738
const testing = std.testing;
3839
const assert = std.debug.assert;
3940
const Allocator = mem.Allocator;
@@ -61,10 +62,14 @@ pub const Edge = struct {
6162

6263
pub 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

270286
const FromByteStreamError = error{

0 commit comments

Comments
 (0)