* fSymbols; uint32_t fSymbolCount; const macho_dyld_info_command
* fInfo; + const macho_linkedit_data_command
* fSharedRegionInfo; + const macho_linkedit_data_command
* fFunctionStartsInfo; uint64_t fBaseAddress; const macho_dysymtab_command
* fDynamicSymbolTable; const macho_segment_command
* fFirstSegment;
@@ -137,6 +150,7 @@ private:
bool fWriteableSegmentWithAddrOver4G;
std::vector * dylib = (macho_dylib_command *)cmd;
+ fDylibLoadCommands.push_back(dylib);
const char* lastSlash = strrchr(dylib->name(), '/');
const char* leafName = (lastSlash != NULL) ? lastSlash+1 : dylib->name();
const char* firstDot = strchr(leafName, '.');
@@ -309,10 +326,38 @@ DyldInfoPrinter::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLen
fStringsEnd = fStrings + symtab->strsize();
}
break;
+ case LC_SEGMENT_SPLIT_INFO:
+ fSharedRegionInfo = (macho_linkedit_data_command *)cmd;
+ break;
+ case LC_FUNCTION_STARTS:
+ fFunctionStartsInfo = (macho_linkedit_data_command *)cmd;
+ break;
}
cmd = (const macho_load_command *)endOfCmd;
}
+ if ( printArch ) {
+ switch ( fHeader->cputype() ) {
+ case CPU_TYPE_I386:
+ printf("for arch i386:\n");
+ break;
+ case CPU_TYPE_X86_64:
+ printf("for arch x86_64:\n");
+ break;
+ case CPU_TYPE_POWERPC:
+ printf("for arch ppc:\n");
+ break;
+ case CPU_TYPE_ARM:
+ for (const ARMSubType* t=ARMSubTypes; t->subTypeName != NULL; ++t) {
+ if ( (cpu_subtype_t)fHeader->cpusubtype() == t->subType) {
+ printf("for arch %s:\n", t->subTypeName);
+ break;
+ }
+ }
+ }
+ }
+
+
if ( printRebase ) {
if ( fInfo != NULL )
printRebaseInfo();
@@ -347,6 +392,14 @@ DyldInfoPrinter::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLen
}
if ( printExportGraph )
printExportInfoGraph();
+ if ( printExportNodes )
+ printExportInfoNodes();
+ if ( printSharedRegion )
+ printSharedRegionInfo();
+ if ( printFunctionStarts )
+ printFunctionStartsInfo();
+ if ( printDylibs )
+ printDylibsInfo();
}
static uint64_t read_uleb128(const uint8_t*& p, const uint8_t* end)
@@ -522,6 +575,8 @@ const char* DyldInfoPrinter::ordinalName(int libraryOrdinal)
template * dylib = *it;
+ const char* attribute = "";
+ switch ( dylib->cmd() ) {
+ case LC_LOAD_WEAK_DYLIB:
+ attribute = "weak_import";
+ break;
+ case LC_REEXPORT_DYLIB:
+ attribute = "re-export";
+ break;
+ case LC_LOAD_UPWARD_DYLIB:
+ attribute = "upward";
+ break;
+ case LC_LAZY_LOAD_DYLIB:
+ attribute = "lazy_load";
+ break;
+ case LC_LOAD_DYLIB:
+ default:
+ break;
+ }
+ printf(" %-12s %s\n", attribute, dylib->name());
+ }
+}
+
template <>
ppc::P::uint_t DyldInfoPrinter * lastExport = &fSymbols[fDynamicSymbolTable->iextdefsym()+fDynamicSymbolTable->nextdefsym()];
+ for (const macho_nlist * sym = &fSymbols[fDynamicSymbolTable->iextdefsym()]; sym < lastExport; ++sym) {
+ if ( (sym->n_value() == addr) && ((sym->n_type() & N_TYPE) == N_SECT) && ((sym->n_type() & N_STAB) == 0) ) {
+ return &fStrings[sym->n_strx()];
+ }
+ }
+ // find exact match in local symbols
+ const macho_nlist * lastLocal = &fSymbols[fDynamicSymbolTable->ilocalsym()+fDynamicSymbolTable->nlocalsym()];
+ for (const macho_nlist * sym = &fSymbols[fDynamicSymbolTable->ilocalsym()]; sym < lastLocal; ++sym) {
+ if ( (sym->n_value() == addr) && ((sym->n_type() & N_TYPE) == N_SECT) && ((sym->n_type() & N_STAB) == 0) ) {
+ return &fStrings[sym->n_strx()];
+ }
+ }
+ }
+ else {
+ // find exact match in all symbols
+ const macho_nlist * lastSym = &fSymbols[fSymbolCount];
+ for (const macho_nlist