X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/ebf6f43431fe84b7b17822014a6d1f0169516e93..9543cb2f21e50a417dc8cf37eb7173f353536979:/src/other/dyldinfo.cpp diff --git a/src/other/dyldinfo.cpp b/src/other/dyldinfo.cpp index 4ad006a..6ac3311 100644 --- a/src/other/dyldinfo.cpp +++ b/src/other/dyldinfo.cpp @@ -33,8 +33,9 @@ #include #include -#include +#include +#include "configure.h" #include "MachOFileAbstraction.hpp" #include "Architectures.hpp" #include "MachOTrie.hpp" @@ -86,14 +87,6 @@ private: typedef typename A::P::E E; typedef typename A::P::uint_t pint_t; - class CStringEquals - { - public: - bool operator()(const char* left, const char* right) const { return (strcmp(left, right) == 0); } - }; - - typedef __gnu_cxx::hash_set, CStringEquals> StringSet; - DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool printArch); void printRebaseInfo(); void printRebaseInfoOpcodes(); @@ -259,6 +252,26 @@ bool DyldInfoPrinter::validFile(const uint8_t* fileContent) } #endif +#if SUPPORT_ARCH_arm64 +template <> +bool DyldInfoPrinter::validFile(const uint8_t* fileContent) +{ + const macho_header

