X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCDwarf.cpp;h=a89201730a54c73083cdb5b7bb0f51fbacde7c39;hb=7ab184a2a1cbf5b5b340d663e07550659438ed7c;hp=74851ce140a9c277816d5a692f21804b80c17d3f;hpb=75c9b9384f50e9387f24dd7ce6af403cbda6d19a;p=oota-llvm.git diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 74851ce140a..a89201730a5 100644 --- a/lib/MC/MCDwarf.cpp +++ b/lib/MC/MCDwarf.cpp @@ -16,7 +16,6 @@ #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCObjectFileInfo.h" -#include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" @@ -47,20 +46,15 @@ using namespace llvm; // Range of line offsets in a special line info. opcode. #define DWARF2_LINE_RANGE 14 -// Define the architecture-dependent minimum instruction length (in bytes). -// This value should be rather too small than too big. -#define DWARF2_LINE_MIN_INSN_LENGTH 1 - -// Note: when DWARF2_LINE_MIN_INSN_LENGTH == 1 which is the current setting, -// this routine is a nop and will be optimized away. -static inline uint64_t ScaleAddrDelta(uint64_t AddrDelta) { - if (DWARF2_LINE_MIN_INSN_LENGTH == 1) +static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) { + unsigned MinInsnLength = Context.getAsmInfo()->getMinInstAlignment(); + if (MinInsnLength == 1) return AddrDelta; - if (AddrDelta % DWARF2_LINE_MIN_INSN_LENGTH != 0) { + if (AddrDelta % MinInsnLength != 0) { // TODO: report this error, but really only once. ; } - return AddrDelta / DWARF2_LINE_MIN_INSN_LENGTH; + return AddrDelta / MinInsnLength; } // @@ -101,7 +95,8 @@ void MCLineEntry::Make(MCStreamer *MCOS, const MCSection *Section) { } // Add the line entry to this section's entries. - LineSection->addLineEntry(LineEntry); + LineSection->addLineEntry(LineEntry, + MCOS->getContext().getDwarfCompileUnitID()); } // @@ -131,7 +126,12 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS, // static inline void EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section, - const MCLineSection *LineSection) { + const MCLineSection *LineSection, + unsigned CUID) { + // This LineSection does not contain any LineEntry for the given Compile Unit. + if (!LineSection->containEntriesForID(CUID)) + return; + unsigned FileNum = 1; unsigned LastLine = 1; unsigned Column = 0; @@ -141,8 +141,8 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, // Loop through each MCLineEntry and encode the dwarf line number table. for (MCLineSection::const_iterator - it = LineSection->getMCLineEntries()->begin(), - ie = LineSection->getMCLineEntries()->end(); it != ie; ++it) { + it = LineSection->getMCLineEntries(CUID).begin(), + ie = LineSection->getMCLineEntries(CUID).end(); it != ie; ++it) { if (FileNum != it->getFileNum()) { FileNum = it->getFileNum(); @@ -176,9 +176,9 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, // At this point we want to emit/create the sequence to encode the delta in // line numbers and the increment of the address from the previous Label // and the current Label. - const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo(); + const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); MCOS->EmitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label, - asmInfo.getPointerSize()); + asmInfo->getPointerSize()); LastLine = it->getLine(); LastLabel = Label; @@ -191,6 +191,8 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, // actually a DW_LNE_end_sequence. // Switch to the section to be able to create a symbol at its end. + // TODO: keep track of the last subsection so that this symbol appears in the + // correct place. MCOS->SwitchSection(Section); MCContext &context = MCOS->getContext(); @@ -202,9 +204,9 @@ static inline void EmitDwarfLineTable(MCStreamer *MCOS, // Switch back the dwarf line section. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); - const MCAsmInfo &asmInfo = MCOS->getContext().getAsmInfo(); + const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd, - asmInfo.getPointerSize()); + asmInfo->getPointerSize()); } // @@ -215,9 +217,36 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { // Switch to the section where the table will be emitted into. MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); - // Create a symbol at the beginning of this section. - MCSymbol *LineStartSym = context.CreateTempSymbol(); - // Set the value of the symbol, as we are at the start of the section. + const DenseMap &MCLineTableSymbols = + MCOS->getContext().getMCLineTableSymbols(); + // CUID and MCLineTableSymbols are set in DwarfDebug, when DwarfDebug does + // not exist, CUID will be 0 and MCLineTableSymbols will be empty. + // Handle Compile Unit 0, the line table start symbol is the section symbol. + const MCSymbol *LineStartSym = EmitCU(MCOS, 0); + // Handle the rest of the Compile Units. + for (unsigned Is = 1, Ie = MCLineTableSymbols.size(); Is < Ie; Is++) + EmitCU(MCOS, Is); + + // Now delete the MCLineSections that were created in MCLineEntry::Make() + // and used to emit the line table. + const DenseMap &MCLineSections = + MCOS->getContext().getMCLineSections(); + for (DenseMap::const_iterator it = + MCLineSections.begin(), ie = MCLineSections.end(); it != ie; + ++it) + delete it->second; + + return LineStartSym; +} + +const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) { + MCContext &context = MCOS->getContext(); + + // Create a symbol at the beginning of the line table. + MCSymbol *LineStartSym = MCOS->getContext().getMCLineTableSymbol(CUID); + if (!LineStartSym) + LineStartSym = context.CreateTempSymbol(); + // Set the value of the symbol, as we are at the start of the line table. MCOS->EmitLabel(LineStartSym); // Create a symbol for the end of the section (to be set when we get there). @@ -239,11 +268,10 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { // total length, the 2 bytes for the version, and these 4 bytes for the // length of the prologue. MCOS->EmitAbsValue(MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym, - (4 + 2 + 4)), - 4, 0); + (4 + 2 + 4)), 4, 0); // Parameters of the state machine, are next. - MCOS->EmitIntValue(DWARF2_LINE_MIN_INSN_LENGTH, 1); + MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1); MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1); MCOS->EmitIntValue(DWARF2_LINE_BASE, 1); MCOS->EmitIntValue(DWARF2_LINE_RANGE, 1); @@ -266,8 +294,8 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { // Put out the directory and file tables. // First the directory table. - const std::vector &MCDwarfDirs = - context.getMCDwarfDirs(); + const SmallVectorImpl &MCDwarfDirs = + context.getMCDwarfDirs(CUID); for (unsigned i = 0; i < MCDwarfDirs.size(); i++) { MCOS->EmitBytes(MCDwarfDirs[i]); // the DirectoryName MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string @@ -275,8 +303,8 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { MCOS->EmitIntValue(0, 1); // Terminate the directory list // Second the file table. - const std::vector &MCDwarfFiles = - MCOS->getContext().getMCDwarfFiles(); + const SmallVectorImpl &MCDwarfFiles = + MCOS->getContext().getMCDwarfFiles(CUID); for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { MCOS->EmitBytes(MCDwarfFiles[i]->getName()); // FileName MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string @@ -301,14 +329,10 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { ++it) { const MCSection *Sec = *it; const MCLineSection *Line = MCLineSections.lookup(Sec); - EmitDwarfLineTable(MCOS, Sec, Line); - - // Now delete the MCLineSections that were created in MCLineEntry::Make() - // and used to emit the line table. - delete Line; + EmitDwarfLineTable(MCOS, Sec, Line, CUID); } - if (MCOS->getContext().getAsmInfo().getLinkerRequiresNonEmptyDwarfLines() + if (MCOS->getContext().getAsmInfo()->getLinkerRequiresNonEmptyDwarfLines() && MCLineSectionOrder.begin() == MCLineSectionOrder.end()) { // The darwin9 linker has a bug (see PR8715). For for 32-bit architectures // it requires: @@ -327,32 +351,24 @@ const MCSymbol *MCDwarfFileTable::Emit(MCStreamer *MCOS) { return LineStartSym; } -/// Utility function to write the encoding to an object writer. -void MCDwarfLineAddr::Write(MCObjectWriter *OW, int64_t LineDelta, - uint64_t AddrDelta) { - SmallString<256> Tmp; - raw_svector_ostream OS(Tmp); - MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS); - OW->WriteBytes(OS.str()); -} - /// Utility function to emit the encoding to a streamer. void MCDwarfLineAddr::Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta) { + MCContext &Context = MCOS->getContext(); SmallString<256> Tmp; raw_svector_ostream OS(Tmp); - MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS); + MCDwarfLineAddr::Encode(Context, LineDelta, AddrDelta, OS); MCOS->EmitBytes(OS.str()); } /// Utility function to encode a Dwarf pair of LineDelta and AddrDeltas. -void MCDwarfLineAddr::Encode(int64_t LineDelta, uint64_t AddrDelta, - raw_ostream &OS) { +void MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta, + uint64_t AddrDelta, raw_ostream &OS) { uint64_t Temp, Opcode; bool NeedCopy = false; // Scale the address delta by the minimum instruction length. - AddrDelta = ScaleAddrDelta(AddrDelta); + AddrDelta = ScaleAddrDelta(Context, AddrDelta); // A LineDelta of INT64_MAX is a signal that this is actually a // DW_LNE_end_sequence. We cannot use special opcodes here, since we want the @@ -504,8 +520,8 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS, // Figure the padding after the header before the table of address and size // pairs who's values are PointerSize'ed. - const MCAsmInfo &asmInfo = context.getAsmInfo(); - int AddrSize = asmInfo.getPointerSize(); + const MCAsmInfo *asmInfo = context.getAsmInfo(); + int AddrSize = asmInfo->getPointerSize(); int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1)); if (Pad == 2 * AddrSize) Pad = 0; @@ -585,8 +601,8 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, MCOS->EmitIntValue(0, 4); } - const MCAsmInfo &asmInfo = context.getAsmInfo(); - int AddrSize = asmInfo.getPointerSize(); + const MCAsmInfo *asmInfo = context.getAsmInfo(); + int AddrSize = asmInfo->getPointerSize(); // The 1 byte size of an address. MCOS->EmitIntValue(AddrSize, 1); @@ -615,13 +631,13 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, // AT_name, the name of the source file. Reconstruct from the first directory // and file table entries. - const std::vector &MCDwarfDirs = + const SmallVectorImpl &MCDwarfDirs = context.getMCDwarfDirs(); if (MCDwarfDirs.size() > 0) { MCOS->EmitBytes(MCDwarfDirs[0]); MCOS->EmitBytes("/"); } - const std::vector &MCDwarfFiles = + const SmallVectorImpl &MCDwarfFiles = MCOS->getContext().getMCDwarfFiles(); MCOS->EmitBytes(MCDwarfFiles[1]->getName()); MCOS->EmitIntValue(0, 1); // NULL byte to terminate the string. @@ -713,9 +729,9 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, void MCGenDwarfInfo::Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol) { // Create the dwarf sections in this order (.debug_line already created). MCContext &context = MCOS->getContext(); - const MCAsmInfo &AsmInfo = context.getAsmInfo(); + const MCAsmInfo *AsmInfo = context.getAsmInfo(); bool CreateDwarfSectionSymbols = - AsmInfo.doesDwarfUseRelocationsAcrossSections(); + AsmInfo->doesDwarfUseRelocationsAcrossSections(); if (!CreateDwarfSectionSymbols) LineSectionSymbol = NULL; MCSymbol *AbbrevSectionSymbol = NULL; @@ -759,7 +775,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, if (Symbol->isTemporary()) return; MCContext &context = MCOS->getContext(); - if (context.getGenDwarfSection() != MCOS->getCurrentSection()) + if (context.getGenDwarfSection() != MCOS->getCurrentSection().first) return; // The dwarf label's name does not have the symbol name's leading @@ -791,9 +807,9 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, static int getDataAlignmentFactor(MCStreamer &streamer) { MCContext &context = streamer.getContext(); - const MCAsmInfo &asmInfo = context.getAsmInfo(); - int size = asmInfo.getPointerSize(); - if (asmInfo.isStackGrowthDirectionUp()) + const MCAsmInfo *asmInfo = context.getAsmInfo(); + int size = asmInfo->getCalleeSaveStackSlotSize(); + if (asmInfo->isStackGrowthDirectionUp()) return size; else return -size; @@ -807,7 +823,7 @@ static unsigned getSizeForEncoding(MCStreamer &streamer, default: llvm_unreachable("Unknown Encoding"); case dwarf::DW_EH_PE_absptr: case dwarf::DW_EH_PE_signed: - return context.getAsmInfo().getPointerSize(); + return context.getAsmInfo()->getPointerSize(); case dwarf::DW_EH_PE_udata2: case dwarf::DW_EH_PE_sdata2: return 2; @@ -823,10 +839,10 @@ static unsigned getSizeForEncoding(MCStreamer &streamer, static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, const char *comment = 0) { MCContext &context = streamer.getContext(); - const MCAsmInfo &asmInfo = context.getAsmInfo(); - const MCExpr *v = asmInfo.getExprForFDESymbol(&symbol, - symbolEncoding, - streamer); + const MCAsmInfo *asmInfo = context.getAsmInfo(); + const MCExpr *v = asmInfo->getExprForFDESymbol(&symbol, + symbolEncoding, + streamer); unsigned size = getSizeForEncoding(streamer, symbolEncoding); if (streamer.isVerboseAsm() && comment) streamer.AddComment(comment); streamer.EmitAbsValue(v, size); @@ -835,25 +851,14 @@ static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding) { MCContext &context = streamer.getContext(); - const MCAsmInfo &asmInfo = context.getAsmInfo(); - const MCExpr *v = asmInfo.getExprForPersonalitySymbol(&symbol, - symbolEncoding, - streamer); + const MCAsmInfo *asmInfo = context.getAsmInfo(); + const MCExpr *v = asmInfo->getExprForPersonalitySymbol(&symbol, + symbolEncoding, + streamer); unsigned size = getSizeForEncoding(streamer, symbolEncoding); streamer.EmitValue(v, size); } -static const MachineLocation TranslateMachineLocation( - const MCRegisterInfo &MRI, - const MachineLocation &Loc) { - unsigned Reg = Loc.getReg() == MachineLocation::VirtualFP ? - MachineLocation::VirtualFP : - unsigned(MRI.getDwarfRegNum(Loc.getReg(), true)); - const MachineLocation &NewLoc = Loc.isReg() ? - MachineLocation(Reg) : MachineLocation(Reg, Loc.getOffset()); - return NewLoc; -} - namespace { class FrameEmitterImpl { int CFAOffset; @@ -871,7 +876,7 @@ namespace { /// EmitCompactUnwind - Emit the unwind information in a compact way. If /// we're successful, return 'true'. Otherwise, return 'false' and it will /// emit the normal CIE and FDE. - bool EmitCompactUnwind(MCStreamer &streamer, + void EmitCompactUnwind(MCStreamer &streamer, const MCDwarfFrameInfo &frame); const MCSymbol &EmitCIE(MCStreamer &streamer, @@ -1111,7 +1116,7 @@ void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer, /// EmitCompactUnwind - Emit the unwind information in a compact way. If we're /// successful, return 'true'. Otherwise, return 'false' and it will emit the /// normal CIE and FDE. -bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, +void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, const MCDwarfFrameInfo &Frame) { MCContext &Context = Streamer.getContext(); const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); @@ -1140,14 +1145,13 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, // .quad except_tab1 uint32_t Encoding = Frame.CompactUnwindEncoding; - if (!Encoding) return false; + if (!Encoding) return; + bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly()); // The encoding needs to know we have an LSDA. - if (Frame.Lsda) + if (!DwarfEHFrameOnly && Frame.Lsda) Encoding |= 0x40000000; - Streamer.SwitchSection(MOFI->getCompactUnwindSection()); - // Range Start unsigned FDEEncoding = MOFI->getFDEEncoding(UsingCFI); unsigned Size = getSizeForEncoding(Streamer, FDEEncoding); @@ -1166,11 +1170,10 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, Twine::utohexstr(Encoding)); Streamer.EmitIntValue(Encoding, Size); - // Personality Function Size = getSizeForEncoding(Streamer, dwarf::DW_EH_PE_absptr); if (VerboseAsm) Streamer.AddComment("Personality Function"); - if (Frame.Personality) + if (!DwarfEHFrameOnly && Frame.Personality) Streamer.EmitSymbolValue(Frame.Personality, Size); else Streamer.EmitIntValue(0, Size); // No personality fn @@ -1178,12 +1181,10 @@ bool FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, // LSDA Size = getSizeForEncoding(Streamer, Frame.LsdaEncoding); if (VerboseAsm) Streamer.AddComment("LSDA"); - if (Frame.Lsda) + if (!DwarfEHFrameOnly && Frame.Lsda) Streamer.EmitSymbolValue(Frame.Lsda, Size); else Streamer.EmitIntValue(0, Size); // No LSDA - - return true; } const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, @@ -1193,7 +1194,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, bool IsSignalFrame, unsigned lsdaEncoding) { MCContext &context = streamer.getContext(); - const MCRegisterInfo &MRI = context.getRegisterInfo(); + const MCRegisterInfo *MRI = context.getRegisterInfo(); const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); bool verboseAsm = streamer.isVerboseAsm(); @@ -1241,7 +1242,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, // Code Alignment Factor if (verboseAsm) streamer.AddComment("CIE Code Alignment Factor"); - streamer.EmitULEB128IntValue(1); + streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment()); // Data Alignment Factor if (verboseAsm) streamer.AddComment("CIE Data Alignment Factor"); @@ -1249,7 +1250,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, // Return Address Register if (verboseAsm) streamer.AddComment("CIE Return Address Column"); - streamer.EmitULEB128IntValue(MRI.getDwarfRegNum(MRI.getRARegister(), true)); + streamer.EmitULEB128IntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true)); // Augmentation Data Length (optional) @@ -1289,38 +1290,13 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer, // Initial Instructions - const MCAsmInfo &MAI = context.getAsmInfo(); - const std::vector &Moves = MAI.getInitialFrameState(); - std::vector Instructions; - - for (int i = 0, n = Moves.size(); i != n; ++i) { - MCSymbol *Label = Moves[i].getLabel(); - const MachineLocation &Dst = - TranslateMachineLocation(MRI, Moves[i].getDestination()); - const MachineLocation &Src = - TranslateMachineLocation(MRI, Moves[i].getSource()); - - if (Dst.isReg()) { - assert(Dst.getReg() == MachineLocation::VirtualFP); - assert(!Src.isReg()); - MCCFIInstruction Inst = - MCCFIInstruction::createDefCfa(Label, Src.getReg(), -Src.getOffset()); - Instructions.push_back(Inst); - } else { - assert(Src.isReg()); - unsigned Reg = Src.getReg(); - int Offset = Dst.getOffset(); - MCCFIInstruction Inst = - MCCFIInstruction::createOffset(Label, Reg, Offset); - Instructions.push_back(Inst); - } - } - + const MCAsmInfo *MAI = context.getAsmInfo(); + const std::vector &Instructions = + MAI->getInitialFrameState(); EmitCFIInstructions(streamer, Instructions, NULL); // Padding - streamer.EmitValueToAlignment(IsEH - ? 4 : context.getAsmInfo().getPointerSize()); + streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize()); streamer.EmitLabel(sectionEnd); return *sectionStart; @@ -1350,13 +1326,13 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, streamer.EmitLabel(fdeStart); // CIE Pointer - const MCAsmInfo &asmInfo = context.getAsmInfo(); + const MCAsmInfo *asmInfo = context.getAsmInfo(); if (IsEH) { const MCExpr *offset = MakeStartMinusEndExpr(streamer, cieStart, *fdeStart, 0); if (verboseAsm) streamer.AddComment("FDE CIE Offset"); streamer.EmitAbsValue(offset, 4); - } else if (!asmInfo.doesDwarfUseRelocationsAcrossSections()) { + } else if (!asmInfo->doesDwarfUseRelocationsAcrossSections()) { const MCExpr *offset = MakeStartMinusEndExpr(streamer, *SectionStart, cieStart, 0); streamer.EmitAbsValue(offset, 4); @@ -1393,7 +1369,6 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, } // Call Frame Instructions - EmitCFIInstructions(streamer, frame.Instructions, frame.Begin); // Padding @@ -1448,21 +1423,28 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, bool UsingCFI, bool IsEH) { MCContext &Context = Streamer.getContext(); - MCObjectFileInfo *MOFI = - const_cast(Context.getObjectFileInfo()); + const MCObjectFileInfo *MOFI = Context.getObjectFileInfo(); FrameEmitterImpl Emitter(UsingCFI, IsEH); ArrayRef FrameArray = Streamer.getFrameInfos(); // Emit the compact unwind info if available. - if (IsEH && MOFI->getCompactUnwindSection()) - for (unsigned i = 0, n = Streamer.getNumFrameInfos(); i < n; ++i) { - const MCDwarfFrameInfo &Frame = Streamer.getFrameInfo(i); - if (Frame.CompactUnwindEncoding) - Emitter.EmitCompactUnwind(Streamer, Frame); + if (IsEH && MOFI->getCompactUnwindSection()) { + bool SectionEmitted = false; + for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) { + const MCDwarfFrameInfo &Frame = FrameArray[i]; + if (Frame.CompactUnwindEncoding == 0) continue; + if (!SectionEmitted) { + Streamer.SwitchSection(MOFI->getCompactUnwindSection()); + Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize()); + SectionEmitted = true; + } + Emitter.EmitCompactUnwind(Streamer, Frame); } + } - const MCSection &Section = IsEH ? *MOFI->getEHFrameSection() : - *MOFI->getDwarfFrameSection(); + const MCSection &Section = + IsEH ? *const_cast(MOFI)->getEHFrameSection() : + *MOFI->getDwarfFrameSection(); Streamer.SwitchSection(&Section); MCSymbol *SectionStart = Context.CreateTempSymbol(); Streamer.EmitLabel(SectionStart); @@ -1489,22 +1471,26 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, Streamer.EmitLabel(FDEEnd); } - Streamer.EmitValueToAlignment(Context.getAsmInfo().getPointerSize()); + Streamer.EmitValueToAlignment(Context.getAsmInfo()->getPointerSize()); if (FDEEnd) Streamer.EmitLabel(FDEEnd); } void MCDwarfFrameEmitter::EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta) { + MCContext &Context = Streamer.getContext(); SmallString<256> Tmp; raw_svector_ostream OS(Tmp); - MCDwarfFrameEmitter::EncodeAdvanceLoc(AddrDelta, OS); + MCDwarfFrameEmitter::EncodeAdvanceLoc(Context, AddrDelta, OS); Streamer.EmitBytes(OS.str()); } -void MCDwarfFrameEmitter::EncodeAdvanceLoc(uint64_t AddrDelta, +void MCDwarfFrameEmitter::EncodeAdvanceLoc(MCContext &Context, + uint64_t AddrDelta, raw_ostream &OS) { - // FIXME: Assumes the code alignment factor is 1. + // Scale the address delta by the minimum instruction length. + AddrDelta = ScaleAddrDelta(Context, AddrDelta); + if (AddrDelta == 0) { } else if (isUIntN(6, AddrDelta)) { uint8_t Opcode = dwarf::DW_CFA_advance_loc | AddrDelta;