}
#endif
+#if SUPPORT_ARCH_arm64
+template <>
+bool DyldInfoPrinter<arm64>::validFile(const uint8_t* fileContent)
+{
+ const macho_header<P>* header = (const macho_header<P>*)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 <typename A>
DyldInfoPrinter<A>::DyldInfoPrinter(const uint8_t* fileContent, uint32_t fileLength, const char* path, bool printArch)
: fHeader(NULL), fLength(fileLength),
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 = "??";
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 ) {
+ if ( weakDef || threadLocal || resolver || abs ) {
bool needComma = false;
printf(" [");
if ( weakDef ) {
printf("per-thread");
needComma = true;
}
+ if ( abs ) {
+ if ( needComma )
+ printf(", ");
+ printf("absolute");
+ needComma = true;
+ }
if ( resolver ) {
if ( needComma )
printf(", ");
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);
}
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";
template <>
x86_64::P::uint_t DyldInfoPrinter<x86_64>::relocBase()
{
- // check for split-seg
return fFirstWritableSegment->vmaddr();
}
}
#endif
+#if SUPPORT_ARCH_arm64
+template <>
+arm64::P::uint_t DyldInfoPrinter<arm64>::relocBase()
+{
+ return fFirstWritableSegment->vmaddr();
+}
+#endif
template <>
const char* DyldInfoPrinter<ppc>::relocTypeName(uint8_t r_type)
}
#endif
+#if SUPPORT_ARCH_arm64
+template <>
+const char* DyldInfoPrinter<arm64>::relocTypeName(uint8_t r_type)
+{
+ if ( r_type == ARM64_RELOC_UNSIGNED )
+ return "pointer";
+ return "??";
+}
+#endif
+
template <typename A>
void DyldInfoPrinter<A>::printRelocRebaseInfo()
{
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<arm64>::validFile(p + offset) )
+ DyldInfoPrinter<arm64>::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);
else if ( DyldInfoPrinter<arm>::validFile(p) ) {
DyldInfoPrinter<arm>::make(p, length, path, false);
}
+#endif
+#if SUPPORT_ARCH_arm64
+ else if ( DyldInfoPrinter<arm64>::validFile(p) ) {
+ DyldInfoPrinter<arm64>::make(p, length, path, false);
+ }
#endif
else {
throw "not a known file type";
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 {
if ( arch == NULL )
throw "-arch missing architecture name";