summaryrefslogtreecommitdiffstats
path: root/llvm/lib/MC
diff options
context:
space:
mode:
authorLuke Cheeseman <luke.cheeseman@arm.com>2018-12-21 10:45:08 +0000
committerLuke Cheeseman <luke.cheeseman@arm.com>2018-12-21 10:45:08 +0000
commit41a9e53500c4317da7fa0d0b52322ea5df78a796 (patch)
treed4c709f59ed2515613b75049277278bc6f3d9b99 /llvm/lib/MC
parent82fbb664657da2f635dc03e1e656649dbdb6c3c0 (diff)
downloadbcm5719-llvm-41a9e53500c4317da7fa0d0b52322ea5df78a796.tar.gz
bcm5719-llvm-41a9e53500c4317da7fa0d0b52322ea5df78a796.zip
[Dwarf/AArch64] Return address signing B key dwarf support
- When signing return addresses with -msign-return-address=<scope>{+<key>}, either the A key instructions or the B key instructions can be used. To correctly authenticate the return address, the unwinder/debugger must know which key was used to sign the return address. - When and exception is thrown or a break point reached, it may be necessary to unwind the stack. To accomplish this, the unwinder/debugger must be able to first authenticate an the return address if it has been signed. - To enable this, the augmentation string of CIEs has been extended to allow inclusion of a 'B' character. Functions that are signed using the B key variant of the instructions should have and FDE whose associated CIE has a 'B' in the augmentation string. - One must also be able to preserve these semantics when first stepping from a high level language into assembly and then, as a second step, into an object file. To achieve this, I have introduced a new assembly directive '.cfi_b_key_frame ', that tells the assembler the current frame uses return address signing with the B key. - This ensures that the FDE is associated with a CIE that has 'B' in the augmentation string. Differential Revision: https://reviews.llvm.org/D51798 llvm-svn: 349895
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp7
-rw-r--r--llvm/lib/MC/MCDwarf.cpp29
-rw-r--r--llvm/lib/MC/MCParser/AsmParser.cpp2
-rw-r--r--llvm/lib/MC/MCStreamer.cpp7
4 files changed, 33 insertions, 12 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 4f0efab73e8..e017103070b 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -266,6 +266,7 @@ public:
void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
void EmitIdent(StringRef IdentString) override;
+ void EmitCFIBKeyFrame() override;
void EmitCFISections(bool EH, bool Debug) override;
void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
void EmitCFIDefCfaOffset(int64_t Offset) override;
@@ -1602,6 +1603,12 @@ void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
EmitEOL();
}
+void MCAsmStreamer::EmitCFIBKeyFrame() {
+ MCStreamer::EmitCFIBKeyFrame();
+ OS << "\t.cfi_b_key_frame";
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
MCStreamer::EmitWinCFIStartProc(Symbol, Loc);
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp
index 9791fb5724b..38b02694d81 100644
--- a/llvm/lib/MC/MCDwarf.cpp
+++ b/llvm/lib/MC/MCDwarf.cpp
@@ -1565,9 +1565,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
Streamer.EmitIntValue(CIEVersion, 1);
- // Augmentation String
- SmallString<8> Augmentation;
if (IsEH) {
+ SmallString<8> Augmentation;
Augmentation += "z";
if (Frame.Personality)
Augmentation += "P";
@@ -1576,6 +1575,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) {
Augmentation += "R";
if (Frame.IsSignalFrame)
Augmentation += "S";
+ if (Frame.IsBKeyFrame)
+ Augmentation += "B";
Streamer.EmitBytes(Augmentation);
}
Streamer.EmitIntValue(0, 1);
@@ -1730,25 +1731,28 @@ namespace {
struct CIEKey {
static const CIEKey getEmptyKey() {
- return CIEKey(nullptr, 0, -1, false, false, static_cast<unsigned>(INT_MAX));
+ return CIEKey(nullptr, 0, -1, false, false, static_cast<unsigned>(INT_MAX),
+ false);
}
static const CIEKey getTombstoneKey() {
- return CIEKey(nullptr, -1, 0, false, false, static_cast<unsigned>(INT_MAX));
+ return CIEKey(nullptr, -1, 0, false, false, static_cast<unsigned>(INT_MAX),
+ false);
}
CIEKey(const MCSymbol *Personality, unsigned PersonalityEncoding,
unsigned LSDAEncoding, bool IsSignalFrame, bool IsSimple,
- unsigned RAReg)
+ unsigned RAReg, bool IsBKeyFrame)
: Personality(Personality), PersonalityEncoding(PersonalityEncoding),
LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame),
- IsSimple(IsSimple), RAReg(RAReg) {}
+ IsSimple(IsSimple), RAReg(RAReg), IsBKeyFrame(IsBKeyFrame) {}
explicit CIEKey(const MCDwarfFrameInfo &Frame)
: Personality(Frame.Personality),
PersonalityEncoding(Frame.PersonalityEncoding),
LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
- IsSimple(Frame.IsSimple), RAReg(Frame.RAReg) {}
+ IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
+ IsBKeyFrame(Frame.IsBKeyFrame) {}
const MCSymbol *Personality;
unsigned PersonalityEncoding;
@@ -1756,6 +1760,7 @@ struct CIEKey {
bool IsSignalFrame;
bool IsSimple;
unsigned RAReg;
+ bool IsBKeyFrame;
};
} // end anonymous namespace
@@ -1767,9 +1772,9 @@ template <> struct DenseMapInfo<CIEKey> {
static CIEKey getTombstoneKey() { return CIEKey::getTombstoneKey(); }
static unsigned getHashValue(const CIEKey &Key) {
- return static_cast<unsigned>(
- hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
- Key.IsSignalFrame, Key.IsSimple, Key.RAReg));
+ return static_cast<unsigned>(hash_combine(
+ Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
+ Key.IsSignalFrame, Key.IsSimple, Key.RAReg, Key.IsBKeyFrame));
}
static bool isEqual(const CIEKey &LHS, const CIEKey &RHS) {
@@ -1777,8 +1782,8 @@ template <> struct DenseMapInfo<CIEKey> {
LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
LHS.LsdaEncoding == RHS.LsdaEncoding &&
LHS.IsSignalFrame == RHS.IsSignalFrame &&
- LHS.IsSimple == RHS.IsSimple &&
- LHS.RAReg == RHS.RAReg;
+ LHS.IsSimple == RHS.IsSimple && LHS.RAReg == RHS.RAReg &&
+ LHS.IsBKeyFrame == RHS.IsBKeyFrame;
}
};
diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp
index aa07eee4491..5c76c900c74 100644
--- a/llvm/lib/MC/MCParser/AsmParser.cpp
+++ b/llvm/lib/MC/MCParser/AsmParser.cpp
@@ -495,6 +495,7 @@ private:
DK_CFI_UNDEFINED,
DK_CFI_REGISTER,
DK_CFI_WINDOW_SAVE,
+ DK_CFI_B_KEY_FRAME,
DK_MACROS_ON,
DK_MACROS_OFF,
DK_ALTMACRO,
@@ -5293,6 +5294,7 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
+ DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp
index 85e69f6f663..18fbea4afa0 100644
--- a/llvm/lib/MC/MCStreamer.cpp
+++ b/llvm/lib/MC/MCStreamer.cpp
@@ -221,6 +221,13 @@ void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
Source);
}
+void MCStreamer::EmitCFIBKeyFrame() {
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+ if (!CurFrame)
+ return;
+ CurFrame->IsBKeyFrame = true;
+}
+
void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa,
OpenPOWER on IntegriCloud