X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/a645023da60d22e86be13f7b4d97adeff8bc6665..c1f6aec514f7e3059b9613d90f479f494f19f7bb:/src/other/ObjectDump.cpp?ds=sidebyside diff --git a/src/other/ObjectDump.cpp b/src/other/ObjectDump.cpp index abf7162..6763e1a 100644 --- a/src/other/ObjectDump.cpp +++ b/src/other/ObjectDump.cpp @@ -42,8 +42,9 @@ static bool sNMmode = false; static bool sShowSection = true; static bool sShowDefinitionKind = true; static bool sShowCombineKind = true; +static bool sShowLineInfo = true; -static cpu_type_t sPreferredArch = CPU_TYPE_I386; +static cpu_type_t sPreferredArch = 0xFFFFFFFF; static cpu_subtype_t sPreferredSubArch = 0xFFFFFFFF; static const char* sMatchName = NULL; static int sPrintRestrict; @@ -395,11 +396,13 @@ struct AtomSorter rightString = (char*)cstringAtom->rawContentPointer(); } } - assert(leftString != NULL); - assert(rightString != NULL); - diff = strcmp(leftString, rightString); - if ( diff != 0 ) - return (diff < 0); + if ( leftString != rightString ) { + assert(leftString != NULL); + assert(rightString != NULL); + diff = strcmp(leftString, rightString); + if ( diff != 0 ) + return (diff < 0); + } } else if ( left->section().type() == ld::Section::typeLiteral4 ) { // if literal sort by content @@ -737,33 +740,6 @@ void dumper::dumpFixup(const ld::Fixup* ref) case ld::Fixup::kindStoreBigEndian64: printf(", then store 64-bit big endian"); break; - case ld::Fixup::kindStorePPCBranch24: - printf(", then store as PPC branch24"); - break; - case ld::Fixup::kindStorePPCBranch14: - printf(", then store as PPC branch14"); - break; - case ld::Fixup::kindStorePPCPicLow14: - printf(", then store as PPC low14 pic"); - break; - case ld::Fixup::kindStorePPCPicLow16: - printf(", then store as PPC low14 pic"); - break; - case ld::Fixup::kindStorePPCPicHigh16AddLow: - printf(", then store as PPC high16 pic"); - break; - case ld::Fixup::kindStorePPCAbsLow14: - printf(", then store as PPC low14 abs"); - break; - case ld::Fixup::kindStorePPCAbsLow16: - printf(", then store as PPC low14 abs"); - break; - case ld::Fixup::kindStorePPCAbsHigh16AddLow: - printf(", then store as PPC high16 abs"); - break; - case ld::Fixup::kindStorePPCAbsHigh16: - printf(", then store as PPC high16 abs, no carry"); - break; case ld::Fixup::kindStoreX86BranchPCRel8: printf(", then store as x86 8-bit pcrel branch"); break; @@ -830,6 +806,47 @@ void dumper::dumpFixup(const ld::Fixup* ref) case ld::Fixup::kindStoreThumbHigh16: printf(", then store high-16 in Thumb movt"); break; +#if SUPPORT_ARCH_arm64 + case ld::Fixup::kindStoreARM64Branch26: + printf(", then store as ARM64 26-bit pcrel branch"); + break; + case ld::Fixup::kindStoreARM64Page21: + printf(", then store as ARM64 21-bit pcrel ADRP"); + break; + case ld::Fixup::kindStoreARM64PageOff12: + printf(", then store as ARM64 12-bit offset"); + break; + case ld::Fixup::kindStoreARM64GOTLoadPage21: + printf(", then store as ARM64 21-bit pcrel ADRP of GOT"); + break; + case ld::Fixup::kindStoreARM64GOTLoadPageOff12: + printf(", then store as ARM64 12-bit page offset of GOT"); + break; + case ld::Fixup::kindStoreARM64GOTLeaPage21: + printf(", then store as ARM64 21-bit pcrel ADRP of GOT lea"); + break; + case ld::Fixup::kindStoreARM64GOTLeaPageOff12: + printf(", then store as ARM64 12-bit page offset of GOT lea"); + break; + case ld::Fixup::kindStoreARM64TLVPLoadPage21: + printf(", then store as ARM64 21-bit pcrel ADRP of TLVP"); + break; + case ld::Fixup::kindStoreARM64TLVPLoadPageOff12: + printf(", then store as ARM64 12-bit page offset of TLVP"); + break; + case ld::Fixup::kindStoreARM64TLVPLoadNowLeaPage21: + printf(", then store as ARM64 21-bit pcrel ADRP of lea of TLVP"); + break; + case ld::Fixup::kindStoreARM64TLVPLoadNowLeaPageOff12: + printf(", then store as ARM64 12-bit page offset of lea of TLVP"); + break; + case ld::Fixup::kindStoreARM64PointerToGOT: + printf(", then store as 64-bit pointer to GOT entry"); + break; + case ld::Fixup::kindStoreARM64PCRelToGOT: + printf(", then store as 32-bit delta to GOT entry"); + break; +#endif case ld::Fixup::kindDtraceExtra: printf("dtrace static probe extra info"); break; @@ -839,12 +856,6 @@ void dumper::dumpFixup(const ld::Fixup* ref) case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear: printf("x86 dtrace static is-enabled site"); break; - case ld::Fixup::kindStorePPCDtraceCallSiteNop: - printf("ppc dtrace static probe site"); - break; - case ld::Fixup::kindStorePPCDtraceIsEnableSiteClear: - printf("ppc dtrace static is-enabled site"); - break; case ld::Fixup::kindStoreARMDtraceCallSiteNop: printf("ARM dtrace static probe site"); break; @@ -857,12 +868,81 @@ void dumper::dumpFixup(const ld::Fixup* ref) case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear: printf("Thumb dtrace static is-enabled site"); break; +#if SUPPORT_ARCH_arm64 + case ld::Fixup::kindStoreARM64DtraceCallSiteNop: + printf("ARM64 dtrace static probe site"); + break; + case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear: + printf("ARM64 dtrace static is-enabled site"); + break; +#endif case ld::Fixup::kindLazyTarget: printf("lazy reference to external symbol %s", referenceTargetAtomName(ref)); break; case ld::Fixup::kindSetLazyOffset: printf("offset of lazy binding info for %s", referenceTargetAtomName(ref)); - break; + break; + case ld::Fixup::kindIslandTarget: + printf("ultimate target of island %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindDataInCodeStartData: + printf("start of data in code"); + break; + case ld::Fixup::kindDataInCodeStartJT8: + printf("start of jump table 8 data in code"); + break; + case ld::Fixup::kindDataInCodeStartJT16: + printf("start of jump table 16 data in code"); + break; + case ld::Fixup::kindDataInCodeStartJT32: + printf("start of jump table 32 data in code"); + break; + case ld::Fixup::kindDataInCodeStartJTA32: + printf("start of jump table absolute 32 data in code"); + break; + case ld::Fixup::kindDataInCodeEnd: + printf("end of data in code"); + break; + case ld::Fixup::kindLinkerOptimizationHint: +#if SUPPORT_ARCH_arm64 + ld::Fixup::LOH_arm64 extra; + extra.addend = ref->u.addend; + printf("ARM64 hint: "); + switch(extra.info.kind) { + case LOH_ARM64_ADRP_ADRP: + printf("ADRP-ADRP"); + break; + case LOH_ARM64_ADRP_LDR: + printf("ADRP-LDR"); + break; + case LOH_ARM64_ADRP_ADD_LDR: + printf("ADRP-ADD-LDR"); + break; + case LOH_ARM64_ADRP_LDR_GOT_LDR: + printf("ADRP-LDR-GOT-LDR"); + break; + case LOH_ARM64_ADRP_ADD_STR: + printf("ADRP-ADD-STR"); + break; + case LOH_ARM64_ADRP_LDR_GOT_STR: + printf("ADRP-LDR-GOT-STR"); + break; + case LOH_ARM64_ADRP_ADD: + printf("ADRP-ADD"); + break; + default: + printf("kind=%d", extra.info.kind); + break; + } + printf(", offset1=0x%X", (extra.info.delta1 << 2) + ref->offsetInAtom); + if ( extra.info.count > 0 ) + printf(", offset2=0x%X", (extra.info.delta2 << 2) + ref->offsetInAtom); + if ( extra.info.count > 1 ) + printf(", offset3=0x%X", (extra.info.delta3 << 2) + ref->offsetInAtom); + if ( extra.info.count > 2 ) + printf(", offset4=0x%X", (extra.info.delta4 << 2) + ref->offsetInAtom); +#endif + break; case ld::Fixup::kindStoreTargetAddressLittleEndian32: printf("store 32-bit little endian address of %s", referenceTargetAtomName(ref)); break; @@ -908,13 +988,46 @@ void dumper::dumpFixup(const ld::Fixup* ref) case ld::Fixup::kindStoreTargetAddressARMLoad12: printf("ARM store 12-bit pc-rel branch to %s", referenceTargetAtomName(ref)); break; - case ld::Fixup::kindStoreTargetAddressPPCBranch24: - printf("PowerPC store 24-bit pc-rel load of %s", referenceTargetAtomName(ref)); - break; case ld::Fixup::kindSetTargetTLVTemplateOffset: case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32: case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64: printf("tlv template offset of %s", referenceTargetAtomName(ref)); + break; +#if SUPPORT_ARCH_arm64 + case ld::Fixup::kindStoreTargetAddressARM64Branch26: + printf("ARM64 store 26-bit pcrel branch to %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64Page21: + printf("ARM64 store 21-bit pcrel ADRP to %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64PageOff12: + printf("ARM64 store 12-bit page offset of %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21: + printf("ARM64 store 21-bit pcrel ADRP to GOT for %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12: + printf("ARM64 store 12-bit page offset of GOT of %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21: + printf("ARM64 store 21-bit pcrel ADRP to GOT lea for %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12: + printf("ARM64 store 12-bit page offset of GOT lea of %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadPage21: + printf("ARM64 store 21-bit pcrel ADRP to TLV for %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadPageOff12: + printf("ARM64 store 12-bit page offset of TLV of %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadNowLeaPage21: + printf("ARM64 store 21-bit pcrel ADRP to lea for TLV for %s", referenceTargetAtomName(ref)); + break; + case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12: + printf("ARM64 store 12-bit page offset of lea for TLV of %s", referenceTargetAtomName(ref)); + break; +#endif //default: // printf("unknown fixup"); // break; @@ -966,7 +1079,20 @@ void dumper::dumpAtom(const ld::Atom& atom) if ( sShowSection ) printf("section: %s,%s\n", atom.section().segmentName(), atom.section().sectionName()); if ( atom.beginUnwind() != atom.endUnwind() ) { - printf("unwind: 0x%08X\n", atom.beginUnwind()->unwindInfo); + uint32_t lastOffset = 0; + uint32_t lastCUE = 0; + bool first = true; + const char* label = "unwind:"; + for (ld::Atom::UnwindInfo::iterator it=atom.beginUnwind(); it != atom.endUnwind(); ++it) { + if ( !first ) { + printf("%s 0x%08X -> 0x%08X: 0x%08X\n", label, lastOffset, it->startOffset, lastCUE); + label = " "; + } + lastOffset = it->startOffset; + lastCUE = it->unwindInfo; + first = false; + } + printf("%s 0x%08X -> 0x%08X: 0x%08X\n", label, lastOffset, (uint32_t)atom.size(), lastCUE); } if ( atom.contentType() == ld::Atom::typeCString ) { uint8_t buffer[atom.size()+2]; @@ -1028,13 +1154,15 @@ void dumper::dumpAtom(const ld::Atom& atom) } } } - if ( atom.beginLineInfo() != atom.endLineInfo() ) { - printf("line info:\n"); - for (ld::Atom::LineInfo::iterator it = atom.beginLineInfo(); it != atom.endLineInfo(); ++it) { - printf(" offset 0x%04X, line %d, file %s\n", it->atomOffset, it->lineNumber, it->fileName); + if ( sShowLineInfo ) { + if ( atom.beginLineInfo() != atom.endLineInfo() ) { + printf("line info:\n"); + for (ld::Atom::LineInfo::iterator it = atom.beginLineInfo(); it != atom.endLineInfo(); ++it) { + printf(" offset 0x%04X, line %d, file %s\n", it->atomOffset, it->lineNumber, it->fileName); + } } } - + printf("\n"); } @@ -1088,14 +1216,27 @@ static ld::relocatable::File* createReader(const char* path) if ( mh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { const struct fat_header* fh = (struct fat_header*)p; const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header)); - for (unsigned long i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) { - if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)sPreferredArch ) { - if ( ((uint32_t)sPreferredSubArch == 0xFFFFFFFF) || ((uint32_t)sPreferredSubArch == OSSwapBigToHostInt32(archs[i].cpusubtype)) ) { - p = p + OSSwapBigToHostInt32(archs[i].offset); - mh = (struct mach_header*)p; - fileLen = OSSwapBigToHostInt32(archs[i].size); - foundFatSlice = true; - break; + if ( (uint32_t)sPreferredArch == 0xFFFFFFFF ) { + // just dump first slice of fat .o file + if ( OSSwapBigToHostInt32(fh->nfat_arch) > 0 ) { + p = p + OSSwapBigToHostInt32(archs[0].offset); + mh = (struct mach_header*)p; + fileLen = OSSwapBigToHostInt32(archs[0].size); + sPreferredArch = OSSwapBigToHostInt32(archs[0].cputype); + sPreferredSubArch = OSSwapBigToHostInt32(archs[0].cpusubtype); + foundFatSlice = true; + } + } + else { + for (unsigned long i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) { + if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)sPreferredArch ) { + if ( ((uint32_t)sPreferredSubArch == 0xFFFFFFFF) || ((uint32_t)sPreferredSubArch == OSSwapBigToHostInt32(archs[i].cpusubtype)) ) { + p = p + OSSwapBigToHostInt32(archs[i].offset); + mh = (struct mach_header*)p; + fileLen = OSSwapBigToHostInt32(archs[i].size); + foundFatSlice = true; + break; + } } } } @@ -1105,24 +1246,31 @@ static ld::relocatable::File* createReader(const char* path) objOpts.architecture = sPreferredArch; objOpts.objSubtypeMustMatch = false; objOpts.logAllFiles = false; - objOpts.convertUnwindInfo = true; + objOpts.warnUnwindConversionProblems = true; + objOpts.keepDwarfUnwind = false; + objOpts.forceDwarfConversion = false; + objOpts.verboseOptimizationHints = true; + objOpts.armUsesZeroCostExceptions = true; objOpts.subType = sPreferredSubArch; + objOpts.treateBitcodeAsData = false; + objOpts.usingBitcode = true; #if 1 if ( ! foundFatSlice ) { cpu_type_t archOfObj; cpu_subtype_t subArchOfObj; - if ( mach_o::relocatable::isObjectFile(p, &archOfObj, &subArchOfObj) ) { + Options::Platform platform; + if ( mach_o::relocatable::isObjectFile(p, &archOfObj, &subArchOfObj, &platform) ) { objOpts.architecture = archOfObj; objOpts.subType = subArchOfObj; } } - ld::relocatable::File* objResult = mach_o::relocatable::parse(p, fileLen, path, stat_buf.st_mtime, 0, objOpts); + ld::relocatable::File* objResult = mach_o::relocatable::parse(p, fileLen, path, stat_buf.st_mtime, ld::File::Ordinal::NullOrdinal(), objOpts); if ( objResult != NULL ) return objResult; // see if it is an llvm object file - objResult = lto::parse(p, fileLen, path, stat_buf.st_mtime, 0, sPreferredArch, sPreferredSubArch, false); + objResult = lto::parse(p, fileLen, path, stat_buf.st_mtime, ld::File::Ordinal::NullOrdinal(), sPreferredArch, sPreferredSubArch, false, true); if ( objResult != NULL ) return objResult; @@ -1186,36 +1334,24 @@ int main(int argc, const char* argv[]) else if ( strcmp(arg, "-no_combine") == 0 ) { sShowCombineKind = false; } + else if ( strcmp(arg, "-no_line_info") == 0 ) { + sShowLineInfo = false; + } else if ( strcmp(arg, "-arch") == 0 ) { - const char* arch = ++iarchName != NULL; ++t) { + if ( strcmp(t->archName,archName) == 0 ) { + sPreferredArch = t->cpuType; + if ( t->isSubType ) + sPreferredSubArch = t->cpuSubType; + found = true; + } } - else - throwf("unknown architecture %s", arch); + if ( !found ) + throwf("unknown architecture %s", archName); } else if ( strcmp(arg, "-only") == 0 ) { sMatchName = ++i