Index: include/llvm/MC/MCDwarf.h =================================================================== --- include/llvm/MC/MCDwarf.h +++ include/llvm/MC/MCDwarf.h @@ -599,6 +599,7 @@ bool IsSignalFrame = false; bool IsSimple = false; unsigned RAReg = static_cast(INT_MAX); + std::string ExtraAugmentation; }; class MCDwarfFrameEmitter { Index: include/llvm/MC/MCStreamer.h =================================================================== --- include/llvm/MC/MCStreamer.h +++ include/llvm/MC/MCStreamer.h @@ -797,6 +797,8 @@ Optional Source, unsigned CUID = 0); + virtual void EmitAppendAugmentation(StringRef String); + /// This implements the DWARF2 '.loc fileno lineno ...' assembler /// directive. virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line, Index: lib/DebugInfo/DWARF/DWARFDebugFrame.cpp =================================================================== --- lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -445,6 +445,8 @@ StartAugmentationOffset = Offset; EndAugmentationOffset = Offset + static_cast(*AugmentationLength); + case 'B': + break; } } Index: lib/MC/MCAsmStreamer.cpp =================================================================== --- lib/MC/MCAsmStreamer.cpp +++ lib/MC/MCAsmStreamer.cpp @@ -266,6 +266,7 @@ void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override; void EmitIdent(StringRef IdentString) override; + void EmitAppendAugmentation(StringRef String) override; void EmitCFISections(bool EH, bool Debug) override; void EmitCFIDefCfa(int64_t Register, int64_t Offset) override; void EmitCFIDefCfaOffset(int64_t Offset) override; @@ -1389,6 +1390,12 @@ EmitEOL(); } +void MCAsmStreamer::EmitAppendAugmentation(StringRef String) +{ + OS << "\t.append_augmentation \"" << String << "\""; + EmitEOL(); +} + void MCAsmStreamer::EmitCFISections(bool EH, bool Debug) { MCStreamer::EmitCFISections(EH, Debug); OS << "\t.cfi_sections "; Index: lib/MC/MCDwarf.cpp =================================================================== --- lib/MC/MCDwarf.cpp +++ lib/MC/MCDwarf.cpp @@ -1566,9 +1566,8 @@ 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"; @@ -1577,6 +1576,8 @@ Augmentation += "R"; if (Frame.IsSignalFrame) Augmentation += "S"; + if (!Frame.ExtraAugmentation.empty()) + Augmentation += Frame.ExtraAugmentation; Streamer.EmitBytes(Augmentation); } Streamer.EmitIntValue(0, 1); @@ -1731,25 +1732,27 @@ struct CIEKey { static const CIEKey getEmptyKey() { - return CIEKey(nullptr, 0, -1, false, false, static_cast(INT_MAX)); + return CIEKey(nullptr, 0, -1, false, false, static_cast(INT_MAX), ""); } static const CIEKey getTombstoneKey() { - return CIEKey(nullptr, -1, 0, false, false, static_cast(INT_MAX)); + return CIEKey(nullptr, -1, 0, false, false, static_cast(INT_MAX), ""); } CIEKey(const MCSymbol *Personality, unsigned PersonalityEncoding, unsigned LSDAEncoding, bool IsSignalFrame, bool IsSimple, - unsigned RAReg) + unsigned RAReg, std::string ExtraAugmentation) : Personality(Personality), PersonalityEncoding(PersonalityEncoding), LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame), - IsSimple(IsSimple), RAReg(RAReg) {} + IsSimple(IsSimple), RAReg(RAReg), + ExtraAugmentation(std::move(ExtraAugmentation)) {} 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), + ExtraAugmentation(Frame.ExtraAugmentation) {} const MCSymbol *Personality; unsigned PersonalityEncoding; @@ -1757,6 +1760,7 @@ bool IsSignalFrame; bool IsSimple; unsigned RAReg; + std::string ExtraAugmentation; }; } // end anonymous namespace @@ -1770,7 +1774,8 @@ static unsigned getHashValue(const CIEKey &Key) { return static_cast( hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding, - Key.IsSignalFrame, Key.IsSimple, Key.RAReg)); + Key.IsSignalFrame, Key.IsSimple, Key.RAReg, + Key.ExtraAugmentation)); } static bool isEqual(const CIEKey &LHS, const CIEKey &RHS) { @@ -1779,7 +1784,8 @@ LHS.LsdaEncoding == RHS.LsdaEncoding && LHS.IsSignalFrame == RHS.IsSignalFrame && LHS.IsSimple == RHS.IsSimple && - LHS.RAReg == RHS.RAReg; + LHS.RAReg == RHS.RAReg && + LHS.ExtraAugmentation == RHS.ExtraAugmentation; } }; Index: lib/MC/MCParser/AsmParser.cpp =================================================================== --- lib/MC/MCParser/AsmParser.cpp +++ lib/MC/MCParser/AsmParser.cpp @@ -508,6 +508,7 @@ DK_PRINT, DK_ADDRSIG, DK_ADDRSIG_SYM, + DK_APPEND_AUGMENTATION, DK_END }; @@ -573,6 +574,8 @@ bool parseDirectiveCFISignalFrame(); bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc); + bool parseDirectiveAppendAugmentation(); + // macro directives bool parseDirectivePurgeMacro(SMLoc DirectiveLoc); bool parseDirectiveExitMacro(StringRef Directive); @@ -2079,6 +2082,8 @@ return parseDirectiveCFIRegister(IDLoc); case DK_CFI_WINDOW_SAVE: return parseDirectiveCFIWindowSave(); + case DK_APPEND_AUGMENTATION: + return parseDirectiveAppendAugmentation(); case DK_MACROS_ON: case DK_MACROS_OFF: return parseDirectiveMacrosOnOff(IDVal); @@ -4157,6 +4162,17 @@ return false; } + +/// parseDirectiveAppendAugmentation +/// ::= .append_augmentation +bool AsmParser::parseDirectiveAppendAugmentation() { + std::string Data; + if (checkForValidSection() || parseEscapedString(Data)) + return true; + getStreamer().EmitAppendAugmentation(Data);; + return false; +} + /// parseDirectiveAltmacro /// ::= .altmacro /// ::= .noaltmacro @@ -5304,6 +5320,7 @@ DirectiveKindMap[".print"] = DK_PRINT; DirectiveKindMap[".addrsig"] = DK_ADDRSIG; DirectiveKindMap[".addrsig_sym"] = DK_ADDRSIG_SYM; + DirectiveKindMap[".append_augmentation"] = DK_APPEND_AUGMENTATION; } MCAsmMacro *AsmParser::parseMacroLikeBody(SMLoc DirectiveLoc) { Index: lib/MC/MCStreamer.cpp =================================================================== --- lib/MC/MCStreamer.cpp +++ lib/MC/MCStreamer.cpp @@ -209,6 +209,10 @@ Source); } +void MCStreamer::EmitAppendAugmentation(StringRef String) { + getCurrentDwarfFrameInfo()->ExtraAugmentation += String.str(); +} + void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line, unsigned Column, unsigned Flags, unsigned Isa, Index: lib/Target/AArch64/AArch64AsmPrinter.cpp =================================================================== --- lib/Target/AArch64/AArch64AsmPrinter.cpp +++ lib/Target/AArch64/AArch64AsmPrinter.cpp @@ -683,6 +683,10 @@ case TargetOpcode::PATCHABLE_TAIL_CALL: LowerPATCHABLE_TAIL_CALL(*MI); return; + + case AArch64::EMITBKEY: + OutStreamer->EmitAppendAugmentation("B"); + return; } // Finally, do the automated lowerings for everything else. Index: lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- lib/Target/AArch64/AArch64FrameLowering.cpp +++ lib/Target/AArch64/AArch64FrameLowering.cpp @@ -606,10 +606,16 @@ DebugLoc DL; if (ShouldSignReturnAddress(MF)) { - BuildMI( - MBB, MBBI, DL, - TII->get(ShouldSignWithAKey(MF) ? AArch64::PACIASP : AArch64::PACIBSP)) - .setMIFlag(MachineInstr::FrameSetup); + if (ShouldSignWithAKey(MF)) + BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIASP)) + .setMIFlag(MachineInstr::FrameSetup); + else + { + BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY)) + .setMIFlag(MachineInstr::FrameSetup); + BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIBSP)) + .setMIFlag(MachineInstr::FrameSetup); + } unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); Index: lib/Target/AArch64/AArch64InstrInfo.td =================================================================== --- lib/Target/AArch64/AArch64InstrInfo.td +++ lib/Target/AArch64/AArch64InstrInfo.td @@ -1442,6 +1442,10 @@ let AsmString = ".tlsdesccall $sym"; } +// Pseudo instruction to tell the streamer to emit a 'B' character into the +// augmentation string. +def EMITBKEY : Pseudo<(outs), (ins), []>, Sched<[]> {} + // FIXME: maybe the scratch register used shouldn't be fixed to X1? // FIXME: can "hasSideEffects be dropped? let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1, Index: test/CodeGen/MIR/AArch64/return-address-signing.mir =================================================================== --- test/CodeGen/MIR/AArch64/return-address-signing.mir +++ test/CodeGen/MIR/AArch64/return-address-signing.mir @@ -98,6 +98,7 @@ fixedStack: stack: constants: +#CHECK: frame-setup EMITBKEY #CHECK: frame-setup PACIBSP implicit-def $lr, implicit $lr, implicit $sp #CHECK: frame-setup CFI_INSTRUCTION negate_ra_sign_state #CHECK: RETAB Index: test/DebugInfo/AArch64/return-address-signing.ll =================================================================== --- /dev/null +++ test/DebugInfo/AArch64/return-address-signing.ll @@ -0,0 +1,15 @@ +; RUN: llc -mtriple=aarch64-arm-none-eabi < %s -filetype=obj -o - \ +; RUN: | llvm-dwarfdump -v - | FileCheck -check-prefix=CHECK %s + +;CHECK: CIE +;CHECK: Augmentation: "zR" +define i32 @foo() "sign-return-address"="all" { + ret i32 0 +} + +;CHECK: CIE +;CHECK: Augmentation: "zRB" + +define i32 @bar() "sign-return-address"="all" "sign-return-address-key"="b_key" { + ret i32 0 +} Index: test/MC/ELF/appendaugmentation.s =================================================================== --- /dev/null +++ test/MC/ELF/appendaugmentation.s @@ -0,0 +1,6 @@ +// RUN: llvm-mc -filetype=obj -triple aarch64-arm-none-eabi %s -o - | llvm-dwarfdump - -v | FileCheck %s +#CHECK: Augmentation: "zRB" +f1: + .cfi_startproc + .append_augmentation "B" + .cfi_endproc