diff options
author | David Majnemer <david.majnemer@gmail.com> | 2016-01-29 19:24:12 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2016-01-29 19:24:12 +0000 |
commit | 6fcbd7e909b9e8bc35d51b58faed52b10e39eb75 (patch) | |
tree | 7b07a7d1a345d0d97976c53d3fe2f46cc0af3dfb /llvm/lib/MC/MCCodeView.cpp | |
parent | ad0e791e0b9e8ec77d8cbd0383b8ebf4caa17ef5 (diff) | |
download | llvm-6fcbd7e909b9e8bc35d51b58faed52b10e39eb75.zip llvm-6fcbd7e909b9e8bc35d51b58faed52b10e39eb75.tar.gz llvm-6fcbd7e909b9e8bc35d51b58faed52b10e39eb75.tar.bz2 |
[CodeView] Implement .cv_inline_linetable
This support is _very_ rudimentary, just enough to get some basic data
into the CodeView debug section.
Left to do is:
- Use the combined opcodes to save space.
- Do something about code offsets.
llvm-svn: 259230
Diffstat (limited to 'llvm/lib/MC/MCCodeView.cpp')
-rw-r--r-- | llvm/lib/MC/MCCodeView.cpp | 74 |
1 files changed, 71 insertions, 3 deletions
diff --git a/llvm/lib/MC/MCCodeView.cpp b/llvm/lib/MC/MCCodeView.cpp index 95cf7cc..a876470 100644 --- a/llvm/lib/MC/MCCodeView.cpp +++ b/llvm/lib/MC/MCCodeView.cpp @@ -15,6 +15,7 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/Line.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectStreamer.h" #include "llvm/Support/COFF.h" @@ -151,11 +152,11 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS, OS.EmitCOFFSectionIndex(FuncBegin); // Actual line info. - ArrayRef<MCCVLineEntry> Locs = getFunctionLineEntries(FuncId); + std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(FuncId); bool HaveColumns = any_of(Locs, [](const MCCVLineEntry &LineEntry) { return LineEntry.getColumn() != 0; }); - OS.EmitIntValue(HaveColumns ? int(codeview::LineFlags::HaveColumns) : 0, 2); + OS.EmitIntValue(HaveColumns ? int(LineFlags::HaveColumns) : 0, 2); OS.emitAbsoluteSymbolDiff(FuncEnd, FuncBegin, 4); for (auto I = Locs.begin(), E = Locs.end(); I != E;) { @@ -180,7 +181,7 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS, OS.emitAbsoluteSymbolDiff(J->getLabel(), FuncBegin, 4); unsigned LineData = J->getLine(); if (J->isStmt()) - LineData |= codeview::LineInfo::StatementFlag; + LineData |= LineInfo::StatementFlag; OS.EmitIntValue(LineData, 4); } if (HaveColumns) { @@ -194,6 +195,73 @@ void CodeViewContext::emitLineTableForFunction(MCObjectStreamer &OS, OS.EmitLabel(LineEnd); } +static bool compressAnnotation(uint32_t Data, SmallVectorImpl<char> &Buffer) { + if (isUInt<7>(Data)) { + Buffer.push_back(Data); + return true; + } + + if (isUInt<14>(Data)) { + Buffer.push_back((Data >> 8) | 0x80); + Buffer.push_back(Data & 0xff); + return true; + } + + if (isUInt<29>(Data)) { + Buffer.push_back((Data >> 24) | 0xC0); + Buffer.push_back((Data >> 16) & 0xff); + Buffer.push_back((Data >> 8) & 0xff); + Buffer.push_back(Data & 0xff); + return true; + } + + return false; +} + +static uint32_t encodeSignedNumber(uint32_t Data) { + if (Data >> 31) + return ((-Data) << 1) | 1; + return Data << 1; +} + +void CodeViewContext::emitInlineLineTableForFunction( + MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId, + unsigned SourceLineNum, ArrayRef<unsigned> SecondaryFunctionIds) { + std::vector<MCCVLineEntry> Locs = getFunctionLineEntries(PrimaryFunctionId); + std::vector<std::pair<BinaryAnnotationsOpCode, uint32_t>> Annotations; + + const MCCVLineEntry *LastLoc = nullptr; + unsigned LastFileId = SourceFileId; + unsigned LastLineNum = SourceLineNum; + + for (const MCCVLineEntry &Loc : Locs) { + if (!LastLoc) { + // TODO ChangeCodeOffset + // TODO ChangeCodeLength + } + + if (Loc.getFileNum() != LastFileId) + Annotations.push_back({ChangeFile, Loc.getFileNum()}); + + if (Loc.getLine() != LastLineNum) + Annotations.push_back( + {ChangeLineOffset, encodeSignedNumber(Loc.getLine() - LastLineNum)}); + + LastLoc = &Loc; + LastFileId = Loc.getFileNum(); + LastLineNum = Loc.getLine(); + } + + SmallString<32> Buffer; + for (auto Annotation : Annotations) { + BinaryAnnotationsOpCode Opcode = Annotation.first; + uint32_t Operand = Annotation.second; + compressAnnotation(Opcode, Buffer); + compressAnnotation(Operand, Buffer); + } + OS.EmitBytes(Buffer); +} + // // This is called when an instruction is assembled into the specified section // and if there is information from the last .cv_loc directive that has yet to have |