diff --git a/llvm/tools/llvm-objdump/llvm-objdump.cpp b/llvm/tools/llvm-objdump/llvm-objdump.cpp --- a/llvm/tools/llvm-objdump/llvm-objdump.cpp +++ b/llvm/tools/llvm-objdump/llvm-objdump.cpp @@ -1299,15 +1299,107 @@ return std::move(*DebugBinary); } -static void disassembleObject(const Target *TheTarget, ObjectFile &Obj, - const ObjectFile &DbgObj, MCContext &Ctx, - MCDisassembler *PrimaryDisAsm, - MCDisassembler *SecondaryDisAsm, - const MCInstrAnalysis *MIA, MCInstPrinter *IP, - const MCSubtargetInfo *PrimarySTI, - const MCSubtargetInfo *SecondarySTI, - PrettyPrinter &PIP, SourcePrinter &SP, - bool InlineRelocs) { +class DisassemblerTarget { +public: + const Target *Target; + std::unique_ptr SubtargetInfo; + std::unique_ptr DisAsm; + MCContext *Context; + const MCInstrAnalysis *InstrAnalysis; + MCInstPrinter *InstPrinter; + PrettyPrinter *PrettyPrinter; + + DisassemblerTarget(const class Target *TheTarget, ObjectFile &Obj, + std::string TripleName, std::string MCPU, + SubtargetFeatures &Features); + DisassemblerTarget(DisassemblerTarget &Other, SubtargetFeatures &Features); + +private: + MCTargetOptions Options; + std::unique_ptr RegisterInfo; + std::unique_ptr AsmInfo; + std::unique_ptr InstrInfo; + std::unique_ptr ContextPtr; + std::unique_ptr ObjectFileInfo; + std::unique_ptr InstrAnalysisPtr; + std::unique_ptr InstPrinterPtr; +}; + +DisassemblerTarget::DisassemblerTarget(const class Target *TheTarget, + ObjectFile &Obj, std::string TripleName, + std::string MCPU, + SubtargetFeatures &Features) { + Target = TheTarget; + PrettyPrinter = &selectPrettyPrinter(Triple(TripleName)); + + RegisterInfo.reset(Target->createMCRegInfo(TripleName)); + if (!RegisterInfo) + reportError(Obj.getFileName(), "no register info for target " + TripleName); + + // Set up disassembler. + AsmInfo.reset(Target->createMCAsmInfo(*RegisterInfo, TripleName, Options)); + if (!AsmInfo) + reportError(Obj.getFileName(), "no assembly info for target " + TripleName); + + SubtargetInfo.reset( + Target->createMCSubtargetInfo(TripleName, MCPU, Features.getString())); + if (!SubtargetInfo) + reportError(Obj.getFileName(), + "no subtarget info for target " + TripleName); + InstrInfo.reset(Target->createMCInstrInfo()); + if (!InstrInfo) + reportError(Obj.getFileName(), + "no instruction info for target " + TripleName); + ContextPtr = + std::make_unique(Triple(TripleName), AsmInfo.get(), + RegisterInfo.get(), SubtargetInfo.get()); + Context = ContextPtr.get(); + + // FIXME: for now initialize MCObjectFileInfo with default values + ObjectFileInfo.reset(Target->createMCObjectFileInfo(*Context, /*PIC=*/false)); + Context->setObjectFileInfo(ObjectFileInfo.get()); + + DisAsm.reset(Target->createMCDisassembler(*SubtargetInfo, *Context)); + if (!DisAsm) + reportError(Obj.getFileName(), "no disassembler for target " + TripleName); + + InstrAnalysisPtr.reset(Target->createMCInstrAnalysis(InstrInfo.get())); + InstrAnalysis = InstrAnalysisPtr.get(); + + int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); + InstPrinterPtr.reset(Target->createMCInstPrinter(Triple(TripleName), + AsmPrinterVariant, *AsmInfo, + *InstrInfo, *RegisterInfo)); + if (!InstPrinterPtr) + reportError(Obj.getFileName(), + "no instruction printer for target " + TripleName); + InstPrinter = InstPrinterPtr.get(); + InstPrinter->setPrintImmHex(PrintImmHex); + InstPrinter->setPrintBranchImmAsAddress(true); + InstPrinter->setSymbolizeOperands(SymbolizeOperands); + InstPrinter->setMCInstrAnalysis(InstrAnalysis); +} + +DisassemblerTarget::DisassemblerTarget(DisassemblerTarget &Other, + SubtargetFeatures &Features) { + Target = Other.Target; + Context = Other.Context; + InstrAnalysis = Other.InstrAnalysis; + InstPrinter = Other.InstPrinter; + SubtargetInfo.reset( + Target->createMCSubtargetInfo(TripleName, MCPU, Features.getString())); + DisAsm.reset(Target->createMCDisassembler(*SubtargetInfo, *Context)); + PrettyPrinter = Other.PrettyPrinter; +} + +static void +disassembleObject(const Target *TheTarget, ObjectFile &Obj, + const ObjectFile &DbgObj, MCContext &Ctx, + MCDisassembler *PrimaryDisAsm, + std::optional &SecondaryTarget, + const MCInstrAnalysis *MIA, MCInstPrinter *IP, + const MCSubtargetInfo *PrimarySTI, PrettyPrinter &PIP, + SourcePrinter &SP, bool InlineRelocs) { const MCSubtargetInfo *STI = PrimarySTI; MCDisassembler *DisAsm = PrimaryDisAsm; bool PrimaryIsThumb = false; @@ -1757,13 +1849,17 @@ if (!MappingSymbols.empty()) { char Kind = getMappingSymbolKind(MappingSymbols, Index); DumpARMELFData = Kind == 'd'; - if (SecondarySTI) { + if (SecondaryTarget) { if (Kind == 'a') { - STI = PrimaryIsThumb ? SecondarySTI : PrimarySTI; - DisAsm = PrimaryIsThumb ? SecondaryDisAsm : PrimaryDisAsm; + STI = PrimaryIsThumb ? SecondaryTarget->SubtargetInfo.get() + : PrimarySTI; + DisAsm = PrimaryIsThumb ? SecondaryTarget->DisAsm.get() + : PrimaryDisAsm; } else if (Kind == 't') { - STI = PrimaryIsThumb ? PrimarySTI : SecondarySTI; - DisAsm = PrimaryIsThumb ? PrimaryDisAsm : SecondaryDisAsm; + STI = PrimaryIsThumb ? PrimarySTI + : SecondaryTarget->SubtargetInfo.get(); + DisAsm = PrimaryIsThumb ? PrimaryDisAsm + : SecondaryTarget->DisAsm.get(); } } } @@ -2022,20 +2118,6 @@ Features.AddFeature("+all"); } - std::unique_ptr MRI( - TheTarget->createMCRegInfo(TripleName)); - if (!MRI) - reportError(Obj->getFileName(), - "no register info for target " + TripleName); - - // Set up disassembler. - MCTargetOptions MCOptions; - std::unique_ptr AsmInfo( - TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); - if (!AsmInfo) - reportError(Obj->getFileName(), - "no assembly info for target " + TripleName); - if (MCPU.empty()) MCPU = Obj->tryGetCPUName().value_or("").str(); @@ -2062,57 +2144,23 @@ } } - std::unique_ptr STI( - TheTarget->createMCSubtargetInfo(TripleName, MCPU, Features.getString())); - if (!STI) - reportError(Obj->getFileName(), - "no subtarget info for target " + TripleName); - std::unique_ptr MII(TheTarget->createMCInstrInfo()); - if (!MII) - reportError(Obj->getFileName(), - "no instruction info for target " + TripleName); - MCContext Ctx(Triple(TripleName), AsmInfo.get(), MRI.get(), STI.get()); - // FIXME: for now initialize MCObjectFileInfo with default values - std::unique_ptr MOFI( - TheTarget->createMCObjectFileInfo(Ctx, /*PIC=*/false)); - Ctx.setObjectFileInfo(MOFI.get()); - - std::unique_ptr DisAsm( - TheTarget->createMCDisassembler(*STI, Ctx)); - if (!DisAsm) - reportError(Obj->getFileName(), "no disassembler for target " + TripleName); + DisassemblerTarget PrimaryTarget(TheTarget, *Obj, TripleName, MCPU, Features); // If we have an ARM object file, we need a second disassembler, because // ARM CPUs have two different instruction sets: ARM mode, and Thumb mode. // We use mapping symbols to switch between the two assemblers, where // appropriate. - std::unique_ptr SecondaryDisAsm; - std::unique_ptr SecondarySTI; - if (isArmElf(*Obj) && !STI->checkFeatures("+mclass")) { - if (STI->checkFeatures("+thumb-mode")) - Features.AddFeature("-thumb-mode"); - else - Features.AddFeature("+thumb-mode"); - SecondarySTI.reset(TheTarget->createMCSubtargetInfo(TripleName, MCPU, - Features.getString())); - SecondaryDisAsm.reset(TheTarget->createMCDisassembler(*SecondarySTI, Ctx)); - } + std::optional SecondaryTarget; - std::unique_ptr MIA( - TheTarget->createMCInstrAnalysis(MII.get())); - - int AsmPrinterVariant = AsmInfo->getAssemblerDialect(); - std::unique_ptr IP(TheTarget->createMCInstPrinter( - Triple(TripleName), AsmPrinterVariant, *AsmInfo, *MII, *MRI)); - if (!IP) - reportError(Obj->getFileName(), - "no instruction printer for target " + TripleName); - IP->setPrintImmHex(PrintImmHex); - IP->setPrintBranchImmAsAddress(true); - IP->setSymbolizeOperands(SymbolizeOperands); - IP->setMCInstrAnalysis(MIA.get()); - - PrettyPrinter &PIP = selectPrettyPrinter(Triple(TripleName)); + if (isArmElf(*Obj)) { + if (!PrimaryTarget.SubtargetInfo->checkFeatures("+mclass")) { + if (PrimaryTarget.SubtargetInfo->checkFeatures("+thumb-mode")) + Features.AddFeature("-thumb-mode"); + else + Features.AddFeature("+thumb-mode"); + SecondaryTarget.emplace(PrimaryTarget, Features); + } + } const ObjectFile *DbgObj = Obj; if (!FetchedBinary.getBinary() && !Obj->hasDebugInfo()) { @@ -2142,13 +2190,15 @@ SourcePrinter SP(DbgObj, TheTarget->getName()); for (StringRef Opt : DisassemblerOptions) - if (!IP->applyTargetSpecificCLOption(Opt)) + if (!PrimaryTarget.InstPrinter->applyTargetSpecificCLOption(Opt)) reportError(Obj->getFileName(), "Unrecognized disassembler option: " + Opt); - disassembleObject(TheTarget, *Obj, *DbgObj, Ctx, DisAsm.get(), - SecondaryDisAsm.get(), MIA.get(), IP.get(), STI.get(), - SecondarySTI.get(), PIP, SP, InlineRelocs); + disassembleObject(TheTarget, *Obj, *DbgObj, *PrimaryTarget.Context, + PrimaryTarget.DisAsm.get(), SecondaryTarget, + PrimaryTarget.InstrAnalysis, PrimaryTarget.InstPrinter, + PrimaryTarget.SubtargetInfo.get(), + *PrimaryTarget.PrettyPrinter, SP, InlineRelocs); } void objdump::printRelocations(const ObjectFile *Obj) {