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,10 +1576,13 @@ Augmentation += "R"; if (Frame.IsSignalFrame) Augmentation += "S"; + if (!Frame.ExtraAugmentation.empty()) + Augmentation += Frame.ExtraAugmentation; Streamer.EmitBytes(Augmentation); } Streamer.EmitIntValue(0, 1); + if (CIEVersion >= 4) { // Address Size Streamer.EmitIntValue(context.getAsmInfo()->getCodePointerSize(), 1); @@ -1731,25 +1733,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(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 +1761,7 @@ bool IsSignalFrame; bool IsSimple; unsigned RAReg; + std::string ExtraAugmentation; }; } // end anonymous namespace @@ -1770,7 +1775,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 +1785,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 @@ -1,7 +1,5 @@ # RUN: llc -mtriple=aarch64-arm-none-eabi -run-pass=prologepilog -o - %s 2>&1 | FileCheck %s --- | - ; ModuleID = '/work/scratch/test.ll' - source_filename = "/work/scratch/test.c" target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64-arm-none-eabi" @@ -11,13 +9,18 @@ ret i32 2 } + ; Function Attrs: noinline nounwind optnone + define dso_local i32 @bar() #1 { + entry: + ret i32 2 + } + attributes #0 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "sign-return-address"="all" "sign-return-address-key"="a_key" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+v8.3a" "unsafe-fp-math"="false" "use-soft-float"="false" } + attributes #1 = { noinline nounwind optnone "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "sign-return-address"="all" "sign-return-address-key"="b_key" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+neon,+v8.3a" "unsafe-fp-math"="false" "use-soft-float"="false" } !llvm.module.flags = !{!0} - !llvm.ident = !{!1} !0 = !{i32 1, !"wchar_size", i32 4} - !1 = !{!"clang version 8.0.0 (https://git.llvm.org/git/clang.git/ f9833ff4fea02c1a3d9ce1d8432be3af9ffc7de4) (https://git.llvm.org/git/llvm.git/ 176f75d48ef7f2d9b3234b5e067e9410cd6cb800)"} ... --- @@ -55,9 +58,54 @@ constants: #CHECK: frame-setup PACIASP implicit-def $lr, implicit $lr, implicit $sp #CHECK: frame-setup CFI_INSTRUCTION negate_ra_sign_state +#CHECK: RETAA +body: | + bb.0.entry: + $w0 = MOVi32imm 2 + RET_ReallyLR implicit killed $w0 + +... +--- +#CHECK: bar +name: bar +alignment: 2 +exposesReturnsTwice: false +legalized: false +regBankSelected: false +selected: false +failedISel: false +tracksRegLiveness: true +registers: +liveins: +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + stackProtector: '' + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false + localFrameSize: 0 + savePoint: '' + restorePoint: '' +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 body: | bb.0.entry: $w0 = MOVi32imm 2 RET_ReallyLR implicit killed $w0 ... + 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