- Notifications
You must be signed in to change notification settings - Fork 15.6k
[LFI] Add MCLFIRewriter infrastructure #172906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[LFI] Add MCLFIRewriter infrastructure #172906
Conversation
| @llvm/pr-subscribers-llvm-mc Author: Zachary Yedidia (zyedidia) ChangesThis PR adds the following:
The rewriter infrastructure could be useful beyond just LFI, for any kind of MC-level rewriting (maybe Spectre mitigations?). We could use a more generic name ( Patch is 20.40 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/172906.diff 15 Files Affected:
diff --git a/clang/tools/driver/cc1as_main.cpp b/clang/tools/driver/cc1as_main.cpp index dfff194f83106..78a1226577be7 100644 --- a/clang/tools/driver/cc1as_main.cpp +++ b/clang/tools/driver/cc1as_main.cpp @@ -28,6 +28,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCLFI.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -588,6 +589,8 @@ static bool ExecuteAssemblerImpl(AssemblerInvocation &Opts, Triple T(Opts.Triple); Str.reset(TheTarget->createMCObjectStreamer( T, Ctx, std::move(MAB), std::move(OW), std::move(CE), *STI)); + if (T.isLFI()) + initializeLFIMCStreamer(*Str.get(), Ctx, T); if (T.isOSBinFormatMachO() && T.isOSDarwin()) { Triple *TVT = Opts.DarwinTargetVariantTriple ? &*Opts.DarwinTargetVariantTriple diff --git a/llvm/include/llvm/MC/MCLFI.h b/llvm/include/llvm/MC/MCLFI.h new file mode 100644 index 0000000000000..f5f638cd47cbb --- /dev/null +++ b/llvm/include/llvm/MC/MCLFI.h @@ -0,0 +1,22 @@ +//===- MCLFI.h - LFI-specific code for MC -----------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file was written by the LFI and Native Client authors. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/CommandLine.h" + +namespace llvm { + +class MCContext; +class MCStreamer; +class Triple; + +void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx, + const Triple &TheTriple); + +} // namespace llvm diff --git a/llvm/include/llvm/MC/MCLFIRewriter.h b/llvm/include/llvm/MC/MCLFIRewriter.h new file mode 100644 index 0000000000000..d78240c7819c4 --- /dev/null +++ b/llvm/include/llvm/MC/MCLFIRewriter.h @@ -0,0 +1,64 @@ +//===- llvm/MC/MCLFIRewriter.h ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file was written by the LFI and Native Client authors. +// +//===----------------------------------------------------------------------===// +// +// This file declares the MCLFIRewriter class. This is an abstract +// class that encapsulates the rewriting logic for MCInsts. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_MC_MCLFIREWRITER_H +#define LLVM_MC_MCLFIREWRITER_H + +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" + +namespace llvm { +class MCInst; +class MCSubtargetInfo; +class MCStreamer; + +class MCLFIRewriter { +private: + MCContext &Ctx; + bool Enabled = true; + +protected: + std::unique_ptr<MCInstrInfo> InstInfo; + std::unique_ptr<MCRegisterInfo> RegInfo; + +public: + MCLFIRewriter(MCContext &Ctx, std::unique_ptr<MCRegisterInfo> &&RI, + std::unique_ptr<MCInstrInfo> &&II) + : Ctx(Ctx), InstInfo(std::move(II)), RegInfo(std::move(RI)) {} + + void error(const MCInst &Inst, const char Msg[]); + + void disable(); + void enable(); + bool isEnabled(); + + bool isCall(const MCInst &Inst) const; + bool isBranch(const MCInst &Inst) const; + bool isIndirectBranch(const MCInst &Inst) const; + bool isReturn(const MCInst &Inst) const; + + bool mayLoad(const MCInst &Inst) const; + bool mayStore(const MCInst &Inst) const; + + bool mayModifyRegister(const MCInst &Inst, MCRegister Reg) const; + + virtual ~MCLFIRewriter() = default; + virtual bool rewriteInst(const MCInst &Inst, MCStreamer &Out, + const MCSubtargetInfo &STI) = 0; +}; + +} // namespace llvm +#endif diff --git a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h index 66fd28827065b..a32982ea315a8 100644 --- a/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h +++ b/llvm/include/llvm/MC/MCParser/MCAsmParserExtension.h @@ -11,6 +11,7 @@ #include "llvm/ADT/STLFunctionalExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/MC/MCLFIRewriter.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/SMLoc.h" @@ -127,6 +128,7 @@ MCAsmParserExtension *createCOFFMasmParser(); MCAsmParserExtension *createGOFFAsmParser(); MCAsmParserExtension *createXCOFFAsmParser(); MCAsmParserExtension *createWasmAsmParser(); +MCAsmParserExtension *createLFIAsmParser(MCLFIRewriter *Exp); } // end namespace llvm diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index 79c715e3820a6..aa7a457c3487c 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -20,6 +20,7 @@ #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCLinkerOptimizationHint.h" +#include "llvm/MC/MCLFIRewriter.h" #include "llvm/MC/MCPseudoProbe.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCWinEH.h" @@ -290,6 +291,8 @@ class LLVM_ABI MCStreamer { /// Returns true if the .cv_loc directive is in the right section. bool checkCVLocSection(unsigned FuncId, unsigned FileNo, SMLoc Loc); + std::unique_ptr<MCLFIRewriter> LFIRewriter; + public: MCStreamer(const MCStreamer &) = delete; MCStreamer &operator=(const MCStreamer &) = delete; @@ -307,6 +310,10 @@ class LLVM_ABI MCStreamer { return StartTokLocPtr ? *StartTokLocPtr : SMLoc(); } + void setLFIRewriter(MCLFIRewriter *Exp) { LFIRewriter.reset(Exp); } + + MCLFIRewriter *getLFIRewriter() { return LFIRewriter.get(); } + /// State management /// virtual void reset(); diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h index 234c587c8e951..70c38da62237c 100644 --- a/llvm/include/llvm/MC/TargetRegistry.h +++ b/llvm/include/llvm/MC/TargetRegistry.h @@ -46,6 +46,7 @@ class MCDisassembler; class MCInstPrinter; class MCInstrAnalysis; class MCInstrInfo; +class MCLFIRewriter; class MCObjectWriter; class MCRegisterInfo; class MCRelocationInfo; @@ -237,6 +238,10 @@ class Target { mca::InstrumentManager *(*)(const MCSubtargetInfo &STI, const MCInstrInfo &MCII); + using MCLFIRewriterCtorTy = MCLFIRewriter *(*)( + MCStreamer &S, std::unique_ptr<MCRegisterInfo> &&RegInfo, + std::unique_ptr<MCInstrInfo> &&InstInfo); + private: /// Next - The next registered target in the linked list, maintained by the /// TargetRegistry. @@ -351,6 +356,10 @@ class Target { /// InstrumentManager, if registered (default = nullptr). InstrumentManagerCtorTy InstrumentManagerCtorFn = nullptr; + // MCLFIRewriterCtorFn - Construction function for this target's + // MCLFIRewriter, if registered (default = nullptr). + MCLFIRewriterCtorTy MCLFIRewriterCtorFn = nullptr; + public: Target() = default; @@ -592,6 +601,13 @@ class Target { return nullptr; } + void createMCLFIRewriter(MCStreamer &S, + std::unique_ptr<MCRegisterInfo> &&RegInfo, + std::unique_ptr<MCInstrInfo> &&InstInfo) const { + if (MCLFIRewriterCtorFn) + MCLFIRewriterCtorFn(S, std::move(RegInfo), std::move(InstInfo)); + } + // TODO(boomanaiden154): Remove this function after LLVM 22 branches. [[deprecated("Use overload accepting Triple instead")]] MCRelocationInfo *createMCRelocationInfo(StringRef TT, MCContext &Ctx) const { @@ -1064,6 +1080,11 @@ struct TargetRegistry { T.InstrumentManagerCtorFn = Fn; } + static void RegisterMCLFIRewriter(Target &T, + Target::MCLFIRewriterCtorTy Fn) { + T.MCLFIRewriterCtorFn = Fn; + } + /// @} }; diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt index 70c4577aeec0a..ed19d513ef54f 100644 --- a/llvm/lib/MC/CMakeLists.txt +++ b/llvm/lib/MC/CMakeLists.txt @@ -31,6 +31,8 @@ add_llvm_component_library(LLVMMC MCInstrAnalysis.cpp MCInstrDesc.cpp MCInstrInfo.cpp + MCLFI.cpp + MCLFIRewriter.cpp MCLabel.cpp MCLinkerOptimizationHint.cpp MCMachOStreamer.cpp diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index e2543058394a2..82e72fa26d759 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -19,6 +19,7 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCInstPrinter.h" +#include "llvm/MC/MCLFIRewriter.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCPseudoProbe.h" @@ -2437,6 +2438,9 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, void MCAsmStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { + if (LFIRewriter && LFIRewriter->isEnabled() && LFIRewriter->rewriteInst(Inst, *this, STI)) + return; + if (CurFrag) { MCSection *Sec = getCurrentSectionOnly(); Sec->setHasInstructions(true); diff --git a/llvm/lib/MC/MCLFI.cpp b/llvm/lib/MC/MCLFI.cpp new file mode 100644 index 0000000000000..4e078f5fb6819 --- /dev/null +++ b/llvm/lib/MC/MCLFI.cpp @@ -0,0 +1,76 @@ +//===- lib/MC/MCLFI.cpp - LFI-specific MC implementation ------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file was written by the LFI and Native Client authors. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCLFI.h" +#include "llvm/BinaryFormat/ELF.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCLFIRewriter.h" +#include "llvm/MC/MCSectionELF.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Support/Alignment.h" +#include "llvm/TargetParser/Triple.h" + +static const char NoteNamespace[] = "LFI"; + +namespace llvm { + +cl::opt<bool> FlagEnableRewriting("lfi-enable-rewriter", + cl::desc("Don't enable rewriting for LFI."), + cl::init(true)); + +void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx, + const Triple &TheTriple) { + assert(TheTriple.isLFI()); + const char *NoteName; + const char *NoteArch; + switch (TheTriple.getArch()) { + case Triple::aarch64: + NoteName = ".note.LFI.ABI.aarch64"; + NoteArch = "aarch64"; + break; + default: + report_fatal_error("Unsupported architecture for LFI"); + } + + std::string Error; // empty + const Target *TheTarget = TargetRegistry::lookupTarget(TheTriple, Error); + + // Create the Target specific MCLFIRewriter. + assert(TheTarget != nullptr); + if (FlagEnableRewriting) { + TheTarget->createMCLFIRewriter( + Streamer, + std::unique_ptr<MCRegisterInfo>( + TheTarget->createMCRegInfo(TheTriple)), + std::unique_ptr<MCInstrInfo>(TheTarget->createMCInstrInfo())); + } + + // Emit an ELF Note section in its own COMDAT group which identifies LFI + // object files. + MCSectionELF *Note = Ctx.getELFSection(NoteName, ELF::SHT_NOTE, + ELF::SHF_ALLOC | ELF::SHF_GROUP, 0, + NoteName, /*IsComdat=*/true); + + Streamer.pushSection(); + Streamer.switchSection(Note); + Streamer.emitIntValue(strlen(NoteNamespace) + 1, 4); + Streamer.emitIntValue(strlen(NoteArch) + 1, 4); + Streamer.emitIntValue(ELF::NT_VERSION, 4); + Streamer.emitBytes(NoteNamespace); + Streamer.emitIntValue(0, 1); // NUL terminator + Streamer.emitValueToAlignment(Align(4)); + Streamer.emitBytes(NoteArch); + Streamer.emitIntValue(0, 1); // NUL terminator + Streamer.emitValueToAlignment(Align(4)); + Streamer.popSection(); +} + +} // namespace llvm diff --git a/llvm/lib/MC/MCLFIRewriter.cpp b/llvm/lib/MC/MCLFIRewriter.cpp new file mode 100644 index 0000000000000..5295a5c3e3771 --- /dev/null +++ b/llvm/lib/MC/MCLFIRewriter.cpp @@ -0,0 +1,61 @@ +//===- MCLFIRewriter.cpp ----------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// This file was written by the LFI and Native Client authors. +// +//===----------------------------------------------------------------------===// +// +// This file implements the MCLFIRewriter class. This is a base +// class that encapsulates the rewriting logic for MCInsts. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCLFIRewriter.h" +#include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCRegisterInfo.h" + +namespace llvm { + +void MCLFIRewriter::error(const MCInst &Inst, const char Msg[]) { + Ctx.reportError(Inst.getLoc(), Msg); +} + +void MCLFIRewriter::disable() { Enabled = false; } + +void MCLFIRewriter::enable() { Enabled = true; } + +bool MCLFIRewriter::isEnabled() { return Enabled; } + +bool MCLFIRewriter::isCall(const MCInst &Inst) const { + return InstInfo->get(Inst.getOpcode()).isCall(); +} + +bool MCLFIRewriter::isBranch(const MCInst &Inst) const { + return InstInfo->get(Inst.getOpcode()).isBranch(); +} + +bool MCLFIRewriter::isIndirectBranch(const MCInst &Inst) const { + return InstInfo->get(Inst.getOpcode()).isIndirectBranch(); +} + +bool MCLFIRewriter::isReturn(const MCInst &Inst) const { + return InstInfo->get(Inst.getOpcode()).isReturn(); +} + +bool MCLFIRewriter::mayLoad(const MCInst &Inst) const { + return InstInfo->get(Inst.getOpcode()).mayLoad(); +} + +bool MCLFIRewriter::mayStore(const MCInst &Inst) const { + return InstInfo->get(Inst.getOpcode()).mayStore(); +} + +bool MCLFIRewriter::mayModifyRegister(const MCInst &Inst, + MCRegister Reg) const { + return InstInfo->get(Inst.getOpcode()).hasDefOfPhysReg(Inst, Reg, *RegInfo); +} +} // namespace llvm diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 94468140a30b9..eef2baf21f3f4 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -15,6 +15,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCLFIRewriter.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSFrame.h" @@ -390,6 +391,9 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { void MCObjectStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { + if (LFIRewriter && LFIRewriter->isEnabled() && LFIRewriter->rewriteInst(Inst, *this, STI)) + return; + MCStreamer::emitInstruction(Inst, STI); MCSection *Sec = getCurrentSectionOnly(); diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 429cdae1fa1b6..3d650081dbd82 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -120,6 +120,7 @@ class AsmParser : public MCAsmParser { SourceMgr::DiagHandlerTy SavedDiagHandler; void *SavedDiagContext; std::unique_ptr<MCAsmParserExtension> PlatformParser; + std::unique_ptr<MCAsmParserExtension> LFIParser; SMLoc StartTokLoc; std::optional<SMLoc> CFIStartProcLoc; @@ -743,8 +744,8 @@ extern cl::opt<unsigned> AsmMacroMaxNestingDepth; AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, const MCAsmInfo &MAI, unsigned CB = 0) - : MCAsmParser(Ctx, Out, SM, MAI), CurBuffer(CB ? CB : SM.getMainFileID()), - MacrosEnabledFlag(true) { + : MCAsmParser(Ctx, Out, SM, MAI), LFIParser(nullptr), + CurBuffer(CB ? CB : SM.getMainFileID()), MacrosEnabledFlag(true) { HadError = false; // Save the old handler. SavedDiagHandler = SrcMgr.getDiagHandler(); @@ -786,6 +787,10 @@ AsmParser::AsmParser(SourceMgr &SM, MCContext &Ctx, MCStreamer &Out, } PlatformParser->Initialize(*this); + if (Out.getLFIRewriter()) { + LFIParser.reset(createLFIAsmParser(Out.getLFIRewriter())); + LFIParser->Initialize(*this); + } initializeDirectiveKindMap(); initializeCVDefRangeTypeMap(); } diff --git a/llvm/lib/MC/MCParser/CMakeLists.txt b/llvm/lib/MC/MCParser/CMakeLists.txt index 008a50e9da660..c911874fc6540 100644 --- a/llvm/lib/MC/MCParser/CMakeLists.txt +++ b/llvm/lib/MC/MCParser/CMakeLists.txt @@ -6,6 +6,7 @@ add_llvm_component_library(LLVMMCParser GOFFAsmParser.cpp DarwinAsmParser.cpp ELFAsmParser.cpp + LFIAsmParser.cpp MCAsmParser.cpp MCAsmParserExtension.cpp MCTargetAsmParser.cpp diff --git a/llvm/lib/MC/MCParser/LFIAsmParser.cpp b/llvm/lib/MC/MCParser/LFIAsmParser.cpp new file mode 100644 index 0000000000000..b54c955cd4174 --- /dev/null +++ b/llvm/lib/MC/MCParser/LFIAsmParser.cpp @@ -0,0 +1,67 @@ +//===- LFIAsmParser.cpp - LFI Assembly Parser -----------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file was written by the LFI and Native Client authors. +// +//===----------------------------------------------------------------------===// + +#include "llvm/MC/MCLFIRewriter.h" +#include "llvm/MC/MCParser/MCAsmParserExtension.h" +#include "llvm/MC/MCStreamer.h" + +using namespace llvm; + +class LFIAsmParser : public MCAsmParserExtension { + MCLFIRewriter *Rewriter; + template <bool (LFIAsmParser::*HandlerMethod)(StringRef, SMLoc)> + void addDirectiveHandler(StringRef Directive) { + MCAsmParser::ExtensionDirectiveHandler Handler = + std::make_pair(this, HandleDirective<LFIAsmParser, HandlerMethod>); + + getParser().addDirectiveHandler(Directive, Handler); + } + +public: + LFIAsmParser(MCLFIRewriter *Exp) : Rewriter(Exp) {} + void Initialize(MCAsmParser &Parser) override { + // Call the base implementation. + MCAsmParserExtension::Initialize(Parser); + addDirectiveHandler<&LFIAsmParser::parseRewriteDisable>(".lfi_rewrite_disable"); + addDirectiveHandler<&LFIAsmParser::parseRewriteEnable>(".lfi_rewrite_enable"); + } + + /// ::= {.lfi_rewrite_disable} + bool parseRewriteDisable(StringRef Directive, SMLoc Loc) { + getParser().checkForValidSection(); + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token"); + Lex(); + + Rewriter->disable(); + + return false; + } + + /// ::= {.lfi_rewrite_enable} + bool parseRewriteEnable(StringRef Directive, SMLoc Loc) { + getParser().checkForValidSection(); + if (getLexer().isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token"); + Lex(); + + Rewriter->enable(); + + return false; + } +}; + +namespace llvm { +MCAsmParserExtension *createLFIAsmParser(MCLFIRewriter *Exp) { + return new LFIAsmParser(Exp); +} +} // namespace llvm diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp index 3b2d4f8625a4c..f8a8254a79792 100644 --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -21,6 +21,7 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstrInfo.h" +#include "llvm/MC/MCLFI.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCParser/AsmLexer.h" @@ -626,6 +627,12 @@ int main(int argc, char **argv) { Str.reset(TheTarget->createAsmStreamer(Ctx, std::move(FOut), std::move(IP), std::move(CE), std::move(MAB))); + Triple T(TripleName); + if (T.isLFI()) { + Str->initSections(NoExecStack, *STI); + initializeLFIMCStreamer(*Str.get(), Ctx, T); + } + } else if (FileType == OFT_Null) { Str.reset(TheTarget->createNullStreamer(Ctx)); } else { @@ -646,6 +653,13 @@ int main(int argc, char... [truncated] |
| ✅ With the latest revision this PR passed the C/C++ code formatter. |
The CI auto-formatter requested `MCStreamer & S`
This is the second PR in the LFI series, following #167061.
This PR adds the following:
MCLFIRewriterclass, which will be used to perform LFI rewrites on a per-architecture basis. Each architecture where LFI is supported will implement a subclass (for example,Target/AArch64/MCTargetDesc/AArch64MCLFIRewriter.cpp) that will implement therewriteInstfunction to perform the actual rewriting (the AArch64 version will be added in the next PR). The generic rewriter class provides some instruction info utilities (mayLoad,mayStore) and is used to callrewriteInstduring instruction emission..lfi_rewrite_disableand.lfi_rewrite_enabledirectives that can be used to control whether rewriting is enabled or not in hand-written assembly.The rewriter infrastructure could be useful beyond just LFI, for any kind of MC-level rewriting (maybe Spectre mitigations?). We could use a more generic name (
MCRewriter) to reflect that. In that case, the AsmParser would also need to be more generic and it would probably make more sense to name the directives.rewrite_disable/.rewrite_enable, or something like that. Let me know if you think we should use a more generic name.