diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/MC/MCELFStreamer.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 27 |
3 files changed, 50 insertions, 10 deletions
diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 24ddc825638..a4d34f386aa 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -475,8 +475,8 @@ static void EmitFrameMoves(MCStreamer &streamer, streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1); } else { streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); - streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), isEH), - 1); + streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(), + isEH)); } streamer.EmitULEB128IntValue(-Src.getOffset(), 1); @@ -508,7 +508,8 @@ static void EmitFrameMoves(MCStreamer &streamer, } } -static const MCSymbol &EmitCIE(MCStreamer &streamer) { +static const MCSymbol &EmitCIE(MCStreamer &streamer, + const MCSymbol *personality) { MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); const MCSection §ion = *asmInfo.getEHFrameSection(); @@ -530,7 +531,10 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer) { // Augmentation String SmallString<8> Augmentation; - Augmentation += "zR"; + Augmentation += "z"; + if (personality) + Augmentation += "P"; + Augmentation += "R"; streamer.EmitBytes(Augmentation.str(), 0); streamer.EmitIntValue(0, 1); @@ -553,6 +557,13 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer) { // Augmentation Data (optional) streamer.EmitLabel(augmentationStart); + if (personality) { + // Personality Encoding + streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1); + // Personality + streamer.EmitSymbolValue(personality, 8); + } + // Encoding of the FDE pointers streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1); streamer.EmitLabel(augmentationEnd); @@ -563,7 +574,7 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer) { EmitFrameMoves(streamer, Moves, NULL, true); // Padding - streamer.EmitValueToAlignment(asmInfo.getPointerSize()); + streamer.EmitValueToAlignment(4); streamer.EmitLabel(sectionEnd); return *sectionStart; @@ -608,13 +619,19 @@ static MCSymbol *EmitFDE(MCStreamer &streamer, void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) { const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); - const MCSymbol &cieStart = EmitCIE(streamer); MCSymbol *fdeEnd = NULL; + DenseMap<const MCSymbol*, const MCSymbol*> Personalities; + for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { - fdeEnd = EmitFDE(streamer, cieStart, streamer.getFrameInfo(i)); + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); + const MCSymbol *&cieStart = Personalities[frame.Personality]; + if (!cieStart) + cieStart = &EmitCIE(streamer, frame.Personality); + fdeEnd = EmitFDE(streamer, *cieStart, frame); if (i != n - 1) streamer.EmitLabel(fdeEnd); } + streamer.EmitValueToAlignment(asmInfo.getPointerSize()); if (fdeEnd) streamer.EmitLabel(fdeEnd); diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 4636e2a1f0e..23698212044 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -488,7 +488,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) { } void MCELFStreamer::Finish() { - if (!FrameInfos.empty()) + if (getNumFrameInfos()) MCDwarfFrameEmitter::Emit(*this); for (std::vector<LocalCommon>::const_iterator i = LocalCommons.begin(), diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index aac55351555..cf11ca9c5a8 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -2206,6 +2206,29 @@ bool GenericAsmParser::ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc) { return getStreamer().EmitCFIOffset(Register, Offset); } +static bool isValidEncoding(int64_t Encoding) { + if (Encoding & ~0xff) + return false; + + if (Encoding == dwarf::DW_EH_PE_omit) + return true; + + const unsigned Format = Encoding & 0xf; + if (Format != dwarf::DW_EH_PE_absptr && Format != dwarf::DW_EH_PE_udata2 && + Format != dwarf::DW_EH_PE_udata4 && Format != dwarf::DW_EH_PE_udata8 && + Format != dwarf::DW_EH_PE_sdata2 && Format != dwarf::DW_EH_PE_sdata4 && + Format != dwarf::DW_EH_PE_sdata8 && Format != dwarf::DW_EH_PE_signed) + return false; + + const unsigned Application = Encoding & 0xf0; + if (Application != dwarf::DW_EH_PE_absptr && + Application != dwarf::DW_EH_PE_pcrel && + Application != dwarf::DW_EH_PE_indirect) + return false; + + return true; +} + /// ParseDirectiveCFIPersonalityOrLsda /// ::= .cfi_personality encoding, [symbol_name] /// ::= .cfi_lsda encoding, [symbol_name] @@ -2214,10 +2237,10 @@ bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal, int64_t Encoding = 0; if (getParser().ParseAbsoluteExpression(Encoding)) return true; - if (Encoding == 255) + if (Encoding == dwarf::DW_EH_PE_omit) return false; - if (Encoding != 0) + if (!isValidEncoding(Encoding)) return TokError("unsupported encoding."); if (getLexer().isNot(AsmToken::Comma)) |