diff options
Diffstat (limited to 'tools/llvm-objdump/MachODump.cpp')
| -rw-r--r-- | tools/llvm-objdump/MachODump.cpp | 82 | 
1 files changed, 74 insertions, 8 deletions
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 8927f57cc97f..05c2c3f7c4cb 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -1135,7 +1135,8 @@ static void DumpInfoPlistSectionContents(StringRef Filename,      DataRefImpl Ref = Section.getRawDataRefImpl();      StringRef SegName = O->getSectionFinalSegmentName(Ref);      if (SegName == "__TEXT" && SectName == "__info_plist") { -      outs() << "Contents of (" << SegName << "," << SectName << ") section\n"; +      if (!NoLeadingHeaders) +        outs() << "Contents of (" << SegName << "," << SectName << ") section\n";        StringRef BytesStr;        Section.getContents(BytesStr);        const char *sect = reinterpret_cast<const char *>(BytesStr.data()); @@ -1223,8 +1224,13 @@ static void ProcessMachO(StringRef Name, MachOObjectFile *MachOOF,      if (Error Err = MachOOF->checkSymbolTable())        report_error(ArchiveName, FileName, std::move(Err), ArchitectureName); -  if (Disassemble) -    DisassembleMachO(FileName, MachOOF, "__TEXT", "__text"); +  if (Disassemble) { +    if (MachOOF->getHeader().filetype == MachO::MH_KEXT_BUNDLE && +	MachOOF->getHeader().cputype == MachO::CPU_TYPE_ARM64) +      DisassembleMachO(FileName, MachOOF, "__TEXT_EXEC", "__text"); +    else +      DisassembleMachO(FileName, MachOOF, "__TEXT", "__text"); +  }    if (IndirectSymbols)      PrintIndirectSymbols(MachOOF, !NonVerbose);    if (DataInCode) @@ -1920,11 +1926,45 @@ static int SymbolizerGetOpInfo(void *DisInfo, uint64_t Pc, uint64_t Offset,    if (Arch == Triple::x86_64) {      if (Size != 1 && Size != 2 && Size != 4 && Size != 0)        return 0; +    // For non MH_OBJECT types, like MH_KEXT_BUNDLE, Search the external +    // relocation entries of a linked image (if any) for an entry that matches +    // this segment offset.      if (info->O->getHeader().filetype != MachO::MH_OBJECT) { -      // TODO: -      // Search the external relocation entries of a fully linked image -      // (if any) for an entry that matches this segment offset. -      // uint64_t seg_offset = (Pc + Offset); +      uint64_t seg_offset = Pc + Offset; +      bool reloc_found = false; +      DataRefImpl Rel; +      MachO::any_relocation_info RE; +      bool isExtern = false; +      SymbolRef Symbol; +      for (const RelocationRef &Reloc : info->O->external_relocations()) { +        uint64_t RelocOffset = Reloc.getOffset(); +        if (RelocOffset == seg_offset) { +          Rel = Reloc.getRawDataRefImpl(); +          RE = info->O->getRelocation(Rel); +          // external relocation entries should always be external. +          isExtern = info->O->getPlainRelocationExternal(RE); +          if (isExtern) { +            symbol_iterator RelocSym = Reloc.getSymbol(); +            Symbol = *RelocSym; +          } +          reloc_found = true; +          break; +        } +      } +      if (reloc_found && isExtern) { +        // The Value passed in will be adjusted by the Pc if the instruction +        // adds the Pc.  But for x86_64 external relocation entries the Value +        // is the offset from the external symbol. +        if (info->O->getAnyRelocationPCRel(RE)) +          op_info->Value -= Pc + Offset + Size; +        Expected<StringRef> SymName = Symbol.getName(); +        if (!SymName) +          report_error(info->O->getFileName(), SymName.takeError()); +        const char *name = SymName->data(); +        op_info->AddSymbol.Present = 1; +        op_info->AddSymbol.Name = name; +        return 1; +      }        return 0;      }      // In MH_OBJECT filetypes search the section's relocation entries (if any) @@ -4572,6 +4612,12 @@ static void print_class64_t(uint64_t p, struct DisassembleInfo *info) {                         n_value, c.superclass);    if (name != nullptr)      outs() << " " << name; +  else { +    name = get_dyld_bind_info_symbolname(S.getAddress() + +             offset + offsetof(struct class64_t, superclass), info); +    if (name != nullptr) +      outs() << " " << name; +  }    outs() << "\n";    outs() << "         cache " << format("0x%" PRIx64, c.cache); @@ -7634,6 +7680,10 @@ static void PrintMachHeader(uint32_t magic, uint32_t cputype,        outs() << " APP_EXTENSION_SAFE";        f &= ~MachO::MH_APP_EXTENSION_SAFE;      } +    if (f & MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO) { +      outs() << " NLIST_OUTOFSYNC_WITH_DYLDINFO"; +      f &= ~MachO::MH_NLIST_OUTOFSYNC_WITH_DYLDINFO; +    }      if (f != 0 || flags == 0)        outs() << format(" 0x%08" PRIx32, f);    } else { @@ -9336,6 +9386,22 @@ void llvm::printMachOLoadCommands(const object::ObjectFile *Obj) {  //===----------------------------------------------------------------------===//  void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) { +  uint64_t BaseSegmentAddress = 0; +  for (const auto &Command : Obj->load_commands()) { +    if (Command.C.cmd == MachO::LC_SEGMENT) { +      MachO::segment_command Seg = Obj->getSegmentLoadCommand(Command); +      if (Seg.fileoff == 0 && Seg.filesize != 0) { +        BaseSegmentAddress = Seg.vmaddr; +        break; +      } +    } else if (Command.C.cmd == MachO::LC_SEGMENT_64) { +      MachO::segment_command_64 Seg = Obj->getSegment64LoadCommand(Command); +      if (Seg.fileoff == 0 && Seg.filesize != 0) { +        BaseSegmentAddress = Seg.vmaddr; +        break; +      } +    } +  }    for (const llvm::object::ExportEntry &Entry : Obj->exports()) {      uint64_t Flags = Entry.flags();      bool ReExport = (Flags & MachO::EXPORT_SYMBOL_FLAGS_REEXPORT); @@ -9349,7 +9415,7 @@ void llvm::printMachOExportsTrie(const object::MachOObjectFile *Obj) {        outs() << "[re-export] ";      else        outs() << format("0x%08llX  ", -                       Entry.address()); // FIXME:add in base address +                       Entry.address() + BaseSegmentAddress);      outs() << Entry.name();      if (WeakDef || ThreadLocal || Resolver || Abs) {        bool NeedsComma = false;  | 
