Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Unified Diff: class-dump/src/CDLCDyldInfo.m

Issue 7793008: Add the 3.3.3 sources for class-dump. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « class-dump/src/CDLCDyldInfo.h ('k') | class-dump/src/CDLCDylib.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: class-dump/src/CDLCDyldInfo.m
===================================================================
--- class-dump/src/CDLCDyldInfo.m (revision 0)
+++ class-dump/src/CDLCDyldInfo.m (revision 0)
@@ -0,0 +1,662 @@
+// -*- mode: ObjC -*-
+
+// This file is part of class-dump, a utility for examining the Objective-C segment of Mach-O files.
+// Copyright (C) 1997-1998, 2000-2001, 2004-2010 Steve Nygard.
+
+#import "CDLCDyldInfo.h"
+
+#import "CDDataCursor.h"
+#import "CDMachOFile.h"
+
+#import "CDLCSegment.h"
+
+static BOOL debugBindOps = NO;
+static BOOL debugExportedSymbols = NO;
+
+// Can use dyldinfo(1) to view info.
+
+// http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-assembler/uleb128.html
+// uleb128 stands for "unsigned little endian base 128."
+// This is a compact, variable length representation of numbers used by the DWARF symbolic debugging format.
+
+// Top bit of byte is set until last byte.
+// Other 7 bits are the "slice".
+// Basically, it represents the low order bits 7 at a time, and can stop when the rest of the bits would be zero.
+// This needs to modify ptr.
+
+// For example, uleb with these bytes: e8 d7 15
+// 0xe8 = 1110 1000
+// 0xd7 = 1101 0111
+// 0x15 = 0001 0101
+
+// .... .... .... .... .... .... .... .... .... .... .... .... .... .... .... ....
+// 0xe8 1 1101000 .... .... .... .... .... .... .... .... .... .... .... .... .... .... .110 1000
+// 0xd7 1 1010111 .... .... .... .... .... .... .... .... .... .... .... .... ..10 1011 1110 1000
+// 0x15 0 0010101 .... .... .... .... .... .... .... .... .... .... .... .... ..10 1011 1110 1000
+// 0x15 0 0010101 .... .... .... .... .... .... .... .... .... .... ...0 0101 0110 1011 1110 1000
+// Result is: 0x056be8
+// So... 24 bits to encode 64 bits
+
+static uint64_t read_uleb128(const uint8_t **ptrptr, const uint8_t *end)
+{
+ static uint32_t maxlen = 0;
+ const uint8_t *ptr = *ptrptr;
+ uint64_t result = 0;
+ int bit = 0;
+
+ //NSLog(@"read_uleb128()");
+ do {
+ uint64_t slice;
+
+ if (ptr == end) {
+ NSLog(@"Malformed uleb128");
+ exit(88);
+ }
+
+ //NSLog(@"byte: %02x", *ptr);
+ slice = *ptr & 0x7f;
+
+ if (bit >= 64 || slice << bit >> bit != slice) {
+ NSLog(@"uleb128 too big");
+ exit(88);
+ } else {
+ result |= (slice << bit);
+ bit += 7;
+ }
+ }
+ while ((*ptr++ & 0x80) != 0);
+
+ if (maxlen < ptr - *ptrptr) {
+ NSMutableArray *byteStrs;
+ const uint8_t *ptr2 = *ptrptr;
+
+ byteStrs = [NSMutableArray array];
+ do {
+ [byteStrs addObject:[NSString stringWithFormat:@"%02x", *ptr2]];
+ } while (++ptr2 < ptr);
+ //NSLog(@"max uleb length now: %u (%@)", ptr - *ptrptr, [byteStrs componentsJoinedByString:@" "]);
+ //NSLog(@"sizeof(uint64_t): %u, sizeof(uintptr_t): %u", sizeof(uint64_t), sizeof(uintptr_t));
+ maxlen = ptr - *ptrptr;
+ }
+
+ *ptrptr = ptr;
+ return result;
+}
+
+static int64_t read_sleb128(const uint8_t **ptrptr, const uint8_t *end)
+{
+ const uint8_t *ptr = *ptrptr;
+
+ int64_t result = 0;
+ int bit = 0;
+ uint8_t byte;
+
+ //NSLog(@"read_sleb128()");
+ do {
+ if (ptr == end) {
+ NSLog(@"Malformed sleb128");
+ exit(88);
+ }
+
+ byte = *ptr++;
+ //NSLog(@"%02x", byte);
+ result |= ((byte & 0x7f) << bit);
+ bit += 7;
+ } while ((byte & 0x80) != 0);
+
+ //NSLog(@"result before sign extend: %ld", result);
+ // sign extend negative numbers
+ // This essentially clears out from -1 the low order bits we've already set, and combines that with our bits.
+ if ( (byte & 0x40) != 0 )
+ result |= (-1LL) << bit;
+
+ //NSLog(@"result after sign extend: %ld", result);
+
+ //NSLog(@"ptr before: %p, after: %p", *ptrptr, ptr);
+ *ptrptr = ptr;
+ return result;
+}
+
+static NSString *CDRebaseTypeString(uint8_t type)
+{
+ switch (type) {
+ case REBASE_TYPE_POINTER: return @"Pointer";
+ case REBASE_TYPE_TEXT_ABSOLUTE32: return @"Absolute 32";
+ case REBASE_TYPE_TEXT_PCREL32: return @"PC rel 32";
+ }
+
+ return @"Unknown";
+}
+
+static NSString *CDBindTypeString(uint8_t type)
+{
+ switch (type) {
+ case REBASE_TYPE_POINTER: return @"Pointer";
+ case REBASE_TYPE_TEXT_ABSOLUTE32: return @"Absolute 32";
+ case REBASE_TYPE_TEXT_PCREL32: return @"PC rel 32";
+ }
+
+ return @"Unknown";
+}
+
+// Need acces to: list of segments
+
+@implementation CDLCDyldInfo
+
+- (id)initWithDataCursor:(CDDataCursor *)cursor machOFile:(CDMachOFile *)aMachOFile;
+{
+ if ([super initWithDataCursor:cursor machOFile:aMachOFile] == nil)
+ return nil;
+
+ dyldInfoCommand.cmd = [cursor readInt32];
+ dyldInfoCommand.cmdsize = [cursor readInt32];
+
+ dyldInfoCommand.rebase_off = [cursor readInt32];
+ dyldInfoCommand.rebase_size = [cursor readInt32];
+ dyldInfoCommand.bind_off = [cursor readInt32];
+ dyldInfoCommand.bind_size = [cursor readInt32];
+ dyldInfoCommand.weak_bind_off = [cursor readInt32];
+ dyldInfoCommand.weak_bind_size = [cursor readInt32];
+ dyldInfoCommand.lazy_bind_off = [cursor readInt32];
+ dyldInfoCommand.lazy_bind_size = [cursor readInt32];
+ dyldInfoCommand.export_off = [cursor readInt32];
+ dyldInfoCommand.export_size = [cursor readInt32];
+
+#if 0
+ NSLog(@" cmdsize: %08x", dyldInfoCommand.cmdsize);
+ NSLog(@" rebase_off: %08x", dyldInfoCommand.rebase_off);
+ NSLog(@" rebase_size: %08x", dyldInfoCommand.rebase_size);
+ NSLog(@" bind_off: %08x", dyldInfoCommand.bind_off);
+ NSLog(@" bind_size: %08x", dyldInfoCommand.bind_size);
+ NSLog(@" weak_bind_off: %08x", dyldInfoCommand.weak_bind_off);
+ NSLog(@"weak_bind_size: %08x", dyldInfoCommand.weak_bind_size);
+ NSLog(@" lazy_bind_off: %08x", dyldInfoCommand.lazy_bind_off);
+ NSLog(@"lazy_bind_size: %08x", dyldInfoCommand.lazy_bind_size);
+ NSLog(@" export_off: %08x", dyldInfoCommand.export_off);
+ NSLog(@" export_size: %08x", dyldInfoCommand.export_size);
+#endif
+
+ if ([aMachOFile uses64BitABI])
+ ptrSize = sizeof(uint64_t);
+ else
+ ptrSize = sizeof(uint32_t);
+
+ symbolNamesByAddress = [[NSMutableDictionary alloc] init];
+
+ //[self logRebaseInfo];
+ [self logBindInfo]; // Acutally loads it for now.
+ [self logWeakBindInfo];
+ //[self logLazyBindInfo];
+ //[self logExportedSymbols];
+
+ //NSLog(@"symbolNamesByAddress: %@", symbolNamesByAddress);
+
+ return self;
+}
+
+- (void)dealloc;
+{
+ [symbolNamesByAddress release];
+
+ [super dealloc];
+}
+
+- (uint32_t)cmd;
+{
+ return dyldInfoCommand.cmd;
+}
+
+- (uint32_t)cmdsize;
+{
+ return dyldInfoCommand.cmdsize;
+}
+
+- (NSString *)symbolNameForAddress:(NSUInteger)address;
+{
+ return [symbolNamesByAddress objectForKey:[NSNumber numberWithUnsignedInteger:address]];
+}
+
+//
+// Rebasing
+//
+
+// address, slide, type
+// slide is constant throughout the loop
+- (void)logRebaseInfo;
+{
+ const uint8_t *start, *end, *ptr;
+ BOOL isDone = NO;
+ NSArray *segments;
+ uint64_t address;
+ uint8_t type;
+ NSUInteger rebaseCount = 0;
+
+ segments = [nonretained_machOFile segments];
+ NSLog(@"segments: %@", segments);
+ NSParameterAssert([segments count] > 0);
+
+ address = [[segments objectAtIndex:0] vmaddr];
+ type = 0;
+
+ NSLog(@"----------------------------------------------------------------------");
+ NSLog(@"rebase_off: %u, rebase_size: %u", dyldInfoCommand.rebase_off, dyldInfoCommand.rebase_size);
+ start = [nonretained_machOFile machODataBytes] + dyldInfoCommand.rebase_off;
+ end = start + dyldInfoCommand.rebase_size;
+
+ NSLog(@"address: %016lx", address);
+ ptr = start;
+ while ((ptr < end) && isDone == NO) {
+ uint8_t immediate, opcode;
+
+ immediate = *ptr & REBASE_IMMEDIATE_MASK;
+ opcode = *ptr & REBASE_OPCODE_MASK;
+ ptr++;
+
+ switch (opcode) {
+ case REBASE_OPCODE_DONE:
+ //NSLog(@"REBASE_OPCODE: DONE");
+ isDone = YES;
+ break;
+
+ case REBASE_OPCODE_SET_TYPE_IMM:
+ //NSLog(@"REBASE_OPCODE: SET_TYPE_IMM, type = 0x%x // %@", immediate, CDRebaseTypeString(immediate));
+ type = immediate;
+ break;
+
+ case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: {
+ uint64_t val = read_uleb128(&ptr, end);
+
+ //NSLog(@"REBASE_OPCODE: SET_SEGMENT_AND_OFFSET_ULEB, segment index: %u, offset: %016lx", immediate, val);
+ NSParameterAssert(immediate < [segments count]);
+ address = [[segments objectAtIndex:immediate] vmaddr] + val;
+ //NSLog(@" address: %016lx", address);
+ break;
+ }
+
+ case REBASE_OPCODE_ADD_ADDR_ULEB: {
+ uint64_t val = read_uleb128(&ptr, end);
+
+ //NSLog(@"REBASE_OPCODE: ADD_ADDR_ULEB, addr += %016lx", val);
+ address += val;
+ //NSLog(@" address: %016lx", address);
+ break;
+ }
+
+ case REBASE_OPCODE_ADD_ADDR_IMM_SCALED:
+ // I expect sizeof(uintptr_t) == sizeof(uint64_t)
+ //NSLog(@"REBASE_OPCODE: ADD_ADDR_IMM_SCALED, addr += %u * %u", immediate, sizeof(uint64_t));
+ address += immediate * ptrSize;
+ //NSLog(@" address: %016lx", address);
+ break;
+
+ case REBASE_OPCODE_DO_REBASE_IMM_TIMES: {
+ uint32_t index;
+
+ //NSLog(@"REBASE_OPCODE: DO_REBASE_IMM_TIMES, count: %u", immediate);
+ for (index = 0; index < immediate; index++) {
+ [self rebaseAddress:address type:type];
+ address += ptrSize;
+ }
+ rebaseCount += immediate;
+ break;
+ }
+
+ case REBASE_OPCODE_DO_REBASE_ULEB_TIMES: {
+ uint64_t count, index;
+
+ count = read_uleb128(&ptr, end);
+
+ //NSLog(@"REBASE_OPCODE: DO_REBASE_ULEB_TIMES, count: 0x%016lx", count);
+ for (index = 0; index < count; index++) {
+ [self rebaseAddress:address type:type];
+ address += ptrSize;
+ }
+ rebaseCount += count;
+ break;
+ }
+
+ case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: {
+ uint64_t val;
+
+ val = read_uleb128(&ptr, end);
+ // --------------------------------------------------------:
+ //NSLog(@"REBASE_OPCODE: DO_REBASE_ADD_ADDR_ULEB, addr += 0x%016lx", val);
+ [self rebaseAddress:address type:type];
+ address += ptrSize + val;
+ rebaseCount++;
+ break;
+ }
+
+ case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: {
+ uint64_t count, skip, index;
+
+ count = read_uleb128(&ptr, end);
+ skip = read_uleb128(&ptr, end);
+ //NSLog(@"REBASE_OPCODE: DO_REBASE_ULEB_TIMES_SKIPPING_ULEB, count: %016lx, skip: %016lx", count, skip);
+ for (index = 0; index < count; index++) {
+ [self rebaseAddress:address type:type];
+ address += ptrSize + skip;
+ }
+ rebaseCount += count;
+ break;
+ }
+
+ default:
+ NSLog(@"Unknown opcode op: %x, imm: %x", opcode, immediate);
+ exit(99);
+ }
+ }
+
+ NSLog(@" ptr: %p, end: %p, bytes left over: %u", ptr, end, end - ptr);
+ NSLog(@" rebaseCount: %lu", rebaseCount);
+ NSLog(@"----------------------------------------------------------------------");
+}
+
+- (void)rebaseAddress:(uint64_t)address type:(uint8_t)type;
+{
+ //NSLog(@" Rebase 0x%016lx, type: %x (%@)", address, type, CDRebaseTypeString(type));
+}
+
+//
+// Binding
+//
+
+// From mach-o/loader.h:
+// Dyld binds an image during the loading process, if the image requires any pointers to be initialized to symbols in other images.
+// Conceptually the bind information is a table of tuples:
+// <seg-index, seg-offset, type, symbol-library-ordinal, symbol-name, addend>
+
+- (void)logBindInfo;
+{
+ const uint8_t *start, *end;
+
+ if (debugBindOps) {
+ NSLog(@"----------------------------------------------------------------------");
+ NSLog(@"bind_off: %u, bind_size: %u", dyldInfoCommand.bind_off, dyldInfoCommand.bind_size);
+ }
+ start = [nonretained_machOFile machODataBytes] + dyldInfoCommand.bind_off;
+ end = start + dyldInfoCommand.bind_size;
+
+ [self logBindOps:start end:end isLazy:NO];
+}
+
+- (void)logWeakBindInfo;
+{
+ const uint8_t *start, *end;
+
+ if (debugBindOps) {
+ NSLog(@"----------------------------------------------------------------------");
+ NSLog(@"weak_bind_off: %u, weak_bind_size: %u", dyldInfoCommand.weak_bind_off, dyldInfoCommand.weak_bind_size);
+ }
+ start = [nonretained_machOFile machODataBytes] + dyldInfoCommand.weak_bind_off;
+ end = start + dyldInfoCommand.weak_bind_size;
+
+ [self logBindOps:start end:end isLazy:NO];
+}
+
+- (void)logLazyBindInfo;
+{
+ const uint8_t *start, *end;
+
+ if (debugBindOps) {
+ NSLog(@"----------------------------------------------------------------------");
+ NSLog(@"lazy_bind_off: %u, lazy_bind_size: %u", dyldInfoCommand.lazy_bind_off, dyldInfoCommand.lazy_bind_size);
+ }
+ start = [nonretained_machOFile machODataBytes] + dyldInfoCommand.lazy_bind_off;
+ end = start + dyldInfoCommand.lazy_bind_size;
+
+ [self logBindOps:start end:end isLazy:YES];
+}
+
+- (void)logBindOps:(const uint8_t *)start end:(const uint8_t *)end isLazy:(BOOL)isLazy;
+{
+ BOOL isDone = NO;
+ NSUInteger bindCount = 0;
+
+ const uint8_t *ptr;
+ NSArray *segments;
+ uint64_t address;
+ int64_t libraryOrdinal = 0;
+ uint8_t type = 0;
+ int64_t addend = 0;
+ uint8_t segmentIndex = 0;
+ const char *symbolName = NULL;
+ uint8_t symbolFlags = 0;
+
+ segments = [nonretained_machOFile segments];
+ //NSLog(@"segments: %@", segments);
+ NSParameterAssert([segments count] > 0);
+
+ address = [[segments objectAtIndex:0] vmaddr];
+
+ ptr = start;
+ while ((ptr < end) && isDone == NO) {
+ uint8_t immediate, opcode;
+
+ immediate = *ptr & BIND_IMMEDIATE_MASK;
+ opcode = *ptr & BIND_OPCODE_MASK;
+ ptr++;
+
+ switch (opcode) {
+ case BIND_OPCODE_DONE:
+ if (debugBindOps) NSLog(@"BIND_OPCODE: DONE");
+
+ // The lazy bindings have one of these at the end of each bind.
+ if (isLazy == NO)
+ isDone = YES;
+ break;
+
+ case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:
+ libraryOrdinal = immediate;
+ if (debugBindOps) NSLog(@"BIND_OPCODE: SET_DYLIB_ORDINAL_IMM, libraryOrdinal = %ld", libraryOrdinal);
+ break;
+
+ case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:
+ libraryOrdinal = read_uleb128(&ptr, end);
+ if (debugBindOps) NSLog(@"BIND_OPCODE: SET_DYLIB_ORDINAL_ULEB, libraryOrdinal = %ld", libraryOrdinal);
+ break;
+
+ case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: {
+ // Special means negative
+ if (immediate == 0)
+ libraryOrdinal = 0;
+ else {
+ int8_t val = immediate | BIND_OPCODE_MASK; // This sign extends the value
+
+ libraryOrdinal = val;
+ }
+ if (debugBindOps) NSLog(@"BIND_OPCODE: SET_DYLIB_SPECIAL_IMM, libraryOrdinal = %ld", libraryOrdinal);
+ break;
+ }
+
+ case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:
+ symbolName = (const char *)ptr;
+ symbolFlags = immediate;
+ if (debugBindOps) NSLog(@"BIND_OPCODE: SET_SYMBOL_TRAILING_FLAGS_IMM, flags: %02x, str = %s", symbolFlags, symbolName);
+ while (*ptr != 0)
+ ptr++;
+
+ ptr++; // skip the trailing zero
+
+ break;
+
+ case BIND_OPCODE_SET_TYPE_IMM:
+ if (debugBindOps) NSLog(@"BIND_OPCODE: SET_TYPE_IMM, type = %u (%@)", immediate, CDBindTypeString(immediate));
+ type = immediate;
+ break;
+
+ case BIND_OPCODE_SET_ADDEND_SLEB:
+ addend = read_sleb128(&ptr, end);
+ if (debugBindOps) NSLog(@"BIND_OPCODE: SET_ADDEND_SLEB, addend = %ld", addend);
+ break;
+
+ case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: {
+ uint64_t val;
+
+ segmentIndex = immediate;
+ val = read_uleb128(&ptr, end);
+ if (debugBindOps) NSLog(@"BIND_OPCODE: SET_SEGMENT_AND_OFFSET_ULEB, segmentIndex: %u, offset: 0x%016lx", segmentIndex, val);
+ address = [[segments objectAtIndex:segmentIndex] vmaddr] + val;
+ if (debugBindOps) NSLog(@" address = 0x%016lx", address);
+ break;
+ }
+
+ case BIND_OPCODE_ADD_ADDR_ULEB: {
+ uint64_t val;
+
+ val = read_uleb128(&ptr, end);
+ if (debugBindOps) NSLog(@"BIND_OPCODE: ADD_ADDR_ULEB, addr += 0x%016lx", val);
+ address += val;
+ break;
+ }
+
+ case BIND_OPCODE_DO_BIND:
+ if (debugBindOps) NSLog(@"BIND_OPCODE: DO_BIND");
+ [self bindAddress:address type:type symbolName:symbolName flags:symbolFlags addend:addend libraryOrdinal:libraryOrdinal];
+ address += ptrSize;
+ bindCount++;
+ break;
+
+ case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB: {
+ uint64_t val;
+
+ val = read_uleb128(&ptr, end);
+ if (debugBindOps) NSLog(@"BIND_OPCODE: DO_BIND_ADD_ADDR_ULEB, address += %016lx", val);
+ [self bindAddress:address type:type symbolName:symbolName flags:symbolFlags addend:addend libraryOrdinal:libraryOrdinal];
+ address += ptrSize + val;
+ bindCount++;
+ break;
+ }
+
+ case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:
+ if (debugBindOps) NSLog(@"BIND_OPCODE: DO_BIND_ADD_ADDR_IMM_SCALED, address += %u * %u", immediate, ptrSize);
+ [self bindAddress:address type:type symbolName:symbolName flags:symbolFlags addend:addend libraryOrdinal:libraryOrdinal];
+ address += ptrSize + immediate * ptrSize;
+ bindCount++;
+ break;
+
+ case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB: {
+ uint64_t count, skip, index;
+
+ count = read_uleb128(&ptr, end);
+ skip = read_uleb128(&ptr, end);
+ if (debugBindOps) NSLog(@"BIND_OPCODE: DO_BIND_ULEB_TIMES_SKIPPING_ULEB, count: %016lx, skip: %016lx", count, skip);
+ for (index = 0; index < count; index++) {
+ [self bindAddress:address type:type symbolName:symbolName flags:symbolFlags addend:addend libraryOrdinal:libraryOrdinal];
+ address += ptrSize + skip;
+ }
+ bindCount += count;
+ break;
+ }
+
+ default:
+ NSLog(@"Unknown opcode op: %x, imm: %x", opcode, immediate);
+ exit(99);
+ }
+ }
+
+ if (debugBindOps) {
+ NSLog(@" ptr: %p, end: %p, bytes left over: %u", ptr, end, end - ptr);
+ NSLog(@" bindCount: %lu", bindCount);
+ NSLog(@"----------------------------------------------------------------------");
+ }
+}
+
+- (void)bindAddress:(uint64_t)address type:(uint8_t)type symbolName:(const char *)symbolName flags:(uint8_t)flags
+ addend:(int64_t)addend libraryOrdinal:(int64_t)libraryOrdinal;
+{
+ NSNumber *key;
+ NSString *str;
+
+#if 0
+ NSLog(@" Bind address: %016lx, type: 0x%02x, flags: %02x, addend: %016lx, libraryOrdinal: %ld, symbolName: %s",
+ address, type, flags, addend, libraryOrdinal, symbolName);
+#endif
+
+ key = [NSNumber numberWithUnsignedInteger:address]; // I don't think 32-bit will dump 64-bit stuff.
+ str = [[NSString alloc] initWithUTF8String:symbolName];
+ [symbolNamesByAddress setObject:str forKey:key];
+ [str release];
+}
+
+//
+// Exported symbols
+//
+
+- (void)logExportedSymbols;
+{
+ const uint8_t *start, *end;
+
+ if (debugExportedSymbols) {
+ NSLog(@"----------------------------------------------------------------------");
+ NSLog(@"export_off: %u, export_size: %u", dyldInfoCommand.export_off, dyldInfoCommand.export_size);
+ NSLog(@"hexdump -Cv -s %u -n %u", dyldInfoCommand.export_off, dyldInfoCommand.export_size);
+ }
+
+ start = [nonretained_machOFile machODataBytes] + dyldInfoCommand.export_off;
+ end = start + dyldInfoCommand.export_size;
+
+ NSLog(@" Type Flags Offset Name");
+ NSLog(@"------------- ----- ---------------- ----");
+ [self printSymbols:start end:end prefix:@"" offset:0];
+}
+
+- (void)printSymbols:(const uint8_t *)start end:(const uint8_t *)end prefix:(NSString *)prefix offset:(uint32_t)offset;
+{
+ uint8_t terminalSize;
+ const uint8_t *ptr, *tptr;
+ uint8_t childCount, index;
+
+ //NSLog(@" > %s, %p-%p, offset: %lx = %p", _cmd, start, end, offset, start + offset);
+
+ ptr = start + offset;
+ NSParameterAssert(ptr < end);
+
+ terminalSize = *ptr++;
+ tptr = ptr;
+ //NSLog(@"terminalSize: %u", terminalSize);
+
+ ptr += terminalSize;
+
+ childCount = *ptr++;
+
+ if (terminalSize > 0) {
+ uint64_t flags;
+ uint8_t kind;
+
+ //NSLog(@"symbol: '%@', terminalSize: %u", prefix, terminalSize);
+ flags = read_uleb128(&tptr, end);
+ kind = flags & EXPORT_SYMBOL_FLAGS_KIND_MASK;
+ if (kind == EXPORT_SYMBOL_FLAGS_KIND_REGULAR) {
+ uint64_t offset;
+
+ offset = read_uleb128(&tptr, end);
+ NSLog(@" Regular: %04x %016lx %@", flags, offset, prefix);
+ //NSLog(@" Regular: %04x 0x%08x %@", flags, offset, prefix);
+ } else if (kind == EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL) {
+ NSLog(@"Thread Local: %04x %@, terminalSize: %u", flags, prefix, terminalSize);
+ } else {
+ NSLog(@" Unknown: %04x %x, name: %@, terminalSize: %u", flags, kind, prefix, terminalSize);
+ }
+ }
+
+ for (index = 0; index < childCount; index++) {
+ const uint8_t *edgeStart = ptr;
+ uint32_t length;
+ uint64_t nodeOffset;
+
+ while (*ptr++ != 0)
+ ;
+
+ length = ptr - edgeStart;
+ //NSLog(@"edge length: %u, edge: '%s'", length, edgeStart);
+ nodeOffset = read_uleb128(&ptr, end);
+ //NSLog(@"node offset: %lx", nodeOffset);
+
+ [self printSymbols:start end:end prefix:[NSString stringWithFormat:@"%@%s", prefix, edgeStart] offset:nodeOffset];
+ }
+
+ //NSLog(@"< %s, %p-%p, offset: %lx = %p", _cmd, start, end, offset, start + offset);
+}
+
+@end
Property changes on: class-dump/src/CDLCDyldInfo.m
___________________________________________________________________
Added: svn:eol-style
+ LF
« no previous file with comments | « class-dump/src/CDLCDyldInfo.h ('k') | class-dump/src/CDLCDylib.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698