diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 21 |
5 files changed, 67 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index da4c458ad62..dfeca1bf2f3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -246,6 +246,12 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const { case MCCFIInstruction::OpSameValue: OutStreamer->EmitCFISameValue(Inst.getRegister()); break; + case MCCFIInstruction::OpGnuArgsSize: + OutStreamer->EmitCFIGnuArgsSize(Inst.getOffset()); + break; + case MCCFIInstruction::OpEscape: + OutStreamer->EmitCFIEscape(Inst.getValues()); + break; } } diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index f9dbd5ad3f0..a6c4e282a2d 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Path.h" #include <cctype> @@ -210,6 +211,8 @@ public: void EmitCFISameValue(int64_t Register) override; void EmitCFIRelOffset(int64_t Register, int64_t Offset) override; void EmitCFIAdjustCfaOffset(int64_t Adjustment) override; + void EmitCFIEscape(StringRef Values) override; + void EmitCFIGnuArgsSize(int64_t Size) override; void EmitCFISignalFrame() override; void EmitCFIUndefined(int64_t Register) override; void EmitCFIRegister(int64_t Register1, int64_t Register2) override; @@ -1010,6 +1013,32 @@ void MCAsmStreamer::EmitCFIDefCfaOffset(int64_t Offset) { EmitEOL(); } +static void PrintCFIEscape(llvm::formatted_raw_ostream &OS, StringRef Values) { + OS << "\t.cfi_escape "; + if (!Values.empty()) { + size_t e = Values.size() - 1; + for (size_t i = 0; i < e; ++i) + OS << format("0x%02x", uint8_t(Values[i])) << ", "; + OS << format("0x%02x", uint8_t(Values[e])); + } +} + +void MCAsmStreamer::EmitCFIEscape(StringRef Values) { + MCStreamer::EmitCFIEscape(Values); + PrintCFIEscape(OS, Values); + EmitEOL(); +} + +void MCAsmStreamer::EmitCFIGnuArgsSize(int64_t Size) { + MCStreamer::EmitCFIGnuArgsSize(Size); + + uint8_t Buffer[16] = { dwarf::DW_CFA_GNU_args_size }; + unsigned Len = encodeULEB128(Size, Buffer + 1) + 1; + + PrintCFIEscape(OS, StringRef((const char *)&Buffer[0], Len)); + EmitEOL(); +} + void MCAsmStreamer::EmitCFIDefCfaRegister(int64_t Register) { MCStreamer::EmitCFIDefCfaRegister(Register); OS << "\t.cfi_def_cfa_register "; diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 58cf652b68f..e964032b9d2 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -1147,6 +1147,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1); return; } + case MCCFIInstruction::OpGnuArgsSize: { + Streamer.EmitIntValue(dwarf::DW_CFA_GNU_args_size, 1); + Streamer.EmitULEB128IntValue(Instr.getOffset()); + return; + } case MCCFIInstruction::OpEscape: Streamer.EmitBytes(Instr.getValues()); return; diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 5d7685177b2..1ae1d51f2a3 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -359,6 +359,14 @@ void MCStreamer::EmitCFIEscape(StringRef Values) { CurFrame->Instructions.push_back(Instruction); } +void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) { + MCSymbol *Label = EmitCFICommon(); + MCCFIInstruction Instruction = + MCCFIInstruction::createGnuArgsSize(Label, Size); + MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); + CurFrame->Instructions.push_back(Instruction); +} + void MCStreamer::EmitCFISignalFrame() { EnsureValidDwarfFrame(); MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo(); diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 1895cd87b10..fc314d76c64 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -2073,8 +2073,6 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, // If the stack pointer can be changed after prologue, turn the // adjcallstackup instruction into a 'sub ESP, <amt>' and the // adjcallstackdown instruction into 'add ESP, <amt>' - if (Amount == 0) - return; // We need to keep the stack aligned properly. To do this, we round the // amount of space needed for the outgoing arguments up to the next @@ -2082,6 +2080,25 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, unsigned StackAlign = getStackAlignment(); Amount = RoundUpToAlignment(Amount, StackAlign); + // If we have any exception handlers in this function, and we adjust + // the SP before calls, we may need to indicate this to the unwinder, + // using GNU_ARGS_SIZE. Note that this may be necessary + // even when Amount == 0, because the preceding function may have + // set a non-0 GNU_ARGS_SIZE. + // TODO: We don't need to reset this between subsequent functions, + // if it didn't change. + bool HasDwarfEHHandlers = + !MF.getTarget().getMCAsmInfo()->usesWindowsCFI() && + !MF.getMMI().getLandingPads().empty(); + + if (HasDwarfEHHandlers && !isDestroy && + MF.getInfo<X86MachineFunctionInfo>()->getHasPushSequences()) + BuildCFI(MBB, I, DL,
+ MCCFIInstruction::createGnuArgsSize(nullptr, Amount));
+ + if (Amount == 0) + return; + // Factor out the amount that gets handled inside the sequence // (Pushes of argument for frame setup, callee pops for frame destroy) Amount -= InternalAmt; |