]> git.saurik.com Git - apple/ld64.git/blobdiff - src/other/ObjectDump.cpp
ld64-351.8.tar.gz
[apple/ld64.git] / src / other / ObjectDump.cpp
index abf716213f3b816b6376c5299aae1fa89b6ecbc5..6763e1a358938083c21e4cf2229e7677e736b015 100644 (file)
@@ -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 = ++i<argc? argv[i]: "";
-                                       if ( strcmp(arch, "ppc64") == 0 )
-                                               sPreferredArch = CPU_TYPE_POWERPC64;
-                                       else if ( strcmp(arch, "ppc") == 0 )
-                                               sPreferredArch = CPU_TYPE_POWERPC;
-                                       else if ( strcmp(arch, "i386") == 0 )
-                                               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;
+                                       const char* archName = argv[++i];
+                                       if ( archName == NULL )
+                                               throw "-arch missing architecture name";
+                                       bool found = false;
+                                       for (const ArchInfo* t=archInfoArray; t->archName != 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<argc? argv[i]: NULL;