X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/a645023da60d22e86be13f7b4d97adeff8bc6665..b2fa67a80bc53211e4d1ea81f23e9f953ee1dd6c:/src/other/dyldinfo.cpp diff --git a/src/other/dyldinfo.cpp b/src/other/dyldinfo.cpp index a6988ec..6a63ca1 100644 --- a/src/other/dyldinfo.cpp +++ b/src/other/dyldinfo.cpp @@ -50,7 +50,7 @@ static bool printExportNodes = false; static bool printSharedRegion = false; static bool printFunctionStarts = false; static bool printDylibs = false; -static cpu_type_t sPreferredArch = CPU_TYPE_I386; +static cpu_type_t sPreferredArch = 0; static cpu_type_t sPreferredSubArch = 0; @@ -73,8 +73,8 @@ class DyldInfoPrinter { public: static bool validFile(const uint8_t* fileContent); - static DyldInfoPrinter* make(const uint8_t* fileContent, uint32_t fileLength, const char* path) - { return new DyldInfoPrinter(fileContent, fileLength, path); } + static DyldInfoPrinter* make(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool printArch) + { return new DyldInfoPrinter(fileContent, fileLength, path, printArch); } virtual ~DyldInfoPrinter() {} @@ -91,7 +91,7 @@ private: typedef __gnu_cxx::hash_set, CStringEquals> StringSet; - DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path); + DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool printArch); void printRebaseInfo(); void printRebaseInfoOpcodes(); void printBindingInfo(); @@ -246,7 +246,7 @@ bool DyldInfoPrinter::validFile(const uint8_t* fileContent) } template -DyldInfoPrinter::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path) +DyldInfoPrinter::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool printArch) : fHeader(NULL), fLength(fileLength), fStrings(NULL), fStringsEnd(NULL), fSymbols(NULL), fSymbolCount(0), fInfo(NULL), fSharedRegionInfo(NULL), fFunctionStartsInfo(NULL), @@ -336,6 +336,28 @@ DyldInfoPrinter::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLen 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(); @@ -1428,6 +1450,60 @@ const uint8_t* DyldInfoPrinter::printSharedRegionInfoForEachULEB128Address(co case 4: kindStr = "32-bit offset to IMPORT"; break; + case 5: + kindStr = "thumb2 movw"; + break; + case 6: + kindStr = "ARM movw"; + break; + case 0x10: + kindStr = "thumb2 movt low high 4 bits=0"; + break; + case 0x11: + kindStr = "thumb2 movt low high 4 bits=1"; + break; + case 0x12: + kindStr = "thumb2 movt low high 4 bits=2"; + break; + case 0x13: + kindStr = "thumb2 movt low high 4 bits=3"; + break; + case 0x14: + kindStr = "thumb2 movt low high 4 bits=4"; + break; + case 0x15: + kindStr = "thumb2 movt low high 4 bits=5"; + break; + case 0x16: + kindStr = "thumb2 movt low high 4 bits=6"; + break; + case 0x17: + kindStr = "thumb2 movt low high 4 bits=7"; + break; + case 0x18: + kindStr = "thumb2 movt low high 4 bits=8"; + break; + case 0x19: + kindStr = "thumb2 movt low high 4 bits=9"; + break; + case 0x1A: + kindStr = "thumb2 movt low high 4 bits=0xA"; + break; + case 0x1B: + kindStr = "thumb2 movt low high 4 bits=0xB"; + break; + case 0x1C: + kindStr = "thumb2 movt low high 4 bits=0xC"; + break; + case 0x1D: + kindStr = "thumb2 movt low high 4 bits=0xD"; + break; + case 0x1E: + kindStr = "thumb2 movt low high 4 bits=0xE"; + break; + case 0x1F: + kindStr = "thumb2 movt low high 4 bits=0xF"; + break; } uint64_t address = 0; uint64_t delta = 0; @@ -1591,8 +1667,6 @@ const char* DyldInfoPrinter::relocTypeName(uint8_t r_type) { if ( r_type == GENERIC_RELOC_VANILLA ) return "pointer"; - else if ( r_type == PPC_RELOC_PB_LA_PTR ) - return "pb pointer"; else return "??"; } @@ -1723,22 +1797,32 @@ void DyldInfoPrinter::printSymbolTableExportInfo() template const char* DyldInfoPrinter::symbolNameForAddress(uint64_t addr) { - // find exact match in globals - const macho_nlist

* 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()]; + if ( fDynamicSymbolTable != NULL ) { + // find exact match in globals + const macho_nlist

* 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()]; + } } } - // 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

