X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCDwarf.cpp;h=1e5c2e34c488bf231b2dd4b2a51cf092a3aae8b1;hb=b74b88edac9ab490ba428aef0bdebc957399bbd7;hp=549ab7ff219d7c8795abbd6e76bbd11f699e5328;hpb=3c08eef20b9cfc31d4ae3a43f1c9a57a4ab2cad7;p=oota-llvm.git diff --git a/lib/MC/MCDwarf.cpp b/lib/MC/MCDwarf.cpp index 549ab7ff219..1e5c2e34c48 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; } // @@ -182,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; @@ -197,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(); @@ -208,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()); } // @@ -272,10 +268,10 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) { // 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); // 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); @@ -336,7 +332,7 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) { 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: @@ -355,32 +351,24 @@ const MCSymbol *MCDwarfFileTable::EmitCU(MCStreamer *MCOS, unsigned CUID) { 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 @@ -532,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; @@ -613,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); @@ -741,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; @@ -787,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 @@ -819,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.getCalleeSaveStackSlotSize(); - if (asmInfo.isStackGrowthDirectionUp()) + const MCAsmInfo *asmInfo = context.getAsmInfo(); + int size = asmInfo->getCalleeSaveStackSlotSize(); + if (asmInfo->isStackGrowthDirectionUp()) return size; else return -size; @@ -835,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; @@ -851,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); @@ -863,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; @@ -896,9 +873,7 @@ namespace { void setSectionStart(const MCSymbol *Label) { SectionStart = Label; } - /// 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. + /// EmitCompactUnwind - Emit the unwind information in a compact way. void EmitCompactUnwind(MCStreamer &streamer, const MCDwarfFrameInfo &frame); @@ -912,7 +887,7 @@ namespace { const MCSymbol &cieStart, const MCDwarfFrameInfo &frame); void EmitCFIInstructions(MCStreamer &streamer, - const std::vector &Instrs, + ArrayRef Instrs, MCSymbol *BaseLabel); void EmitCFIInstruction(MCStreamer &Streamer, const MCCFIInstruction &Instr); @@ -984,6 +959,10 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer, Streamer.EmitULEB128IntValue(Reg2); return; } + case MCCFIInstruction::OpWindowSave: { + Streamer.EmitIntValue(dwarf::DW_CFA_GNU_window_save, 1); + return; + } case MCCFIInstruction::OpUndefined: { unsigned Reg = Instr.getRegister(); if (VerboseAsm) { @@ -1114,7 +1093,7 @@ void FrameEmitterImpl::EmitCFIInstruction(MCStreamer &Streamer, /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. void FrameEmitterImpl::EmitCFIInstructions(MCStreamer &streamer, - const std::vector &Instrs, + ArrayRef Instrs, MCSymbol *BaseLabel) { for (unsigned i = 0, N = Instrs.size(); i < N; ++i) { const MCCFIInstruction &Instr = Instrs[i]; @@ -1136,9 +1115,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. +/// EmitCompactUnwind - Emit the unwind information in a compact way. void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, const MCDwarfFrameInfo &Frame) { MCContext &Context = Streamer.getContext(); @@ -1169,15 +1146,12 @@ void FrameEmitterImpl::EmitCompactUnwind(MCStreamer &Streamer, uint32_t Encoding = Frame.CompactUnwindEncoding; if (!Encoding) return; - bool DwarfEHFrameOnly = (Encoding == MOFI->getCompactUnwindDwarfEHFrameOnly()); // The encoding needs to know we have an LSDA. if (!DwarfEHFrameOnly && Frame.Lsda) Encoding |= 0x40000000; - Streamer.SwitchSection(MOFI->getCompactUnwindSection()); - // Range Start unsigned FDEEncoding = MOFI->getFDEEncoding(UsingCFI); unsigned Size = getSizeForEncoding(Streamer, FDEEncoding); @@ -1220,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(); @@ -1268,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"); @@ -1276,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) @@ -1316,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; @@ -1377,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); @@ -1420,7 +1369,6 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer, } // Call Frame Instructions - EmitCFIInstructions(streamer, frame.Instructions, frame.Begin); // Padding @@ -1471,25 +1419,33 @@ namespace llvm { }; } -void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, - bool UsingCFI, - bool IsEH) { +void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer, MCAsmBackend *MAB, + bool UsingCFI, bool IsEH) { + Streamer.generateCompactUnwindEncodings(MAB); + 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); @@ -1516,22 +1472,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;