Skip to content
Merged
Show file tree
Hide file tree
Changes from 94 commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
5b78ea0
Forward CFI directives alongside their associated instruction to a si…
May 6, 2025
b781e83
Create a new CFI analysis for each dwarf separately
May 6, 2025
8b43f8c
Separate the logic and display
May 6, 2025
6790f90
Compile llvm mc depending on bolt
May 9, 2025
75f3b2d
Extract semantic info on MCInst from bolt
May 13, 2025
a3d08d8
Typo in evaluateStackOffsetExpr doc
May 13, 2025
7a10923
Add a DS to keep track of each register CFI state
May 13, 2025
5841b8f
Check if the CFA change is correct or not
May 14, 2025
69a8e9d
Add the CFI validation as a option to llvm-mc tool
May 14, 2025
43b54fd
Provide the directives as an arrayref instead of index range
May 14, 2025
474ff1c
Remove TODOs
May 14, 2025
8ea5d9c
Wrap all the MCPB info needed into a ExtendedMCInstrAnalysis class
May 14, 2025
e92005c
Use extended MCAnalysis instead of MCplus (directly)
May 14, 2025
7527ba2
Make the CFA checker to first generate, if not matched check the Read…
May 19, 2025
3d65eeb
Check register states as well
May 20, 2025
79c1664
Process prologue as well
May 20, 2025
02410ac
Ignore flag registers as well
May 20, 2025
dfdd22f
Enable dump
May 20, 2025
4fd37bf
Enable getting flag register through extended MCInstrAnalysis
May 20, 2025
07d38b2
Move the isolated MC semantic methods to ExtendedMCAnalysis
May 20, 2025
eb06aa4
Remove unused includes
May 21, 2025
e7c3140
Test cfi validator on following cases:
May 22, 2025
6347ef4
Prune the CFA diff checker to only check read/write
May 22, 2025
453917b
Move the CFI analysis headers to MC
May 23, 2025
9f8bca8
Move all the CFI analysis implementations to lib
May 27, 2025
2c233f9
Remove stack pointer method
May 27, 2025
12faad8
Comment out Ignoring flags at the beginning CFI analysis
May 29, 2025
282cb77
Move the necessary MCStreamer interface methods to CFIAnalysisMCStrea…
Jun 3, 2025
903e3fb
Make the update method const
Jun 5, 2025
7bb20f8
Move CFI analysis out of MC layer
Jun 5, 2025
050dbdb
Write a CFI directive to DWARF operation converter
Jun 6, 2025
223f4f7
Use UnwindTable instead of CFI State:
Jun 13, 2025
6b727ec
Make CFI analysis available both EH and Debug frames
Jun 17, 2025
580b1fc
Remove ExtendedMCA
Jun 18, 2025
7f4daf8
Use UnwindRow as state and record the UnwindHistory
Jun 20, 2025
cece662
Make CFA access easier
Jun 20, 2025
fa0505b
Rename CFI to Unwind info analysis
Jun 21, 2025
ff81fa2
Remove MCInstrAnalysis from UnwindInfo analysis
Jun 21, 2025
0cf499e
Remove redundant definitions and fields from CFIAnalysis streamer
Jun 21, 2025
969f86f
Rename CFIAnalysisStreamer to FunctionUnitStreamer
Jun 21, 2025
c57ed14
Test function unit streamer functionalities
Jun 23, 2025
0a8f747
Fix the CFIProgram usage temporary
Jun 24, 2025
48472ac
Minimize check reg diff arguments
Jun 24, 2025
9b09b49
Move `FunctionUnitStreamer` analysis calls to a different class calle…
Jun 24, 2025
7576857
Rename the library to UnwindInfoChecker
Jun 24, 2025
374f144
Fix the header guards
Jun 24, 2025
e42907f
Add file headers
Jun 24, 2025
37858ef
Resolve warnings
Jun 24, 2025
b8cdef6
Refactor UnwindInfoAnalysis
Jun 25, 2025
c1538d3
Move tests to UnwindInfoChecker folder
Jun 25, 2025
88952b0
Rename UnwindHistory to UnwindState
Jun 25, 2025
017d890
Make different methods to add instruction public
Jun 25, 2025
76b96dd
Revert bolt change
Jun 25, 2025
60689b3
Revert bolt changes
Jun 25, 2025
5b3475b
Change UnwindTable to RowContainer
Jun 25, 2025
6bcc0cc
Refactor UnwindInfoState
Jun 25, 2025
439c1d0
Revert unnecessary changes to llvm-mc
Jun 25, 2025
dfddfea
Lint
Jun 25, 2025
876f5a6
Pass the tests
Jun 25, 2025
9546eac
Fix weird end file formatting issues
Jun 25, 2025
f419eb6
Apply suggestions
Jun 25, 2025
ee98d82
Make class names more specific
Jun 26, 2025
1f7a26f
Change file names based on their class names
Jun 26, 2025
07ef762
Rename tests folder name
Jun 26, 2025
f0f7108
Remove uneccasary optional
Jun 26, 2025
d6b27ec
Summarize instantiation
Jun 26, 2025
c32c667
Either add an instruction or crash
Jun 26, 2025
325e29f
Document the process of updating CFI state
Jun 26, 2025
6a38936
Document why register information should not vanish or appear during …
Jun 26, 2025
bc5b570
Change unnessary assert to warning
Jun 26, 2025
e9b7d78
Assert ref reg when using it
Jun 26, 2025
62f3d02
Change register naming format from %{reg} to register ${regName}
Jun 26, 2025
b0cc777
Make the tests more restrict
Jun 27, 2025
55920fe
File check test as well
Jun 27, 2025
afa9914
Fix misspells
Jun 27, 2025
17348ef
Move the empty implementations to header
Jun 27, 2025
290fa4a
Use vector of pointers instead of vector of UnwindRow objects to avoi…
Jun 27, 2025
f6770c0
Document each class resposibility and rules
Jun 28, 2025
260fef2
Remove mistaked documentation
Jun 28, 2025
68fc758
Sync an assertion message with the refactors happened around it
Jun 30, 2025
62c41f7
Merge branch 'main' into cfi-validation-generation
Jun 30, 2025
f1f4796
Merge branch 'main' into cfi-validation-generation
Jun 30, 2025
77168bb
Sync implementation and `DWARFCFIAnalysis` explaination
Jul 1, 2025
627e8b3
Change error messages for CFA
Jul 1, 2025
9abf615
Test CFA corner cases
Jul 1, 2025
3c632ba
Warn the user about ignoring `.cfi_escape` directive
Jul 1, 2025
86cdd3d
Move warning to the point happening
Jul 1, 2025
ccfeaa5
Support `.cfi_label`
Jul 1, 2025
8a87530
Store only the last row in the state
Jul 1, 2025
f080e0d
Reference another file properly
Jul 1, 2025
10a84ff
Sort fields by size for memory layout and move them to the end of the…
Jul 1, 2025
d6025c6
Change the error messages to show that the warnings are not the progr…
Jul 1, 2025
c8c6582
Delete unwanted commited test
Jul 1, 2025
f2efe74
Use make unique instead of `new`ing a raw pointer
Jul 1, 2025
4d934c0
Fix a typo
Jul 2, 2025
1e9b4e6
[TEMP] Store FrameStreamer state in stack instead of trying to guess …
Jul 3, 2025
1981374
Fix the nested frame case and document the updateReceiver behavior
Jul 3, 2025
d231713
Move the definition to usage
Jul 3, 2025
aa1fbf3
Sync the braces styles
Jul 3, 2025
417c31b
Merge branch 'main' into cfi-validation-generation
amsen20 Jul 4, 2025
713877e
Add triple setting to llvm-mc args to make sure that tests are runnin…
amsen20 Jul 4, 2025
da4002c
Add overview for the link mentioned in `DWARFAnalysis`
Jul 7, 2025
29d968f
Update llvm/include/llvm/DWARFCFIChecker/DWARFCFIAnalysis.h
amsen20 Jul 7, 2025
f981996
Lint
Jul 7, 2025
76bb638
Fix cases formatting
Jul 7, 2025
0eb0f2d
Use `SmallVector` instead of `std::vector`
Jul 7, 2025
11d76c4
Update llvm/include/llvm/DWARFCFIChecker/DWARFCFIState.h
amsen20 Jul 7, 2025
d901096
Lint
Jul 7, 2025
8dd62ea
Reword the future support for dwarf expressions
Jul 7, 2025
7e461ad
Fix punctuation error
Jul 7, 2025
aa3d1d7
Reformat Run tests to one line
Jul 7, 2025
cc2107f
Change TODO style in all tests
Jul 7, 2025
2d04fc1
Check llvm-mc does not emit any error or warnings for each test
Jul 7, 2025
f83d966
Replace `CHECK-NOT` with `implicit-check-not`
Jul 7, 2025
742ab6f
Mention that remember state is not supported
Jul 8, 2025
8acbc43
Test all CFA directives
Jul 8, 2025
24e398b
Mention why remember and restore state is not supported
Jul 8, 2025
b6b9b57
Document why some directives are not supported and test them
Jul 8, 2025
5c789de
Merge branch 'main' into cfi-validation-generation
Jul 8, 2025
da67918
Depends on DebugInfoDWARFLowLevel instead of DebugInfoDWARF
Jul 8, 2025
78c8c2b
Mention why --alow-empty is used for --validate-cfi tests and how it …
Jul 8, 2025
e186683
Include low level debug info library inside headers
Jul 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions llvm/include/llvm/DWARFCFIChecker/DWARFCFIAnalysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares `DWARFCFIAnalysis` class.
/// `DWARFCFIAnalysis` is a minimal implementation of a DWARF CFI checker
/// described in this link:
/// https://discourse.llvm.org/t/rfc-dwarf-cfi-validation/86936
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_DWARFCFICHECKER_DWARFCFIANALYSIS_H
#define LLVM_DWARFCFICHECKER_DWARFCFIANALYSIS_H

