summaryrefslogtreecommitdiff
path: root/include/llvm/MC/MCCodeView.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/MC/MCCodeView.h')
-rw-r--r--include/llvm/MC/MCCodeView.h210
1 files changed, 210 insertions, 0 deletions
diff --git a/include/llvm/MC/MCCodeView.h b/include/llvm/MC/MCCodeView.h
new file mode 100644
index 0000000000000..d999ff5559970
--- /dev/null
+++ b/include/llvm/MC/MCCodeView.h
@@ -0,0 +1,210 @@
+//===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Holds state from .cv_file and .cv_loc directives for later emission.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEVIEW_H
+#define LLVM_MC_MCCODEVIEW_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/MC/MCObjectStreamer.h"
+#include "llvm/MC/MCFragment.h"
+#include <map>
+#include <vector>
+
+namespace llvm {
+class MCContext;
+class MCObjectStreamer;
+class MCStreamer;
+
+/// \brief Instances of this class represent the information from a
+/// .cv_loc directive.
+class MCCVLoc {
+ uint32_t FunctionId;
+ uint32_t FileNum;
+ uint32_t Line;
+ uint16_t Column;
+ uint16_t PrologueEnd : 1;
+ uint16_t IsStmt : 1;
+
+private: // MCContext manages these
+ friend class MCContext;
+ MCCVLoc(unsigned functionid, unsigned fileNum, unsigned line, unsigned column,
+ bool prologueend, bool isstmt)
+ : FunctionId(functionid), FileNum(fileNum), Line(line), Column(column),
+ PrologueEnd(prologueend), IsStmt(isstmt) {}
+
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCCVLoc object.
+
+public:
+ unsigned getFunctionId() const { return FunctionId; }
+
+ /// \brief Get the FileNum of this MCCVLoc.
+ unsigned getFileNum() const { return FileNum; }
+
+ /// \brief Get the Line of this MCCVLoc.
+ unsigned getLine() const { return Line; }
+
+ /// \brief Get the Column of this MCCVLoc.
+ unsigned getColumn() const { return Column; }
+
+ bool isPrologueEnd() const { return PrologueEnd; }
+ bool isStmt() const { return IsStmt; }
+
+ void setFunctionId(unsigned FID) { FunctionId = FID; }
+
+ /// \brief Set the FileNum of this MCCVLoc.
+ void setFileNum(unsigned fileNum) { FileNum = fileNum; }
+
+ /// \brief Set the Line of this MCCVLoc.
+ void setLine(unsigned line) { Line = line; }
+
+ /// \brief Set the Column of this MCCVLoc.
+ void setColumn(unsigned column) {
+ assert(column <= UINT16_MAX);
+ Column = column;
+ }
+
+ void setPrologueEnd(bool PE) { PrologueEnd = PE; }
+ void setIsStmt(bool IS) { IsStmt = IS; }
+};
+
+/// \brief Instances of this class represent the line information for
+/// the CodeView line table entries. Which is created after a machine
+/// instruction is assembled and uses an address from a temporary label
+/// created at the current address in the current section and the info from
+/// the last .cv_loc directive seen as stored in the context.
+class MCCVLineEntry : public MCCVLoc {
+ const MCSymbol *Label;
+
+private:
+ // Allow the default copy constructor and assignment operator to be used
+ // for an MCCVLineEntry object.
+
+public:
+ // Constructor to create an MCCVLineEntry given a symbol and the dwarf loc.
+ MCCVLineEntry(const MCSymbol *Label, const MCCVLoc loc)
+ : MCCVLoc(loc), Label(Label) {}
+
+ const MCSymbol *getLabel() const { return Label; }
+
+ // 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 a line entry made for it is made.
+ static void Make(MCObjectStreamer *MCOS);
+};
+
+/// Holds state from .cv_file and .cv_loc directives for later emission.
+class CodeViewContext {
+public:
+ CodeViewContext();
+ ~CodeViewContext();
+
+ bool isValidFileNumber(unsigned FileNumber) const;
+ bool addFile(unsigned FileNumber, StringRef Filename);
+ ArrayRef<StringRef> getFilenames() { return Filenames; }
+
+ /// \brief Add a line entry.
+ void addLineEntry(const MCCVLineEntry &LineEntry) {
+ size_t Offset = MCCVLines.size();
+ auto I = MCCVLineStartStop.insert(
+ {LineEntry.getFunctionId(), {Offset, Offset + 1}});
+ if (!I.second)
+ I.first->second.second = Offset + 1;
+ MCCVLines.push_back(LineEntry);
+ }
+
+ std::vector<MCCVLineEntry> getFunctionLineEntries(unsigned FuncId) {
+ std::vector<MCCVLineEntry> FilteredLines;
+
+ auto I = MCCVLineStartStop.find(FuncId);
+ if (I != MCCVLineStartStop.end())
+ for (size_t Idx = I->second.first, End = I->second.second; Idx != End;
+ ++Idx)
+ if (MCCVLines[Idx].getFunctionId() == FuncId)
+ FilteredLines.push_back(MCCVLines[Idx]);
+ return FilteredLines;
+ }
+
+ std::pair<size_t, size_t> getLineExtent(unsigned FuncId) {
+ auto I = MCCVLineStartStop.find(FuncId);
+ // Return an empty extent if there are no cv_locs for this function id.
+ if (I == MCCVLineStartStop.end())
+ return {~0ULL, 0};
+ return I->second;
+ }
+
+ ArrayRef<MCCVLineEntry> getLinesForExtent(size_t L, size_t R) {
+ if (R <= L)
+ return None;
+ if (L >= MCCVLines.size())
+ return None;
+ return makeArrayRef(&MCCVLines[L], R - L);
+ }
+
+ /// Emits a line table substream.
+ void emitLineTableForFunction(MCObjectStreamer &OS, unsigned FuncId,
+ const MCSymbol *FuncBegin,
+ const MCSymbol *FuncEnd);
+
+ void emitInlineLineTableForFunction(
+ MCObjectStreamer &OS, unsigned PrimaryFunctionId, unsigned SourceFileId,
+ unsigned SourceLineNum, const MCSymbol *FnStartSym,
+ const MCSymbol *FnEndSym, ArrayRef<unsigned> SecondaryFunctionIds);
+
+ /// Encodes the binary annotations once we have a layout.
+ void encodeInlineLineTable(MCAsmLayout &Layout,
+ MCCVInlineLineTableFragment &F);
+
+ void
+ emitDefRange(MCObjectStreamer &OS,
+ ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
+ StringRef FixedSizePortion);
+
+ void encodeDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &F);
+
+ /// Emits the string table substream.
+ void emitStringTable(MCObjectStreamer &OS);
+
+ /// Emits the file checksum substream.
+ void emitFileChecksums(MCObjectStreamer &OS);
+
+private:
+ /// Map from string to string table offset.
+ StringMap<unsigned> StringTable;
+
+ /// The fragment that ultimately holds our strings.
+ MCDataFragment *StrTabFragment = nullptr;
+ bool InsertedStrTabFragment = false;
+
+ MCDataFragment *getStringTableFragment();
+
+ /// Add something to the string table.
+ StringRef addToStringTable(StringRef S);
+
+ /// Get a string table offset.
+ unsigned getStringTableOffset(StringRef S);
+
+ /// An array of absolute paths. Eventually this may include the file checksum.
+ SmallVector<StringRef, 4> Filenames;
+
+ /// The offset of the first and last .cv_loc directive for a given function
+ /// id.
+ std::map<unsigned, std::pair<size_t, size_t>> MCCVLineStartStop;
+
+ /// A collection of MCCVLineEntry for each section.
+ std::vector<MCCVLineEntry> MCCVLines;
+};
+
+} // end namespace llvm
+#endif