aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCDwarf.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-12-27 00:36:05 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-12-27 00:36:05 +0000
commit3a83c40ab61d5ca624f2bbadd70237c6adbdb304 (patch)
treef0e3c71d1852277f7ed6d945f96c8493bc395101 /lib/MC/MCDwarf.cpp
parentdef548f9a0efa6e997a68ac2d77cb0ef574b7d43 (diff)
Add support for the same encodings of the personality function that gnu as
supports. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@122577 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCDwarf.cpp')
-rw-r--r--lib/MC/MCDwarf.cpp51
1 files changed, 45 insertions, 6 deletions
diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp
index 75c844f09e..9d26bec824 100644
--- a/lib/MC/MCDwarf.cpp
+++ b/lib/MC/MCDwarf.cpp
@@ -509,7 +509,8 @@ static void EmitFrameMoves(MCStreamer &streamer,
}
static const MCSymbol &EmitCIE(MCStreamer &streamer,
- const MCSymbol *personality) {
+ const MCSymbol *personality,
+ unsigned personalityEncoding) {
MCContext &context = streamer.getContext();
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
const MCSection &section = *asmInfo.getEHFrameSection();
@@ -559,9 +560,44 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer,
streamer.EmitLabel(augmentationStart);
if (personality) {
// Personality Encoding
- streamer.EmitIntValue(dwarf::DW_EH_PE_absptr, 1);
+ streamer.EmitIntValue(personalityEncoding, 1);
// Personality
- streamer.EmitSymbolValue(personality, asmInfo.getPointerSize());
+ 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;
+ }
}
// Encoding of the FDE pointers
streamer.EmitIntValue(dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4, 1);
@@ -620,13 +656,16 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) {
const MCContext &context = streamer.getContext();
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
MCSymbol *fdeEnd = NULL;
- DenseMap<const MCSymbol*, const MCSymbol*> Personalities;
+ typedef std::pair<const MCSymbol*, unsigned> personalityKey;
+ DenseMap<personalityKey, const MCSymbol*> personalities;
for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
- const MCSymbol *&cieStart = Personalities[frame.Personality];
+ personalityKey key(frame.Personality, frame.PersonalityEncoding);
+ const MCSymbol *&cieStart = personalities[key];
if (!cieStart)
- cieStart = &EmitCIE(streamer, frame.Personality);
+ cieStart = &EmitCIE(streamer, frame.Personality,
+ frame.PersonalityEncoding);
fdeEnd = EmitFDE(streamer, *cieStart, frame);
if (i != n - 1)
streamer.EmitLabel(fdeEnd);