#include "DWARFCFIState.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/TargetRegistry.h"

namespace llvm {

/// `DWARFCFIAnalysis` validates the DWARF Call Frame Information one machine
/// instruction at a time. This class maintains an internal CFI state
/// initialized with the prologue directives and updated with each instruction's
/// associated directives. In each update, it checks if the CFI state
/// modifications match the machine instruction influence on the CFI state or
/// not. This checking may results in errors and warnings.
///
/// In current stage, the analysis is only aware of what registers the
/// instruction modifies. If the modification is happening to a sub-register,
/// the analysis considers the super-register is modified.
///
/// In each update, for each register (or CFA), the following cases can happen:
/// 1. The unwinding rule is not changed:
/// a. The registers involved in this rule are not modified: the analysis
/// proceeds without emitting error or warning.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// a. The registers involved in this rule are not modified: the analysis
/// proceeds without emitting error or warning.
/// a. The registers involved in this rule are not modified: the analysis
/// proceeds without emitting error or warning.

This formatting seems easier to read, you may want to update the rest of the comments to reflect.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

/// b. The registers involved in this rule are modified: it emits an error.
/// 2. The unwinding rule is changed:
/// a. The rule is structurally modified (i.e., the location is changed): It
/// emits a warning.
/// b. The rule is structurally the same, but the register set is changed: it
/// emits a warning.
/// c. The rule is structurally the same, using the same set of registers, but
/// the offset is changed:
/// i. If the registers included in the rule are modified as well: It
/// emits a warning.
/// ii. If the registers included in the rule are not modified: It emits an
/// error.
///
/// The analysis only checks the CFA unwinding rule when the rule is a register
/// plus some offset. Therefore, for CFA, only cases 1, 2.b, and 2.c are
/// checked, and in all other case(s), a warning is emitted.
class DWARFCFIAnalysis {
public:
DWARFCFIAnalysis(MCContext *Context, MCInstrInfo const &MCII, bool IsEH,
ArrayRef<MCCFIInstruction> Prologue);

void update(const MCInst &Inst, ArrayRef<MCCFIInstruction> Directives);

private:
void checkRegDiff(const MCInst &Inst, DWARFRegNum Reg,
const dwarf::UnwindRow &PrevRow,
const dwarf::UnwindRow &NextRow,
const SmallSet<DWARFRegNum, 4> &Reads,
const SmallSet<DWARFRegNum, 4> &Writes);

void checkCFADiff(const MCInst &Inst, const dwarf::UnwindRow &PrevRow,
const dwarf::UnwindRow &NextRow,
const SmallSet<DWARFRegNum, 4> &Reads,
const SmallSet<DWARFRegNum, 4> &Writes);

private:
DWARFCFIState State;
MCContext *Context;
MCInstrInfo const &MCII;
MCRegisterInfo const *MCRI;
bool IsEH;
};

} // namespace llvm

