[clang] [llvm] [LFI] Add MCLFIRewriter infrastructure (PR #172906)
Zachary Yedidia via llvm-commits
llvm-commits at lists.llvm.org
Thu Dec 18 13:26:07 PST 2025
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 <zyedidia at gmail.com>
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 <zyedidia at gmail.com>
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 <zyedidia at gmail.com>
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);
More information about the llvm-commits
mailing list