diff options
| author | Luke Cheeseman <luke.cheeseman@arm.com> | 2018-12-21 10:45:08 +0000 |
|---|---|---|
| committer | Luke Cheeseman <luke.cheeseman@arm.com> | 2018-12-21 10:45:08 +0000 |
| commit | 41a9e53500c4317da7fa0d0b52322ea5df78a796 (patch) | |
| tree | d4c709f59ed2515613b75049277278bc6f3d9b99 /llvm/lib/MC | |
| parent | 82fbb664657da2f635dc03e1e656649dbdb6c3c0 (diff) | |
| download | bcm5719-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.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 29 | ||||
| -rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 7 |
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, |