#endif
49 changes: 49 additions & 0 deletions llvm/include/llvm/DWARFCFIChecker/DWARFCFIFunctionFrameAnalyzer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares CFIFunctionFrameAnalyzer class.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This class appears to be a derived class of the no-op base class CFIFunctionFrameReceiver, which overrides the methods to actually do something. An explanation here should say that, and say what it does.

In particular, after this class receives CFI instructions and thinks about them, what happens as a consequence? There don't seem to be any query methods that allow you to get information back out of it.

(Having read the rest of your code, I know the answer – the answer is that you use the provided MCContext to emit warnings and errors. But say so in a comment here, so that it isn't necessary to go and read the main source file to figure out what's going on.)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added documentation

///
//===----------------------------------------------------------------------===//

#ifndef LLVM_DWARFCFICHECKER_DWARFCFIFUNCTIONFRAMEANALYZER_H
#define LLVM_DWARFCFICHECKER_DWARFCFIFUNCTIONFRAMEANALYZER_H

#include "DWARFCFIAnalysis.h"
#include "DWARFCFIFunctionFrameReceiver.h"
#include "llvm/ADT/ArrayRef.h"

namespace llvm {

/// This class implements the `CFIFunctionFrameReceiver` interface to validate
/// Call Frame Information in a stream of function frames. For validation, it
/// instantiates a `DWARFCFIAnalysis` for each frame. The errors/warnings are
/// emitted through the `MCContext` instance to the constructor. If a frame
/// finishes without being started or if all the frames are not finished before
/// this classes is destructured, the program fails through an assertion.
class CFIFunctionFrameAnalyzer : public CFIFunctionFrameReceiver {
public:
CFIFunctionFrameAnalyzer(MCContext &Context, const MCInstrInfo &MCII)
: CFIFunctionFrameReceiver(Context), MCII(MCII) {}
~CFIFunctionFrameAnalyzer();

void startFunctionFrame(bool IsEH,
ArrayRef<MCCFIInstruction> Prologue) override;
void
emitInstructionAndDirectives(const MCInst &Inst,
ArrayRef<MCCFIInstruction> Directives) override;
void finishFunctionFrame() override;

private:
MCInstrInfo const &MCII;
std::vector<DWARFCFIAnalysis> UIAs;
};

} // namespace llvm

