diff --git a/include/llvm/MC/MCDwarf.h b/include/llvm/MC/MCDwarf.h index 220d63087b8..ea2af78eb4e 100644 --- a/include/llvm/MC/MCDwarf.h +++ b/include/llvm/MC/MCDwarf.h @@ -282,6 +282,7 @@ namespace llvm { // This emits the frame info section. // static void Emit(MCStreamer &streamer); + static void EmitDarwin(MCStreamer &streamer); static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta); static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS, const TargetAsmInfo &AsmInfo); diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 7111758a727..18484300486 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -824,9 +824,67 @@ namespace llvm { }; } +// This is an implementation of CIE and FDE emission that is bug by bug +// compatible with the one in CodeGen. It is useful during the transition +// to make it easy to compare the outputs, but should probably be removed +// afterwards. +void MCDwarfFrameEmitter::EmitDarwin(MCStreamer &streamer) { + FrameEmitterImpl Emitter; + DenseMap Personalities; + const MCSymbol *aCIE = NULL; + const MCDwarfFrameInfo *aFrame = NULL; + + for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); + if (!frame.Personality) + continue; + if (Personalities.count(frame.Personality)) + continue; + + const MCSymbol *cieStart = &Emitter.EmitCIE(streamer, frame.Personality, + frame.PersonalityEncoding, + frame.Lsda, + frame.LsdaEncoding); + aCIE = cieStart; + aFrame = &frame; + Personalities[frame.Personality] = cieStart; + } + + if (Personalities.empty()) { + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(0); + aCIE = &Emitter.EmitCIE(streamer, frame.Personality, + frame.PersonalityEncoding, frame.Lsda, + frame.LsdaEncoding); + aFrame = &frame; + } + + MCSymbol *fdeEnd = NULL; + for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) { + const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i); + const MCSymbol *cieStart = Personalities[frame.Personality]; + if (!cieStart) + cieStart = aCIE; + + fdeEnd = Emitter.EmitFDE(streamer, *cieStart, frame); + if (i != n - 1) + streamer.EmitLabel(fdeEnd); + } + + const MCContext &context = streamer.getContext(); + const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); + streamer.EmitValueToAlignment(asmInfo.getPointerSize()); + if (fdeEnd) + streamer.EmitLabel(fdeEnd); +} + void MCDwarfFrameEmitter::Emit(MCStreamer &streamer) { const MCContext &context = streamer.getContext(); const TargetAsmInfo &asmInfo = context.getTargetAsmInfo(); + if (!asmInfo.isFunctionEHFrameSymbolPrivate()) { + EmitDarwin(streamer); + return; + } + MCSymbol *fdeEnd = NULL; DenseMap CIEStarts; FrameEmitterImpl Emitter;