diff options
Diffstat (limited to 'contrib/llvm/lib/MC/MCDwarf.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCDwarf.cpp | 181 |
1 files changed, 108 insertions, 73 deletions
diff --git a/contrib/llvm/lib/MC/MCDwarf.cpp b/contrib/llvm/lib/MC/MCDwarf.cpp index 5effb01..90f96e2 100644 --- a/contrib/llvm/lib/MC/MCDwarf.cpp +++ b/contrib/llvm/lib/MC/MCDwarf.cpp @@ -64,12 +64,12 @@ static inline uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta) { // and if there is information from the last .loc directive that has yet to have // a line entry made for it is made. // -void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { +void MCLineEntry::Make(MCObjectStreamer *MCOS, MCSection *Section) { if (!MCOS->getContext().getDwarfLocSeen()) return; // Create a symbol at in the current section for use in the line entry. - MCSymbol *LineSym = MCOS->getContext().CreateTempSymbol(); + MCSymbol *LineSym = MCOS->getContext().createTempSymbol(); // Set the value of the symbol to use for the MCLineEntry. MCOS->EmitLabel(LineSym); @@ -80,7 +80,7 @@ void MCLineEntry::Make(MCObjectStreamer *MCOS, const MCSection *Section) { MCLineEntry LineEntry(LineSym, DwarfLoc); // clear DwarfLocSeen saying the current .loc info is now used. - MCOS->getContext().ClearDwarfLocSeen(); + MCOS->getContext().clearDwarfLocSeen(); // Add the line entry to this section's entries. MCOS->getContext() @@ -98,15 +98,15 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS, int IntVal) { MCSymbolRefExpr::VariantKind Variant = MCSymbolRefExpr::VK_None; const MCExpr *Res = - MCSymbolRefExpr::Create(&End, Variant, MCOS.getContext()); + MCSymbolRefExpr::create(&End, Variant, MCOS.getContext()); const MCExpr *RHS = - MCSymbolRefExpr::Create(&Start, Variant, MCOS.getContext()); + MCSymbolRefExpr::create(&Start, Variant, MCOS.getContext()); const MCExpr *Res1 = - MCBinaryExpr::Create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext()); + MCBinaryExpr::create(MCBinaryExpr::Sub, Res, RHS, MCOS.getContext()); const MCExpr *Res2 = - MCConstantExpr::Create(IntVal, MCOS.getContext()); + MCConstantExpr::create(IntVal, MCOS.getContext()); const MCExpr *Res3 = - MCBinaryExpr::Create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext()); + MCBinaryExpr::create(MCBinaryExpr::Sub, Res1, Res2, MCOS.getContext()); return Res3; } @@ -115,7 +115,7 @@ static inline const MCExpr *MakeStartMinusEndExpr(const MCStreamer &MCOS, // in the LineSection. // static inline void -EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section, +EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section, const MCLineSection::MCLineEntryCollection &LineEntries) { unsigned FileNum = 1; unsigned LastLine = 1; @@ -179,28 +179,19 @@ EmitDwarfLineTable(MCObjectStreamer *MCOS, const MCSection *Section, } // Emit a DW_LNE_end_sequence for the end of the section. - // Using the pointer Section create a temporary label at the end of the - // section and use that and the LastLabel to compute the address delta - // and use INT64_MAX as the line delta which is the signal that this is - // actually a DW_LNE_end_sequence. + // Use the section end label to compute the address delta and use INT64_MAX + // as the line delta which is the signal that this is actually a + // DW_LNE_end_sequence. + MCSymbol *SectionEnd = MCOS->endSection(Section); - // 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); + // Switch back the dwarf line section, in case endSection had to switch the + // section. + MCContext &Ctx = MCOS->getContext(); + MCOS->SwitchSection(Ctx.getObjectFileInfo()->getDwarfLineSection()); - MCContext &context = MCOS->getContext(); - // Create a symbol at the end of the section. - MCSymbol *SectionEnd = context.CreateTempSymbol(); - // Set the value of the symbol, as we are at the end of the section. - MCOS->EmitLabel(SectionEnd); - - // Switch back the dwarf line section. - MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfLineSection()); - - const MCAsmInfo *asmInfo = MCOS->getContext().getAsmInfo(); + const MCAsmInfo *AsmInfo = Ctx.getAsmInfo(); MCOS->EmitDwarfAdvanceLineAddr(INT64_MAX, LastLabel, SectionEnd, - asmInfo->getPointerSize()); + AsmInfo->getPointerSize()); } // @@ -243,7 +234,8 @@ std::pair<MCSymbol *, MCSymbol *> MCDwarfLineTableHeader::Emit(MCStreamer *MCOS) 0, // length of DW_LNS_set_epilogue_begin 1 // DW_LNS_set_isa }; - assert(array_lengthof(StandardOpcodeLengths) == (DWARF2_LINE_OPCODE_BASE - 1)); + assert(array_lengthof(StandardOpcodeLengths) == + (DWARF2_LINE_OPCODE_BASE - 1)); return Emit(MCOS, StandardOpcodeLengths); } @@ -253,9 +245,9 @@ static const MCExpr *forceExpAbs(MCStreamer &OS, const MCExpr* Expr) { if (Context.getAsmInfo()->hasAggressiveSymbolFolding()) return Expr; - MCSymbol *ABS = Context.CreateTempSymbol(); + MCSymbol *ABS = Context.createTempSymbol(); OS.EmitAssignment(ABS, Expr); - return MCSymbolRefExpr::Create(ABS, Context); + return MCSymbolRefExpr::create(ABS, Context); } static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) { @@ -272,12 +264,12 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, // Create a symbol at the beginning of the line table. MCSymbol *LineStartSym = Label; if (!LineStartSym) - LineStartSym = context.CreateTempSymbol(); + 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). - MCSymbol *LineEndSym = context.CreateTempSymbol(); + MCSymbol *LineEndSym = context.createTempSymbol(); // The first 4 bytes is the total length of the information for this // compilation unit (not including these 4 bytes for the length). @@ -288,7 +280,7 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCOS->EmitIntValue(2, 2); // Create a symbol for the end of the prologue (to be set when we get there). - MCSymbol *ProEndSym = context.CreateTempSymbol(); // Lprologue_end + MCSymbol *ProEndSym = context.createTempSymbol(); // Lprologue_end // Length of the prologue, is the next 4 bytes. Which is the start of the // section to the end of the prologue. Not including the 4 bytes for the @@ -368,8 +360,10 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, FileNumber = SourceIdMap.size() + 1; assert((MCDwarfFiles.empty() || FileNumber == MCDwarfFiles.size()) && "Don't mix autonumbered and explicit numbered line table usage"); + SmallString<256> Buffer; auto IterBool = SourceIdMap.insert( - std::make_pair((Directory + Twine('\0') + FileName).str(), FileNumber)); + std::make_pair((Directory + Twine('\0') + FileName).toStringRef(Buffer), + FileNumber)); if (!IterBool.second) return IterBool.first->second; } @@ -446,7 +440,7 @@ void MCDwarfLineAddr::Encode(MCContext &Context, int64_t LineDelta, if (LineDelta == INT64_MAX) { if (AddrDelta == MAX_SPECIAL_ADDR_DELTA) OS << char(dwarf::DW_LNS_const_add_pc); - else { + else if (AddrDelta) { OS << char(dwarf::DW_LNS_advance_pc); encodeULEB128(AddrDelta, OS); } @@ -616,13 +610,13 @@ static void EmitGenDwarfAranges(MCStreamer *MCOS, // Now emit the table of pairs of PointerSize'ed values for the section // addresses and sizes. - for (const auto &sec : Sections) { - MCSymbol *StartSymbol = sec.second.first; - MCSymbol *EndSymbol = sec.second.second; + for (MCSection *Sec : Sections) { + const MCSymbol *StartSymbol = Sec->getBeginSymbol(); + MCSymbol *EndSymbol = Sec->getEndSymbol(context); assert(StartSymbol && "StartSymbol must not be NULL"); assert(EndSymbol && "EndSymbol must not be NULL"); - const MCExpr *Addr = MCSymbolRefExpr::Create( + const MCExpr *Addr = MCSymbolRefExpr::create( StartSymbol, MCSymbolRefExpr::VK_None, context); const MCExpr *Size = MakeStartMinusEndExpr(*MCOS, *StartSymbol, *EndSymbol, 0); @@ -648,9 +642,9 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, // Create a symbol at the start and end of this section used in here for the // expression to calculate the length in the header. - MCSymbol *InfoStart = context.CreateTempSymbol(); + MCSymbol *InfoStart = context.createTempSymbol(); MCOS->EmitLabel(InfoStart); - MCSymbol *InfoEnd = context.CreateTempSymbol(); + MCSymbol *InfoEnd = context.createTempSymbol(); // First part: the header. @@ -705,18 +699,18 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, const auto TextSection = Sections.begin(); assert(TextSection != Sections.end() && "No text section found"); - MCSymbol *StartSymbol = TextSection->second.first; - MCSymbol *EndSymbol = TextSection->second.second; + MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol(); + MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context); assert(StartSymbol && "StartSymbol must not be NULL"); assert(EndSymbol && "EndSymbol must not be NULL"); // AT_low_pc, the first address of the default .text section. - const MCExpr *Start = MCSymbolRefExpr::Create( + const MCExpr *Start = MCSymbolRefExpr::create( StartSymbol, MCSymbolRefExpr::VK_None, context); MCOS->EmitValue(Start, AddrSize); // AT_high_pc, the last address of the default .text section. - const MCExpr *End = MCSymbolRefExpr::Create( + const MCExpr *End = MCSymbolRefExpr::create( EndSymbol, MCSymbolRefExpr::VK_None, context); MCOS->EmitValue(End, AddrSize); } @@ -778,7 +772,7 @@ static void EmitGenDwarfInfo(MCStreamer *MCOS, MCOS->EmitIntValue(Entry.getLineNumber(), 4); // AT_low_pc, start address of the label. - const MCExpr *AT_low_pc = MCSymbolRefExpr::Create(Entry.getLabel(), + const MCExpr *AT_low_pc = MCSymbolRefExpr::create(Entry.getLabel(), MCSymbolRefExpr::VK_None, context); MCOS->EmitValue(AT_low_pc, AddrSize); @@ -811,15 +805,14 @@ static void EmitGenDwarfRanges(MCStreamer *MCOS) { MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); - for (const auto sec : Sections) { - - MCSymbol *StartSymbol = sec.second.first; - MCSymbol *EndSymbol = sec.second.second; + for (MCSection *Sec : Sections) { + const MCSymbol *StartSymbol = Sec->getBeginSymbol(); + MCSymbol *EndSymbol = Sec->getEndSymbol(context); assert(StartSymbol && "StartSymbol must not be NULL"); assert(EndSymbol && "EndSymbol must not be NULL"); // Emit a base address selection entry for the start of this section - const MCExpr *SectionStartAddr = MCSymbolRefExpr::Create( + const MCExpr *SectionStartAddr = MCSymbolRefExpr::create( StartSymbol, MCSymbolRefExpr::VK_None, context); MCOS->EmitFill(AddrSize, 0xFF); MCOS->EmitValue(SectionStartAddr, AddrSize); @@ -871,18 +864,18 @@ void MCGenDwarfInfo::Emit(MCStreamer *MCOS) { MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfInfoSection()); if (CreateDwarfSectionSymbols) { - InfoSectionSymbol = context.CreateTempSymbol(); + InfoSectionSymbol = context.createTempSymbol(); MCOS->EmitLabel(InfoSectionSymbol); } MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfAbbrevSection()); if (CreateDwarfSectionSymbols) { - AbbrevSectionSymbol = context.CreateTempSymbol(); + AbbrevSectionSymbol = context.createTempSymbol(); MCOS->EmitLabel(AbbrevSectionSymbol); } if (UseRangesSection) { MCOS->SwitchSection(context.getObjectFileInfo()->getDwarfRangesSection()); if (CreateDwarfSectionSymbols) { - RangesSectionSymbol = context.CreateTempSymbol(); + RangesSectionSymbol = context.createTempSymbol(); MCOS->EmitLabel(RangesSectionSymbol); } } @@ -940,7 +933,7 @@ void MCGenDwarfLabelEntry::Make(MCSymbol *Symbol, MCStreamer *MCOS, // values so that they don't have things like an ARM thumb bit from the // original symbol. So when used they won't get a low bit set after // relocation. - MCSymbol *Label = context.CreateTempSymbol(); + MCSymbol *Label = context.createTempSymbol(); MCOS->EmitLabel(Label); // Create and entry for the info and add it to the other entries. @@ -1007,11 +1000,13 @@ static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, namespace { class FrameEmitterImpl { int CFAOffset; + int InitialCFAOffset; bool IsEH; const MCSymbol *SectionStart; public: FrameEmitterImpl(bool isEH) - : CFAOffset(0), IsEH(isEH), SectionStart(nullptr) {} + : CFAOffset(0), InitialCFAOffset(0), IsEH(isEH), SectionStart(nullptr) { + } void setSectionStart(const MCSymbol *Label) { SectionStart = Label; } @@ -1045,11 +1040,16 @@ static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding) { void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, const MCCFIInstruction &Instr) { int dataAlignmentFactor = getDataAlignmentFactor(Streamer); + auto *MRI = Streamer.getContext().getRegisterInfo(); switch (Instr.getOperation()) { case MCCFIInstruction::OpRegister: { unsigned Reg1 = Instr.getRegister(); unsigned Reg2 = Instr.getRegister2(); + if (!IsEH) { + Reg1 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg1, true), false); + Reg2 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg2, true), false); + } Streamer.EmitIntValue(dwarf::DW_CFA_register, 1); Streamer.EmitULEB128IntValue(Reg1); Streamer.EmitULEB128IntValue(Reg2); @@ -1082,8 +1082,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, return; } case MCCFIInstruction::OpDefCfa: { + unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); - Streamer.EmitULEB128IntValue(Instr.getRegister()); + Streamer.EmitULEB128IntValue(Reg); CFAOffset = -Instr.getOffset(); Streamer.EmitULEB128IntValue(CFAOffset); @@ -1091,8 +1094,11 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, } case MCCFIInstruction::OpDefCfaRegister: { + unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); - Streamer.EmitULEB128IntValue(Instr.getRegister()); + Streamer.EmitULEB128IntValue(Reg); return; } @@ -1103,6 +1109,9 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, Instr.getOperation() == MCCFIInstruction::OpRelOffset; unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); + int Offset = Instr.getOffset(); if (IsRelative) Offset -= CFAOffset; @@ -1136,6 +1145,8 @@ void FrameEmitterImpl::EmitCFIInstruction(MCObjectStreamer &Streamer, } case MCCFIInstruction::OpRestore: { unsigned Reg = Instr.getRegister(); + if (!IsEH) + Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1); return; } @@ -1234,6 +1245,20 @@ void FrameEmitterImpl::EmitCompactUnwind(MCObjectStreamer &Streamer, Streamer.EmitIntValue(0, Size); // No LSDA } +static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) { + if (IsEH) + return 1; + switch (DwarfVersion) { + case 2: + return 1; + case 3: + return 3; + case 4: + return 4; + } + llvm_unreachable("Unknown version"); +} + const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, const MCSymbol *personality, unsigned personalityEncoding, @@ -1245,10 +1270,10 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, const MCRegisterInfo *MRI = context.getRegisterInfo(); const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); - MCSymbol *sectionStart = context.CreateTempSymbol(); + MCSymbol *sectionStart = context.createTempSymbol(); streamer.EmitLabel(sectionStart); - MCSymbol *sectionEnd = context.CreateTempSymbol(); + MCSymbol *sectionEnd = context.createTempSymbol(); // Length const MCExpr *Length = MakeStartMinusEndExpr(streamer, *sectionStart, @@ -1260,9 +1285,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, streamer.EmitIntValue(CIE_ID, 4); // Version - // For DWARF2, we use CIE version 1 - // For DWARF3+, we use CIE version 3 - uint8_t CIEVersion = context.getDwarfVersion() <= 2 ? 1 : 3; + uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion()); streamer.EmitIntValue(CIEVersion, 1); // Augmentation String @@ -1276,10 +1299,18 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, Augmentation += "R"; if (IsSignalFrame) Augmentation += "S"; - streamer.EmitBytes(Augmentation.str()); + streamer.EmitBytes(Augmentation); } streamer.EmitIntValue(0, 1); + if (CIEVersion >= 4) { + // Address Size + streamer.EmitIntValue(context.getAsmInfo()->getPointerSize(), 1); + + // Segment Descriptor Size + streamer.EmitIntValue(0, 1); + } + // Code Alignment Factor streamer.EmitULEB128IntValue(context.getAsmInfo()->getMinInstAlignment()); @@ -1290,10 +1321,10 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, if (CIEVersion == 1) { assert(MRI->getRARegister() <= 255 && "DWARF 2 encodes return_address_register in one byte"); - streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), true), 1); + streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1); } else { streamer.EmitULEB128IntValue( - MRI->getDwarfRegNum(MRI->getRARegister(), true)); + MRI->getDwarfRegNum(MRI->getRARegister(), IsEH)); } // Augmentation Data Length (optional) @@ -1337,6 +1368,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCObjectStreamer &streamer, EmitCFIInstructions(streamer, Instructions, nullptr); } + InitialCFAOffset = CFAOffset; + // Padding streamer.EmitValueToAlignment(IsEH ? 4 : MAI->getPointerSize()); @@ -1348,10 +1381,12 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCObjectStreamer &streamer, const MCSymbol &cieStart, const MCDwarfFrameInfo &frame) { MCContext &context = streamer.getContext(); - MCSymbol *fdeStart = context.CreateTempSymbol(); - MCSymbol *fdeEnd = context.CreateTempSymbol(); + MCSymbol *fdeStart = context.createTempSymbol(); + MCSymbol *fdeEnd = context.createTempSymbol(); const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); + CFAOffset = InitialCFAOffset; + // Length const MCExpr *Length = MakeStartMinusEndExpr(streamer, *fdeStart, *fdeEnd, 0); emitAbsValue(streamer, Length, 4); @@ -1485,12 +1520,12 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, if (!NeedsEHFrameSection) return; - const MCSection &Section = - IsEH ? *const_cast<MCObjectFileInfo*>(MOFI)->getEHFrameSection() : - *MOFI->getDwarfFrameSection(); + MCSection &Section = + IsEH ? *const_cast<MCObjectFileInfo *>(MOFI)->getEHFrameSection() + : *MOFI->getDwarfFrameSection(); Streamer.SwitchSection(&Section); - MCSymbol *SectionStart = Context.CreateTempSymbol(); + MCSymbol *SectionStart = Context.createTempSymbol(); Streamer.EmitLabel(SectionStart); Emitter.setSectionStart(SectionStart); |