#endif
54 changes: 54 additions & 0 deletions llvm/include/llvm/DWARFCFIChecker/DWARFCFIFunctionFrameReceiver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares CFIFunctionFrameReceiver class.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems to be an empty base class which exists only to be derived from, and is passed to another checking function. What function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added documentation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What motivates the abstract base class here? it feels a little yagni, and adds complexity that may not be realistically needed. But perhaps there are plans for multiple implementations later?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two reasons motivate the existence of this abstract class:

  1. The main reason for developing this class is to enable DWARFCFIFunctionFrameStreamer to be moved to any other library (e.g., DebugInfo/DWARF or MC).
  2. There might be other uses for a stream of FDEs in instruction per instruction flow; a possible use case that I had in mind was a dummy printer implementation that only prints the instructions and their directives in order.

If these reasons are not enough to have this abstract class, I can just remove it.

///
//===----------------------------------------------------------------------===//

#ifndef LLVM_DWARFCFICHECKER_DWARFCFIFUNCTIONFRAMERECEIVER_H
#define LLVM_DWARFCFICHECKER_DWARFCFIFUNCTIONFRAMERECEIVER_H

#include "llvm/ADT/ArrayRef.h"

namespace llvm {

class MCCFIInstruction;
class MCContext;
class MCInst;

/// This abstract base class is an interface for receiving DWARF function frames
/// Call Frame Information. `DWARFCFIFunctionFrameStreamer` channels the
/// function frames information gathered from an `MCStreamer` using a pointer to
/// an instance of this class for the whole program.
class CFIFunctionFrameReceiver {
public:
CFIFunctionFrameReceiver(const CFIFunctionFrameReceiver &) = delete;
CFIFunctionFrameReceiver &
operator=(const CFIFunctionFrameReceiver &) = delete;
virtual ~CFIFunctionFrameReceiver() = default;

CFIFunctionFrameReceiver(MCContext &Context) : Context(Context) {}

MCContext &getContext() const { return Context; }

virtual void startFunctionFrame(bool IsEH,
ArrayRef<MCCFIInstruction> Prologue) {}
/// Instructions are processed in the program order.
virtual void
emitInstructionAndDirectives(const MCInst &Inst,
ArrayRef<MCCFIInstruction> Directives) {}
virtual void finishFunctionFrame() {}

private:
MCContext &Context;
};

} // namespace llvm

#endif
76 changes: 76 additions & 0 deletions llvm/include/llvm/DWARFCFIChecker/DWARFCFIFunctionFrameStreamer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares CFIFunctionFrameStreamer class.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing explanation: "This is a derived class of MCStreamer which looks only at [particular parts of the output] and [does something with them]"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added documentation

///
//===----------------------------------------------------------------------===//

#ifndef LLVM_DWARFCFICHECKER_DWARFCFIFUNCTIONFRAMESTREAMER_H
#define LLVM_DWARFCFICHECKER_DWARFCFIFUNCTIONFRAMESTREAMER_H

#include "DWARFCFIFunctionFrameReceiver.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCStreamer.h"
#include <memory>
#include <optional>

