Skip to content

Commit ed69ebe

Browse files
committed
Update macho ctx with reexport support
1 parent 12a0965 commit ed69ebe

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

builtin-plugin/SymbolResolver/macho/macho_ctx.cc

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,8 @@ intptr_t read_sleb128(const uint8_t **pp, const uint8_t *end) {
177177

178178
// dyld
179179
// bool MachOLoaded::findExportedSymbol
180-
uint8_t *walk_exported_trie(const uint8_t *start, const uint8_t *end, const char *symbol) {
180+
// MachOLoaded::trieWalk
181+
uint8_t *tail_walk(const uint8_t *start, const uint8_t *end, const char *symbol) {
181182
uint32_t visitedNodeOffsets[128];
182183
int visitedNodeOffsetCount = 0;
183184
visitedNodeOffsets[visitedNodeOffsetCount++] = 0;
@@ -191,9 +192,6 @@ uint8_t *walk_exported_trie(const uint8_t *start, const uint8_t *end, const char
191192
}
192193
if ((*symbol == '\0') && (terminalSize != 0)) {
193194
return (uint8_t *)p;
194-
// skip flag == EXPORT_SYMBOL_FLAGS_REEXPORT
195-
read_uleb128(&p, end);
196-
return (uint8_t *)read_uleb128(&p, end);
197195
}
198196
const uint8_t *children = p + terminalSize;
199197
if (children > end) {
@@ -203,6 +201,7 @@ uint8_t *walk_exported_trie(const uint8_t *start, const uint8_t *end, const char
203201
uint8_t childrenRemaining = *children++;
204202
p = children;
205203
uint64_t nodeOffset = 0;
204+
206205
for (; childrenRemaining > 0; --childrenRemaining) {
207206
const char *ss = symbol;
208207
bool wrongEdge = false;
@@ -227,7 +226,7 @@ uint8_t *walk_exported_trie(const uint8_t *start, const uint8_t *end, const char
227226
++p; // skip over last byte of uleb128
228227
if (p > end) {
229228
// diag.error("malformed trie node, child node extends past end of trie\n");
230-
return NULL;
229+
return nullptr;
231230
}
232231
} else {
233232
// the symbol so far matches this edge (child)
@@ -236,12 +235,13 @@ uint8_t *walk_exported_trie(const uint8_t *start, const uint8_t *end, const char
236235
nodeOffset = read_uleb128(&p, end);
237236
if ((nodeOffset == 0) || (&start[nodeOffset] > end)) {
238237
// diag.error("malformed trie child, nodeOffset=0x%llX out of range\n", nodeOffset);
239-
return NULL;
238+
return nullptr;
240239
}
241240
symbol = ss;
242241
break;
243242
}
244243
}
244+
245245
if (nodeOffset != 0) {
246246
if (nodeOffset > (uint64_t)(end - start)) {
247247
// diag.error("malformed trie child, nodeOffset=0x%llX out of range\n", nodeOffset);
@@ -254,10 +254,6 @@ uint8_t *walk_exported_trie(const uint8_t *start, const uint8_t *end, const char
254254
}
255255
}
256256
visitedNodeOffsets[visitedNodeOffsetCount++] = (uint32_t)nodeOffset;
257-
if (visitedNodeOffsetCount >= 128) {
258-
// diag.error("malformed trie too deep\n");
259-
return NULL;
260-
}
261257
p = &start[nodeOffset];
262258
} else
263259
p = end;
@@ -284,16 +280,24 @@ uintptr_t macho_ctx_iterate_exported_symbol(macho_ctx_t *ctx, const char *symbol
284280

285281
uint8_t *exports_start = (uint8_t *)exports;
286282
uint8_t *exports_end = exports_start + trieFileSize;
287-
uint8_t *node = (uint8_t *)walk_exported_trie(exports_start, exports_end, symbol_name);
283+
uint8_t *node = (uint8_t *)tail_walk(exports_start, exports_end, symbol_name);
288284
if (node == NULL)
289285
return 0;
290286
const uint8_t *p = node;
291287
const uintptr_t flags = read_uleb128(&p, exports_end);
292-
if (flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
293-
return 0;
294-
}
295288
if (out_flags)
296289
*out_flags = flags;
290+
if (flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
291+
const uint64_t ordinal = read_uleb128(&p, exports_end);
292+
const char *importedName = (const char *)p;
293+
if (importedName[0] == '\0') {
294+
importedName = symbol_name;
295+
return 0;
296+
}
297+
// trick
298+
printf("reexported symbol: %s\n", importedName);
299+
return (uintptr_t)importedName;
300+
}
297301
uint64_t trieValue = read_uleb128(&p, exports_end);
298302
return trieValue;
299303
#if 0

0 commit comments

Comments
 (0)