https://github.com/zyedidia updated https://github.com/llvm/llvm-project/pull/172906
>From c1102064630e7b3568b0192f563c124c05b81722 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia <[email protected]> Date: Thu, 18 Dec 2025 21:06:01 +0000 Subject: [PATCH 1/3] [LFI] Add MCLFIRewriter infrastructure --- clang/tools/driver/cc1as_main.cpp | 3 + llvm/include/llvm/MC/MCLFI.h | 22 ++++++ llvm/include/llvm/MC/MCLFIRewriter.h | 64 ++++++++++++++++ .../llvm/MC/MCParser/MCAsmParserExtension.h | 2 + llvm/include/llvm/MC/MCStreamer.h | 7 ++ llvm/include/llvm/MC/TargetRegistry.h | 21 +++++ llvm/lib/MC/CMakeLists.txt | 2 + llvm/lib/MC/MCAsmStreamer.cpp | 4 + llvm/lib/MC/MCLFI.cpp | 76 +++++++++++++++++++ llvm/lib/MC/MCLFIRewriter.cpp | 61 +++++++++++++++ llvm/lib/MC/MCObjectStreamer.cpp | 4 + llvm/lib/MC/MCParser/AsmParser.cpp | 9 ++- llvm/lib/MC/MCParser/CMakeLists.txt | 1 + llvm/lib/MC/MCParser/LFIAsmParser.cpp | 67 ++++++++++++++++ llvm/tools/llvm-mc/llvm-mc.cpp | 14 ++++ 15 files changed, 355 insertions(+), 2 deletions(-) create mode 100644 llvm/include/llvm/MC/MCLFI.h create mode 100644 llvm/include/llvm/MC/MCLFIRewriter.h create mode 100644 llvm/lib/MC/MCLFI.cpp create mode 100644 llvm/lib/MC/MCLFIRewriter.cpp create mode 100644 llvm/lib/MC/MCParser/LFIAsmParser.cpp 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 **argv) { if (NoExecStack) Str->switchSection( Ctx.getAsmInfo()->getStackSection(Ctx, /*Exec=*/false)); + + Triple T(TripleName); + if (T.isLFI()) { + Str->initSections(NoExecStack, *STI); + initializeLFIMCStreamer(*Str.get(), Ctx, T); + } + Str->emitVersionForTarget(TheTriple, VersionTuple(), nullptr, VersionTuple()); } >From 74a4738707046eba77bd363657b1455590420a94 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia <[email protected]> Date: Thu, 18 Dec 2025 21:18:12 +0000 Subject: [PATCH 2/3] Apply clang format --- llvm/include/llvm/MC/MCStreamer.h | 2 +- llvm/include/llvm/MC/TargetRegistry.h | 14 +++++++------- llvm/lib/MC/MCAsmStreamer.cpp | 3 ++- llvm/lib/MC/MCLFI.cpp | 7 +++---- llvm/lib/MC/MCObjectStreamer.cpp | 3 ++- llvm/lib/MC/MCParser/LFIAsmParser.cpp | 6 ++++-- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index aa7a457c3487c..72d4ba1e050cb 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -19,8 +19,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCDwarf.h" -#include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCLFIRewriter.h" +#include "llvm/MC/MCLinkerOptimizationHint.h" #include "llvm/MC/MCPseudoProbe.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCWinEH.h" diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h index 70c38da62237c..db1369c874c63 100644 --- a/llvm/include/llvm/MC/TargetRegistry.h +++ b/llvm/include/llvm/MC/TargetRegistry.h @@ -238,9 +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); + 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 @@ -602,8 +603,8 @@ class Target { } void createMCLFIRewriter(MCStreamer &S, - std::unique_ptr<MCRegisterInfo> &&RegInfo, - std::unique_ptr<MCInstrInfo> &&InstInfo) const { + std::unique_ptr<MCRegisterInfo> &&RegInfo, + std::unique_ptr<MCInstrInfo> &&InstInfo) const { if (MCLFIRewriterCtorFn) MCLFIRewriterCtorFn(S, std::move(RegInfo), std::move(InstInfo)); } @@ -1080,8 +1081,7 @@ struct TargetRegistry { T.InstrumentManagerCtorFn = Fn; } - static void RegisterMCLFIRewriter(Target &T, - Target::MCLFIRewriterCtorTy Fn) { + static void RegisterMCLFIRewriter(Target &T, Target::MCLFIRewriterCtorTy Fn) { T.MCLFIRewriterCtorFn = Fn; } diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 82e72fa26d759..a2e09caf792e3 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -2438,7 +2438,8 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, void MCAsmStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { - if (LFIRewriter && LFIRewriter->isEnabled() && LFIRewriter->rewriteInst(Inst, *this, STI)) + if (LFIRewriter && LFIRewriter->isEnabled() && + LFIRewriter->rewriteInst(Inst, *this, STI)) return; if (CurFrag) { diff --git a/llvm/lib/MC/MCLFI.cpp b/llvm/lib/MC/MCLFI.cpp index 4e078f5fb6819..6082edac1a781 100644 --- a/llvm/lib/MC/MCLFI.cpp +++ b/llvm/lib/MC/MCLFI.cpp @@ -23,8 +23,8 @@ 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)); + cl::desc("Don't enable rewriting for LFI."), + cl::init(true)); void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx, const Triple &TheTriple) { @@ -48,8 +48,7 @@ void initializeLFIMCStreamer(MCStreamer &Streamer, MCContext &Ctx, if (FlagEnableRewriting) { TheTarget->createMCLFIRewriter( Streamer, - std::unique_ptr<MCRegisterInfo>( - TheTarget->createMCRegInfo(TheTriple)), + std::unique_ptr<MCRegisterInfo>(TheTarget->createMCRegInfo(TheTriple)), std::unique_ptr<MCInstrInfo>(TheTarget->createMCInstrInfo())); } diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index eef2baf21f3f4..cfc46d77d212b 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -391,7 +391,8 @@ bool MCObjectStreamer::mayHaveInstructions(MCSection &Sec) const { void MCObjectStreamer::emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) { - if (LFIRewriter && LFIRewriter->isEnabled() && LFIRewriter->rewriteInst(Inst, *this, STI)) + if (LFIRewriter && LFIRewriter->isEnabled() && + LFIRewriter->rewriteInst(Inst, *this, STI)) return; MCStreamer::emitInstruction(Inst, STI); diff --git a/llvm/lib/MC/MCParser/LFIAsmParser.cpp b/llvm/lib/MC/MCParser/LFIAsmParser.cpp index b54c955cd4174..4601052e0d65f 100644 --- a/llvm/lib/MC/MCParser/LFIAsmParser.cpp +++ b/llvm/lib/MC/MCParser/LFIAsmParser.cpp @@ -31,8 +31,10 @@ class LFIAsmParser : public MCAsmParserExtension { void Initialize(MCAsmParser &Parser) override { // Call the base implementation. MCAsmParserExtension::Initialize(Parser); - addDirectiveHandler<&LFIAsmParser::parseRewriteDisable>(".lfi_rewrite_disable"); - addDirectiveHandler<&LFIAsmParser::parseRewriteEnable>(".lfi_rewrite_enable"); + addDirectiveHandler<&LFIAsmParser::parseRewriteDisable>( + ".lfi_rewrite_disable"); + addDirectiveHandler<&LFIAsmParser::parseRewriteEnable>( + ".lfi_rewrite_enable"); } /// ::= {.lfi_rewrite_disable} >From da7e64689aa175592941277af7fbea333194a125 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia <[email protected]> Date: Thu, 18 Dec 2025 21:24:28 +0000 Subject: [PATCH 3/3] [LFI] Auto-format from github actions The CI auto-formatter requested `MCStreamer & S` --- llvm/include/llvm/MC/TargetRegistry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/MC/TargetRegistry.h b/llvm/include/llvm/MC/TargetRegistry.h index db1369c874c63..88ec00e74af54 100644 --- a/llvm/include/llvm/MC/TargetRegistry.h +++ b/llvm/include/llvm/MC/TargetRegistry.h @@ -239,7 +239,7 @@ class Target { const MCInstrInfo &MCII); using MCLFIRewriterCtorTy = - MCLFIRewriter *(*)(MCStreamer &S, + MCLFIRewriter *(*)(MCStreamer & S, std::unique_ptr<MCRegisterInfo> &&RegInfo, std::unique_ptr<MCInstrInfo> &&InstInfo); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
