diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-27 15:56:22 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-27 15:56:22 +0000 |
commit | 1de2dd0e5edd2bc2c82d047cc0f3770488f09a11 (patch) | |
tree | f8a6b3cd0e4eb22ea7646342fafb10a4a91ded36 /llvm/lib/MC | |
parent | a895c69431e29e67d0adfb00ca9f696be456a746 (diff) | |
download | bcm5719-llvm-1de2dd0e5edd2bc2c82d047cc0f3770488f09a11.tar.gz bcm5719-llvm-1de2dd0e5edd2bc2c82d047cc0f3770488f09a11.zip |
Add support for .cfi_lsda.
llvm-svn: 122584
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 159 | ||||
-rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 2 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 5 |
4 files changed, 122 insertions, 52 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index ee1342937f5..f8c3a8acae7 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -190,7 +190,7 @@ public: virtual bool EmitCFIDefCfaRegister(int64_t Register); virtual bool EmitCFIOffset(int64_t Register, int64_t Offset); virtual bool EmitCFIPersonality(const MCSymbol *Sym, unsigned Encoding); - virtual bool EmitCFILsda(const MCSymbol *Sym); + virtual bool EmitCFILsda(const MCSymbol *Sym, unsigned Encoding); virtual void EmitInstruction(const MCInst &Inst); @@ -769,11 +769,11 @@ bool MCAsmStreamer::EmitCFIPersonality(const MCSymbol *Sym, return false; } -bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym) { - if (this->MCStreamer::EmitCFILsda(Sym)) +bool MCAsmStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { + if (this->MCStreamer::EmitCFILsda(Sym, Encoding)) return true; - OS << ".cfi_lsda 0, " << *Sym; + OS << ".cfi_lsda " << Encoding << ", " << *Sym; EmitEOL(); return false; diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 9d26bec824e..cd5141083e3 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/FoldingSet.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCAssembler.h" @@ -508,9 +509,53 @@ static void EmitFrameMoves(MCStreamer &streamer, } } +static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, + unsigned symbolEncoding) { + MCContext &context = streamer.getContext(); + const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); + unsigned format = symbolEncoding & 0x0f; + unsigned application = symbolEncoding & 0xf0; + unsigned size; + switch (format) { + default: + assert(0 && "Unknown Encoding"); + break; + case dwarf::DW_EH_PE_absptr: + case dwarf::DW_EH_PE_signed: + size = asmInfo.getPointerSize(); + break; + case dwarf::DW_EH_PE_udata2: + case dwarf::DW_EH_PE_sdata2: + size = 2; + break; + case dwarf::DW_EH_PE_udata4: + case dwarf::DW_EH_PE_sdata4: + size = 4; + break; + case dwarf::DW_EH_PE_udata8: + case dwarf::DW_EH_PE_sdata8: + size = 8; + break; + } + switch (application) { + default: + assert(0 && "Unknown Encoding"); + break; + case 0: + case dwarf::DW_EH_PE_indirect: + streamer.EmitSymbolValue(&symbol, size); + break; + case dwarf::DW_EH_PE_pcrel: + streamer.EmitPCRelSymbolValue(&symbol, size); + break; + } +} + static const MCSymbol &EmitCIE(MCStreamer &streamer, const MCSymbol *personality, - unsigned personalityEncoding) { + unsigned personalityEncoding, + const MCSymbol *lsda, + unsigned lsdaEncoding) { MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); const MCSection §ion = *asmInfo.getEHFrameSection(); @@ -535,6 +580,8 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer, Augmentation += "z"; if (personality) Augmentation += "P"; + if (lsda) + Augmentation += "L"; Augmentation += "R"; streamer.EmitBytes(Augmentation.str(), 0); streamer.EmitIntValue(0, 1); @@ -562,42 +609,11 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer, // Personality Encoding streamer.EmitIntValue(personalityEncoding, 1); // Personality - unsigned format = personalityEncoding & 0x0f; - unsigned application = personalityEncoding & 0xf0; - unsigned size; - switch (format) { - default: - assert(0 && "Unknown Encoding"); - break; - case dwarf::DW_EH_PE_absptr: - case dwarf::DW_EH_PE_signed: - size = asmInfo.getPointerSize(); - break; - case dwarf::DW_EH_PE_udata2: - case dwarf::DW_EH_PE_sdata2: - size = 2; - break; - case dwarf::DW_EH_PE_udata4: - case dwarf::DW_EH_PE_sdata4: - size = 4; - break; - case dwarf::DW_EH_PE_udata8: - case dwarf::DW_EH_PE_sdata8: - size = 8; - break; - } - switch (application) { - default: - assert(0 && "Unknown Encoding"); - break; - case 0: - case dwarf::DW_EH_PE_indirect: - streamer.EmitSymbolValue(personality, size); - break; - case dwarf::DW_EH_PE_pcrel: - streamer.EmitPCRelSymbolValue(personality, size); - break; - } + EmitSymbol(streamer, *personality, personalityEncoding); + } + if (lsda) { + // LSDA Encoding + streamer.EmitIntValue(lsdaEncoding, 1); } // Encoding of the FDE pointers streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1); @@ -619,8 +635,9 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer, static MCSymbol *EmitFDE(MCStreamer &streamer, const MCSymbol &cieStart, const MCDwarfFrameInfo &frame) { - MCSymbol *fdeStart = streamer.getContext().CreateTempSymbol(); - MCSymbol *fdeEnd = streamer.getContext().CreateTempSymbol(); + MCContext &context = streamer.getContext(); + MCSymbol *fdeStart = context.CreateTempSymbol(); + MCSymbol *fdeEnd = context.CreateTempSymbol(); // Length const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0); @@ -641,9 +658,18 @@ static MCSymbol *EmitFDE(MCStreamer &streamer, streamer.EmitValue(Range, 4); // Augmentation Data Length - streamer.EmitULEB128IntValue(0); + MCSymbol *augmentationStart = streamer.getContext().CreateTempSymbol(); + MCSymbol *augmentationEnd = streamer.getContext().CreateTempSymbol(); + const MCExpr *augmentationLength = MakeStartMinusEndExpr(streamer, + *augmentationStart, + *augmentationEnd, 0); + streamer.EmitULEB128Value(augmentationLength); // Augmentation Data + streamer.EmitLabel(augmentationStart); + if (frame.Lsda) + EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding); + streamer.EmitLabel(augmentationEnd); // Call Frame Instructions // Padding @@ -652,20 +678,63 @@ static MCSymbol *EmitFDE(MCStreamer &streamer, return fdeEnd; } +struct CIEKey { + static const CIEKey EmptyKey; + static const CIEKey TombstoneKey; + + CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_, + unsigned LsdaEncoding_) : Personality(Personality_), + PersonalityEncoding(PersonalityEncoding_), + LsdaEncoding(LsdaEncoding_) { + } + const MCSymbol* Personality; + unsigned PersonalityEncoding; + unsigned LsdaEncoding; +}; + +const CIEKey CIEKey::EmptyKey(0, 0, -1); +const CIEKey CIEKey::TombstoneKey(0, -1, 0); + +namespace llvm { + template <> + struct DenseMapInfo<CIEKey> { + static CIEKey getEmptyKey() { + return CIEKey::EmptyKey; + } + static CIEKey getTombstoneKey() { + return CIEKey::TombstoneKey; + } + static unsigned getHashValue(const CIEKey &Key) { + FoldingSetNodeID ID; + ID.AddPointer(Key.Personality); + ID.AddInteger(Key.PersonalityEncoding); + ID.AddInteger(Key.LsdaEncoding); + return ID.ComputeHash(); + } + static bool isEqual(const CIEKey &LHS, + const CIEKey &RHS) { + return LHS.Personality == RHS.Personality && + LHS.PersonalityEncoding == RHS.PersonalityEncoding && + LHS.LsdaEncoding == RHS.LsdaEncoding; + } + }; +} + void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) { const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); MCSymbol *fdeEnd = NULL; - typedef std::pair<const MCSymbol*, unsigned> personalityKey; - DenseMap<personalityKey, const MCSymbol*> personalities; + DenseMap<CIEKey, const MCSymbol*> CIEStarts; for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); - personalityKey key(frame.Personality, frame.PersonalityEncoding); - const MCSymbol *&cieStart = personalities[key]; + CIEKey key(frame.Personality, frame.PersonalityEncoding, + frame.LsdaEncoding); + const MCSymbol *&cieStart = CIEStarts[key]; if (!cieStart) cieStart = &EmitCIE(streamer, frame.Personality, - frame.PersonalityEncoding); + frame.PersonalityEncoding, frame.Lsda, + frame.LsdaEncoding); fdeEnd = EmitFDE(streamer, *cieStart, frame); if (i != n - 1) streamer.EmitLabel(fdeEnd); diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 450a927a2ad..27b2dced554 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -2257,7 +2257,7 @@ bool GenericAsmParser::ParseDirectiveCFIPersonalityOrLsda(StringRef IDVal, return getStreamer().EmitCFIPersonality(Sym, Encoding); else { assert(IDVal == ".cfi_lsda"); - return getStreamer().EmitCFILsda(Sym); + return getStreamer().EmitCFILsda(Sym, Encoding); } } diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 399b4baded1..922a40ce3e7 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -157,7 +157,7 @@ bool MCStreamer::EmitCFIStartProc() { report_fatal_error("Starting a frame before finishing the previous one!"); return true; } - MCDwarfFrameInfo Frame = {0, 0, 0, 0}; + MCDwarfFrameInfo Frame = {0, 0, 0, 0, 0, 0}; Frame.Begin = getContext().CreateTempSymbol(); EmitLabel(Frame.Begin); FrameInfos.push_back(Frame); @@ -196,10 +196,11 @@ bool MCStreamer::EmitCFIPersonality(const MCSymbol *Sym, return false; } -bool MCStreamer::EmitCFILsda(const MCSymbol *Sym) { +bool MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) { EnsureValidFrame(); MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo(); CurFrame->Lsda = Sym; + CurFrame->LsdaEncoding = Encoding; return false; } |