diff options
Diffstat (limited to 'gnu/llvm/lib/MC/MCDwarf.cpp')
| -rw-r--r-- | gnu/llvm/lib/MC/MCDwarf.cpp | 217 |
1 files changed, 142 insertions, 75 deletions
diff --git a/gnu/llvm/lib/MC/MCDwarf.cpp b/gnu/llvm/lib/MC/MCDwarf.cpp index a2beee32f2c..9e5d9ff73c7 100644 --- a/gnu/llvm/lib/MC/MCDwarf.cpp +++ b/gnu/llvm/lib/MC/MCDwarf.cpp @@ -257,6 +257,66 @@ static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size) { OS.EmitValue(ABS, Size); } +static void +emitV2FileDirTables(MCStreamer *MCOS, + const SmallVectorImpl<std::string> &MCDwarfDirs, + const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles) { + // First the directory table. + for (auto Dir : MCDwarfDirs) { + MCOS->EmitBytes(Dir); // The DirectoryName, and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + } + MCOS->EmitIntValue(0, 1); // Terminate the directory list. + + // Second the file table. + for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { + assert(!MCDwarfFiles[i].Name.empty()); + MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number. + MCOS->EmitIntValue(0, 1); // Last modification timestamp (always 0). + MCOS->EmitIntValue(0, 1); // File size (always 0). + } + MCOS->EmitIntValue(0, 1); // Terminate the file list. +} + +static void +emitV5FileDirTables(MCStreamer *MCOS, + const SmallVectorImpl<std::string> &MCDwarfDirs, + const SmallVectorImpl<MCDwarfFile> &MCDwarfFiles, + StringRef CompilationDir) { + // The directory format, which is just inline null-terminated strings. + MCOS->EmitIntValue(1, 1); + MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path); + MCOS->EmitULEB128IntValue(dwarf::DW_FORM_string); + // Then the list of directory paths. CompilationDir comes first. + MCOS->EmitULEB128IntValue(MCDwarfDirs.size() + 1); + MCOS->EmitBytes(CompilationDir); + MCOS->EmitBytes(StringRef("\0", 1)); + for (auto Dir : MCDwarfDirs) { + MCOS->EmitBytes(Dir); // The DirectoryName, and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + } + + // The file format, which is the inline null-terminated filename and a + // directory index. We don't track file size/timestamp so don't emit them + // in the v5 table. + // FIXME: Arrange to emit MD5 signatures for the source files. + MCOS->EmitIntValue(2, 1); + MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_path); + MCOS->EmitULEB128IntValue(dwarf::DW_FORM_string); + MCOS->EmitULEB128IntValue(dwarf::DW_LNCT_directory_index); + MCOS->EmitULEB128IntValue(dwarf::DW_FORM_udata); + // Then the list of file names. These start at 1 for some reason. + MCOS->EmitULEB128IntValue(MCDwarfFiles.size() - 1); + for (unsigned i = 1; i < MCDwarfFiles.size(); ++i) { + assert(!MCDwarfFiles[i].Name.empty()); + MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName and... + MCOS->EmitBytes(StringRef("\0", 1)); // its null terminator. + MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); // Directory number. + } +} + std::pair<MCSymbol *, MCSymbol *> MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, ArrayRef<char> StandardOpcodeLengths) const { @@ -277,22 +337,41 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, emitAbsValue(*MCOS, MakeStartMinusEndExpr(*MCOS, *LineStartSym, *LineEndSym, 4), 4); - // Next 2 bytes is the Version, which is Dwarf 2. - MCOS->EmitIntValue(2, 2); + // Next 2 bytes is the Version. + // FIXME: On Darwin we still default to V2. + unsigned LineTableVersion = context.getDwarfVersion(); + if (context.getObjectFileInfo()->getTargetTriple().isOSDarwin()) + LineTableVersion = 2; + MCOS->EmitIntValue(LineTableVersion, 2); + + // Keep track of the bytes between the very start and where the header length + // comes out. + unsigned PreHeaderLengthBytes = 4 + 2; + + // In v5, we get address info next. + if (LineTableVersion >= 5) { + MCOS->EmitIntValue(context.getAsmInfo()->getCodePointerSize(), 1); + MCOS->EmitIntValue(0, 1); // Segment selector; same as EmitGenDwarfAranges. + PreHeaderLengthBytes += 2; + } // Create a symbol for the end of the prologue (to be set when we get there). 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 - // total length, the 2 bytes for the version, and these 4 bytes for the - // length of the prologue. - emitAbsValue( - *MCOS, - MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym, (4 + 2 + 4)), 4); + // Length of the prologue, is the next 4 bytes. This is actually the length + // from after the length word, to the end of the prologue. + emitAbsValue(*MCOS, + MakeStartMinusEndExpr(*MCOS, *LineStartSym, *ProEndSym, + (PreHeaderLengthBytes + 4)), + 4); // Parameters of the state machine, are next. MCOS->EmitIntValue(context.getAsmInfo()->getMinInstAlignment(), 1); + // maximum_operations_per_instruction + // For non-VLIW architectures this field is always 1. + // FIXME: VLIW architectures need to update this field accordingly. + if (LineTableVersion >= 4) + MCOS->EmitIntValue(1, 1); MCOS->EmitIntValue(DWARF2_LINE_DEFAULT_IS_STMT, 1); MCOS->EmitIntValue(Params.DWARF2LineBase, 1); MCOS->EmitIntValue(Params.DWARF2LineRange, 1); @@ -302,26 +381,12 @@ MCDwarfLineTableHeader::Emit(MCStreamer *MCOS, MCDwarfLineTableParams Params, for (char Length : StandardOpcodeLengths) MCOS->EmitIntValue(Length, 1); - // Put out the directory and file tables. - - // First the directory table. - 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 - } - MCOS->EmitIntValue(0, 1); // Terminate the directory list - - // Second the file table. - for (unsigned i = 1; i < MCDwarfFiles.size(); i++) { - assert(!MCDwarfFiles[i].Name.empty()); - MCOS->EmitBytes(MCDwarfFiles[i].Name); // FileName - MCOS->EmitBytes(StringRef("\0", 1)); // the null term. of the string - // the Directory num - MCOS->EmitULEB128IntValue(MCDwarfFiles[i].DirIndex); - MCOS->EmitIntValue(0, 1); // last modification timestamp (always 0) - MCOS->EmitIntValue(0, 1); // filesize (always 0) - } - MCOS->EmitIntValue(0, 1); // Terminate the file list + // Put out the directory and file tables. The formats vary depending on + // the version. + if (LineTableVersion >= 5) + emitV5FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles, CompilationDir); + else + emitV2FileDirTables(MCOS, MCDwarfDirs, MCDwarfFiles); // This is the end of the prologue, so set the value of the symbol at the // end of the prologue (that was used in a previous expression). @@ -370,7 +435,8 @@ unsigned MCDwarfLineTableHeader::getFile(StringRef &Directory, return IterBool.first->second; } // Make space for this FileNumber in the MCDwarfFiles vector if needed. - MCDwarfFiles.resize(FileNumber + 1); + if (FileNumber >= MCDwarfFiles.size()) + MCDwarfFiles.resize(FileNumber + 1); // Get the new MCDwarfFile slot for this FileNumber. MCDwarfFile &File = MCDwarfFiles[FileNumber]; @@ -1034,10 +1100,7 @@ public: /// Emit the unwind information in a compact way. void EmitCompactUnwind(const MCDwarfFrameInfo &frame); - const MCSymbol &EmitCIE(const MCSymbol *personality, - unsigned personalityEncoding, const MCSymbol *lsda, - bool IsSignalFrame, unsigned lsdaEncoding, - bool IsSimple); + const MCSymbol &EmitCIE(const MCDwarfFrameInfo &F); void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame, bool LastInSection, const MCSymbol &SectionStart); void EmitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs, @@ -1060,8 +1123,8 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) { 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); + Reg1 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg1); + Reg2 = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg2); } Streamer.EmitIntValue(dwarf::DW_CFA_register, 1); Streamer.EmitULEB128IntValue(Reg1); @@ -1097,7 +1160,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) { case MCCFIInstruction::OpDefCfa: { unsigned Reg = Instr.getRegister(); if (!IsEH) - Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); + Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1); Streamer.EmitULEB128IntValue(Reg); CFAOffset = -Instr.getOffset(); @@ -1108,7 +1171,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) { case MCCFIInstruction::OpDefCfaRegister: { unsigned Reg = Instr.getRegister(); if (!IsEH) - Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); + Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg); Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1); Streamer.EmitULEB128IntValue(Reg); @@ -1121,7 +1184,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) { unsigned Reg = Instr.getRegister(); if (!IsEH) - Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); + Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg); int Offset = Instr.getOffset(); if (IsRelative) @@ -1157,7 +1220,7 @@ void FrameEmitterImpl::EmitCFIInstruction(const MCCFIInstruction &Instr) { case MCCFIInstruction::OpRestore: { unsigned Reg = Instr.getRegister(); if (!IsEH) - Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg, true), false); + Reg = MRI->getDwarfRegNumFromDwarfEHRegNum(Reg); Streamer.EmitIntValue(dwarf::DW_CFA_restore | Reg, 1); return; } @@ -1273,12 +1336,7 @@ static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion) { llvm_unreachable("Unknown version"); } -const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality, - unsigned personalityEncoding, - const MCSymbol *lsda, - bool IsSignalFrame, - unsigned lsdaEncoding, - bool IsSimple) { +const MCSymbol &FrameEmitterImpl::EmitCIE(const MCDwarfFrameInfo &Frame) { MCContext &context = Streamer.getContext(); const MCRegisterInfo *MRI = context.getRegisterInfo(); const MCObjectFileInfo *MOFI = context.getObjectFileInfo(); @@ -1305,12 +1363,12 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality, SmallString<8> Augmentation; if (IsEH) { Augmentation += "z"; - if (personality) + if (Frame.Personality) Augmentation += "P"; - if (lsda) + if (Frame.Lsda) Augmentation += "L"; Augmentation += "R"; - if (IsSignalFrame) + if (Frame.IsSignalFrame) Augmentation += "S"; Streamer.EmitBytes(Augmentation); } @@ -1331,26 +1389,29 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality, Streamer.EmitSLEB128IntValue(getDataAlignmentFactor(Streamer)); // Return Address Register + unsigned RAReg = Frame.RAReg; + if (RAReg == static_cast<unsigned>(INT_MAX)) + RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH); + if (CIEVersion == 1) { - assert(MRI->getRARegister() <= 255 && + assert(RAReg <= 255 && "DWARF 2 encodes return_address_register in one byte"); - Streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1); + Streamer.EmitIntValue(RAReg, 1); } else { - Streamer.EmitULEB128IntValue( - MRI->getDwarfRegNum(MRI->getRARegister(), IsEH)); + Streamer.EmitULEB128IntValue(RAReg); } // Augmentation Data Length (optional) - unsigned augmentationLength = 0; if (IsEH) { - if (personality) { + if (Frame.Personality) { // Personality Encoding augmentationLength += 1; // Personality - augmentationLength += getSizeForEncoding(Streamer, personalityEncoding); + augmentationLength += + getSizeForEncoding(Streamer, Frame.PersonalityEncoding); } - if (lsda) + if (Frame.Lsda) augmentationLength += 1; // Encoding of the FDE pointers augmentationLength += 1; @@ -1358,15 +1419,15 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality, Streamer.EmitULEB128IntValue(augmentationLength); // Augmentation Data (optional) - if (personality) { + if (Frame.Personality) { // Personality Encoding - emitEncodingByte(Streamer, personalityEncoding); + emitEncodingByte(Streamer, Frame.PersonalityEncoding); // Personality - EmitPersonality(Streamer, *personality, personalityEncoding); + EmitPersonality(Streamer, *Frame.Personality, Frame.PersonalityEncoding); } - if (lsda) - emitEncodingByte(Streamer, lsdaEncoding); + if (Frame.Lsda) + emitEncodingByte(Streamer, Frame.LsdaEncoding); // Encoding of the FDE pointers emitEncodingByte(Streamer, MOFI->getFDEEncoding()); @@ -1375,7 +1436,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality, // Initial Instructions const MCAsmInfo *MAI = context.getAsmInfo(); - if (!IsSimple) { + if (!Frame.IsSimple) { const std::vector<MCCFIInstruction> &Instructions = MAI->getInitialFrameState(); EmitCFIInstructions(Instructions, nullptr); @@ -1463,24 +1524,32 @@ namespace { struct CIEKey { static const CIEKey getEmptyKey() { - return CIEKey(nullptr, 0, -1, false, false); + return CIEKey(nullptr, 0, -1, false, false, static_cast<unsigned>(INT_MAX)); } static const CIEKey getTombstoneKey() { - return CIEKey(nullptr, -1, 0, false, false); + return CIEKey(nullptr, -1, 0, false, false, static_cast<unsigned>(INT_MAX)); } CIEKey(const MCSymbol *Personality, unsigned PersonalityEncoding, - unsigned LsdaEncoding, bool IsSignalFrame, bool IsSimple) + unsigned LSDAEncoding, bool IsSignalFrame, bool IsSimple, + unsigned RAReg) : Personality(Personality), PersonalityEncoding(PersonalityEncoding), - LsdaEncoding(LsdaEncoding), IsSignalFrame(IsSignalFrame), - IsSimple(IsSimple) {} + LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame), + IsSimple(IsSimple), RAReg(RAReg) {} + + explicit CIEKey(const MCDwarfFrameInfo &Frame) + : Personality(Frame.Personality), + PersonalityEncoding(Frame.PersonalityEncoding), + LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame), + IsSimple(Frame.IsSimple), RAReg(Frame.RAReg) {} const MCSymbol *Personality; unsigned PersonalityEncoding; unsigned LsdaEncoding; bool IsSignalFrame; bool IsSimple; + unsigned RAReg; }; } // end anonymous namespace @@ -1494,7 +1563,7 @@ template <> struct DenseMapInfo<CIEKey> { static unsigned getHashValue(const CIEKey &Key) { return static_cast<unsigned>( hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding, - Key.IsSignalFrame, Key.IsSimple)); + Key.IsSignalFrame, Key.IsSimple, Key.RAReg)); } static bool isEqual(const CIEKey &LHS, const CIEKey &RHS) { @@ -1502,7 +1571,8 @@ template <> struct DenseMapInfo<CIEKey> { LHS.PersonalityEncoding == RHS.PersonalityEncoding && LHS.LsdaEncoding == RHS.LsdaEncoding && LHS.IsSignalFrame == RHS.IsSignalFrame && - LHS.IsSimple == RHS.IsSimple; + LHS.IsSimple == RHS.IsSimple && + LHS.RAReg == RHS.RAReg; } }; @@ -1559,13 +1629,10 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB, // of by the compact unwind encoding. continue; - CIEKey Key(Frame.Personality, Frame.PersonalityEncoding, - Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple); + CIEKey Key(Frame); const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey; if (!CIEStart) - CIEStart = &Emitter.EmitCIE(Frame.Personality, Frame.PersonalityEncoding, - Frame.Lsda, Frame.IsSignalFrame, - Frame.LsdaEncoding, Frame.IsSimple); + CIEStart = &Emitter.EmitCIE(Frame); Emitter.EmitFDE(*CIEStart, Frame, I == E, *SectionStart); } |