namespace llvm {

/// This class is an `MCStreamer` implementation that watches for machine
/// instructions and CFI directives. It cuts the stream into function frames and
/// channels them to `CFIFunctionFrameReceiver`. A function frame is the machine
/// instructions and CFI directives that are between `.cfi_startproc` and
/// `.cfi_endproc` directives.
class CFIFunctionFrameStreamer : public MCStreamer {
public:
CFIFunctionFrameStreamer(MCContext &Context,
std::unique_ptr<CFIFunctionFrameReceiver> Receiver)
: MCStreamer(Context), LastInstruction(std::nullopt),
Receiver(std::move(Receiver)), LastDirectiveIndex(0) {
assert(this->Receiver && "Receiver should not be null");
}

bool hasRawTextSupport() const override { return true; }
void emitRawTextImpl(StringRef String) override {}

bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
return true;
}

void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
Align ByteAlignment) override {}
void emitSubsectionsViaSymbols() override {};
void beginCOFFSymbolDef(const MCSymbol *Symbol) override {}
void emitCOFFSymbolStorageClass(int StorageClass) override {}
void emitCOFFSymbolType(int Type) override {}
void endCOFFSymbolDef() override {}
void emitXCOFFSymbolLinkageWithVisibility(MCSymbol *Symbol,
MCSymbolAttr Linkage,
MCSymbolAttr Visibility) override {}

void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
void emitCFIStartProcImpl(MCDwarfFrameInfo &Frame) override;
void emitCFIEndProcImpl(MCDwarfFrameInfo &CurFrame) override;

private:
std::pair<unsigned, unsigned> updateDirectivesRange();
void updateReceiver();

private:
std::vector<unsigned> FrameIndices;
std::optional<MCInst> LastInstruction;
std::unique_ptr<CFIFunctionFrameReceiver> Receiver;
unsigned LastDirectiveIndex;
};

} // namespace llvm

#endif
51 changes: 51 additions & 0 deletions llvm/include/llvm/DWARFCFIChecker/DWARFCFIState.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//===----------------------------------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares DWARFCFIState class.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing explanation: what is this class for? How is somebody expected to use it?

Looking just at the API here, it seems strangely "write only". There's an update function to pass data in to it, and you can retrieve an iterator pointing at the current last row (if any), but how does anyone read data out of it again? It looks almost impossible. You could step through the table starting from the iterator returned from getCurrentUnwindRow, but you wouldn't be able to tell when to stop, because you can't check it against Table.begin() from outside the class, because Table itself is private.

I look at this file and think "surely once you've put data in here it can't be retrieved, so what's the point?". The header comment is a good place to explain what the point is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added documentation

///
//===----------------------------------------------------------------------===//

#ifndef LLVM_DWARFCFICHECKER_UNWINDINFOSTATE_H
#define LLVM_DWARFCFICHECKER_UNWINDINFOSTATE_H

#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include <optional>

namespace llvm {

using DWARFRegNum = uint32_t;

/// This class is used to maintain a CFI state, referred to as an unwinding row,
/// during CFI analysis. The only way to modify the state is by updating it with
/// a CFI directive.
class DWARFCFIState {
public:
DWARFCFIState(MCContext *Context) : Context(Context), IsInitiated(false) {};

std::optional<dwarf::UnwindRow> getCurrentUnwindRow() const;
/// This method updates the state by applying \p Directive to the current
/// state. If the directive is not supported by the checker or any error
/// happens while applying the CFI directive, a warning or error is reported
/// to the user, and the directive is ignored, leaving the state unchanged.
void update(const MCCFIInstruction &Directive);

private:
dwarf::CFIProgram convert(MCCFIInstruction Directive);

private:
dwarf::UnwindRow Row;
MCContext *Context;
bool IsInitiated;
};

} // namespace llvm

#endif
1 change: 1 addition & 0 deletions llvm/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ add_subdirectory(Option)
add_subdirectory(Remarks)
add_subdirectory(Debuginfod)
add_subdirectory(DebugInfo)
add_subdirectory(DWARFCFIChecker)
add_subdirectory(DWP)
add_subdirectory(ExecutionEngine)
add_subdirectory(Target)
Expand Down
14 changes: 14 additions & 0 deletions llvm/lib/DWARFCFIChecker/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_llvm_component_library(LLVMDWARFCFIChecker
DWARFCFIAnalysis.cpp
DWARFCFIFunctionFrameAnalyzer.cpp
DWARFCFIFunctionFrameStreamer.cpp
DWARFCFIState.cpp

ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/MCA

LINK_COMPONENTS
MC
DebugInfoDWARF
Support
)
Loading
Loading