* header = (const macho_header

*)fileContent; + if ( header->magic() != MH_MAGIC_64 ) + return false; + if ( header->cputype() != CPU_TYPE_ARM64 ) + return false; + switch (header->filetype()) { + case MH_EXECUTE: + case MH_DYLIB: + case MH_BUNDLE: + case MH_DYLINKER: + return true; + } + return false; +} +#endif + template DyldInfoPrinter::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool printArch) : fHeader(NULL), fLength(fileLength), @@ -619,7 +632,7 @@ void DyldInfoPrinter::printRebaseInfo() uint64_t segOffset = 0; uint32_t count; uint32_t skip; - int segIndex; + int segIndex = 0; pint_t segStartAddr = 0; const char* segName = "??"; const char* typeName = "??"; @@ -1271,26 +1284,50 @@ void DyldInfoPrinter::printExportInfo() parseTrie(start, end, list); //std::sort(list.begin(), list.end(), SortExportsByAddress()); for (std::vector::iterator it=list.begin(); it != list.end(); ++it) { - if ( it->flags & EXPORT_SYMBOL_FLAGS_REEXPORT ) { - if ( it->importName[0] == '\0' ) - fprintf(stdout, "[re-export] %s from dylib=%llu\n", it->name, it->other); - else - fprintf(stdout, "[re-export] %s from dylib=%llu named=%s\n", it->name, it->other, it->importName); - } - else { - const char* flags = ""; - if ( it->flags & EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION ) - flags = "[weak_def] "; - else if ( (it->flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) == EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL ) - flags = "[per-thread] "; - if ( it->flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER ) { - flags = "[resolver] "; - fprintf(stdout, "0x%08llX %s%s (resolver=0x%08llX)\n", fBaseAddress+it->address, flags, it->name, it->other); + const bool reExport = (it->flags & EXPORT_SYMBOL_FLAGS_REEXPORT); + const bool weakDef = (it->flags & EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION); + const bool threadLocal = ((it->flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) == EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL); + const bool abs = ((it->flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) == EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE); + const bool resolver = (it->flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER); + if ( reExport ) + printf("[re-export] "); + else + printf("0x%08llX ", fBaseAddress+it->address); + printf("%s", it->name); + if ( weakDef || threadLocal || resolver || abs ) { + bool needComma = false; + printf(" ["); + if ( weakDef ) { + printf("weak_def"); + needComma = true; } - else { - fprintf(stdout, "0x%08llX %s%s\n", fBaseAddress+it->address, flags, it->name); + if ( threadLocal ) { + if ( needComma ) + printf(", "); + printf("per-thread"); + needComma = true; + } + if ( abs ) { + if ( needComma ) + printf(", "); + printf("absolute"); + needComma = true; } + if ( resolver ) { + if ( needComma ) + printf(", "); + printf("resolver=0x%08llX", it->other); + needComma = true; + } + printf("]"); + } + if ( reExport ) { + if ( it->importName[0] == '\0' ) + printf(" (from %s)", fDylibs[it->other - 1]); + else + printf(" (%s from %s)", it->importName, fDylibs[it->other - 1]); } + printf("\n"); } } } @@ -1302,7 +1339,7 @@ void DyldInfoPrinter::processExportGraphNode(const uint8_t* const start, cons char* cummulativeString, int curStrOffset) { const uint8_t* const me = p; - const uint8_t terminalSize = read_uleb128(p, end); + const uint64_t terminalSize = read_uleb128(p, end); const uint8_t* children = p + terminalSize; if ( terminalSize != 0 ) { uint32_t flags = read_uleb128(p, end); @@ -1422,6 +1459,8 @@ void DyldInfoPrinter::printExportInfoNodes() printf("[addr=0x%06llX] ", address); else if ( (flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) == EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL) printf("[flags=THREAD_LOCAL addr=0x%06llX] ", address); + else if ( (flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) == EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE) + printf("[flags=ABSOLUTE addr=0x%06llX] ", address); else printf("[flags=0x%llX addr=0x%06llX] ", flags, address); } @@ -1457,7 +1496,12 @@ const uint8_t* DyldInfoPrinter::printSharedRegionInfoForEachULEB128Address(co kindStr = "64-bit pointer"; break; case 3: - kindStr = "ppc hi16"; +#if SUPPORT_ARCH_arm64 + if ( fHeader->cputype() == CPU_TYPE_ARM64 ) + kindStr = "arm64 ADRP"; + else +#endif + kindStr = "ppc hi16"; break; case 4: kindStr = "32-bit offset to IMPORT"; @@ -1741,7 +1785,6 @@ x86::P::uint_t DyldInfoPrinter::relocBase() template <> x86_64::P::uint_t DyldInfoPrinter::relocBase() { - // check for split-seg return fFirstWritableSegment->vmaddr(); } @@ -1756,6 +1799,13 @@ arm::P::uint_t DyldInfoPrinter::relocBase() } #endif +#if SUPPORT_ARCH_arm64 +template <> +arm64::P::uint_t DyldInfoPrinter::relocBase() +{ + return fFirstWritableSegment->vmaddr(); +} +#endif template <> const char* DyldInfoPrinter::relocTypeName(uint8_t r_type) @@ -1808,6 +1858,16 @@ const char* DyldInfoPrinter::relocTypeName(uint8_t r_type) } #endif +#if SUPPORT_ARCH_arm64 +template <> +const char* DyldInfoPrinter::relocTypeName(uint8_t r_type) +{ + if ( r_type == ARM64_RELOC_UNSIGNED ) + return "pointer"; + return "??"; +} +#endif + template void DyldInfoPrinter::printRelocRebaseInfo() { @@ -2104,6 +2164,14 @@ static void dump(const char* path) else throw "in universal file, arm slice does not contain arm mach-o"; break; +#endif +#if SUPPORT_ARCH_arm64 + case CPU_TYPE_ARM64: + if ( DyldInfoPrinter::validFile(p + offset) ) + DyldInfoPrinter::make(p + offset, size, path, (sPreferredArch == 0)); + else + throw "in universal file, arm64 slice does not contain arm mach-o"; + break; #endif default: throwf("in universal file, unknown architecture slice 0x%x\n", cputype); @@ -2127,6 +2195,11 @@ static void dump(const char* path) else if ( DyldInfoPrinter::validFile(p) ) { DyldInfoPrinter::make(p, length, path, false); } +#endif +#if SUPPORT_ARCH_arm64 + else if ( DyldInfoPrinter::validFile(p) ) { + DyldInfoPrinter::make(p, length, path, false); + } #endif else { throw "not a known file type"; @@ -2177,20 +2250,25 @@ int main(int argc, const char* argv[]) sPreferredArch = CPU_TYPE_I386; else if ( strcmp(arch, "x86_64") == 0 ) sPreferredArch = CPU_TYPE_X86_64; +#if SUPPORT_ARCH_arm64 + else if ( strcmp(arch, "arm64") == 0 ) + sPreferredArch = CPU_TYPE_ARM64; +#endif else { - const char* archName = argv[++i]; - if ( archName == NULL ) + if ( arch == NULL ) throw "-arch missing architecture name"; bool found = false; for (const ArchInfo* t=archInfoArray; t->archName != NULL; ++t) { - if ( strcmp(t->archName,archName) == 0 ) { + if ( strcmp(t->archName,arch) == 0 ) { sPreferredArch = t->cpuType; if ( t->isSubType ) sPreferredSubArch = t->cpuSubType; + found = true; + break; } } if ( !found ) - throwf("unknown architecture %s", archName); + throwf("unknown architecture %s", arch); } } else if ( strcmp(arg, "-rebase") == 0 ) {