* sym = &fSymbols[0]; sym < lastSym; ++sym) { + if ( (sym->n_value() == addr) && ((sym->n_type() & N_TYPE) == N_SECT) && ((sym->n_type() & N_STAB) == 0) ) { + return &fStrings[sym->n_strx()]; + } } } - return "?"; } @@ -1889,36 +1973,37 @@ static void dump(const char* path) size_t size = OSSwapBigToHostInt32(archs[i].size); cpu_type_t cputype = OSSwapBigToHostInt32(archs[i].cputype); cpu_type_t cpusubtype = OSSwapBigToHostInt32(archs[i].cpusubtype); - if ( (cputype == sPreferredArch) - && ((sPreferredSubArch==0) || (sPreferredSubArch==cpusubtype)) ) { + if ( ((cputype == sPreferredArch) + && ((sPreferredSubArch==0) || (sPreferredSubArch==cpusubtype))) + || (sPreferredArch == 0) ) { switch(cputype) { case CPU_TYPE_POWERPC: if ( DyldInfoPrinter::validFile(p + offset) ) - DyldInfoPrinter::make(p + offset, size, path); + DyldInfoPrinter::make(p + offset, size, path, (sPreferredArch == 0)); else throw "in universal file, ppc slice does not contain ppc mach-o"; break; case CPU_TYPE_I386: if ( DyldInfoPrinter::validFile(p + offset) ) - DyldInfoPrinter::make(p + offset, size, path); + DyldInfoPrinter::make(p + offset, size, path, (sPreferredArch == 0)); else throw "in universal file, i386 slice does not contain i386 mach-o"; break; case CPU_TYPE_POWERPC64: if ( DyldInfoPrinter::validFile(p + offset) ) - DyldInfoPrinter::make(p + offset, size, path); + DyldInfoPrinter::make(p + offset, size, path, (sPreferredArch == 0)); else throw "in universal file, ppc64 slice does not contain ppc64 mach-o"; break; case CPU_TYPE_X86_64: if ( DyldInfoPrinter::validFile(p + offset) ) - DyldInfoPrinter::make(p + offset, size, path); + DyldInfoPrinter::make(p + offset, size, path, (sPreferredArch == 0)); else throw "in universal file, x86_64 slice does not contain x86_64 mach-o"; break; case CPU_TYPE_ARM: - if ( DyldInfoPrinter::validFile(p + offset) ) - DyldInfoPrinter::make(p + offset, size, path); + if ( DyldInfoPrinter::validFile(p + offset) ) + DyldInfoPrinter::make(p + offset, size, path, (sPreferredArch == 0)); else throw "in universal file, arm slice does not contain arm mach-o"; break; @@ -1929,19 +2014,19 @@ static void dump(const char* path) } } else if ( DyldInfoPrinter::validFile(p) ) { - DyldInfoPrinter::make(p, length, path); + DyldInfoPrinter::make(p, length, path, false); } else if ( DyldInfoPrinter::validFile(p) ) { - DyldInfoPrinter::make(p, length, path); + DyldInfoPrinter::make(p, length, path, false); } else if ( DyldInfoPrinter::validFile(p) ) { - DyldInfoPrinter::make(p, length, path); + DyldInfoPrinter::make(p, length, path, false); } else if ( DyldInfoPrinter::validFile(p) ) { - DyldInfoPrinter::make(p, length, path); + DyldInfoPrinter::make(p, length, path, false); } else if ( DyldInfoPrinter::validFile(p) ) { - DyldInfoPrinter::make(p, length, path); + DyldInfoPrinter::make(p, length, path, false); } else { throw "not a known file type"; @@ -1990,26 +2075,19 @@ int main(int argc, const char* argv[]) sPreferredArch = CPU_TYPE_I386; else if ( strcmp(arch, "x86_64") == 0 ) sPreferredArch = CPU_TYPE_X86_64; - else if ( strcmp(arch, "arm") == 0 ) - sPreferredArch = CPU_TYPE_ARM; - else if ( strcmp(arch, "armv4t") == 0 ) { - sPreferredArch = CPU_TYPE_ARM; - sPreferredSubArch = CPU_SUBTYPE_ARM_V4T; - } - else if ( strcmp(arch, "armv5") == 0 ) { - sPreferredArch = CPU_TYPE_ARM; - sPreferredSubArch = CPU_SUBTYPE_ARM_V5TEJ; - } - else if ( strcmp(arch, "armv6") == 0 ) { - sPreferredArch = CPU_TYPE_ARM; - sPreferredSubArch = CPU_SUBTYPE_ARM_V6; - } - else if ( strcmp(arch, "armv7") == 0 ) { - sPreferredArch = CPU_TYPE_ARM; - sPreferredSubArch = CPU_SUBTYPE_ARM_V7; + else { + bool found = false; + for (const ARMSubType* t=ARMSubTypes; t->subTypeName != NULL; ++t) { + if ( strcmp(t->subTypeName,arch) == 0 ) { + sPreferredArch = CPU_TYPE_ARM; + sPreferredSubArch = t->subType; + found = true; + break; + } + } + if ( !found ) + throwf("unknown architecture %s", arch); } - else - throwf("unknown architecture %s", arch); } else if ( strcmp(arg, "-rebase") == 0 ) { printRebase = true;