mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 12:12:47 +01:00
db5a260b9c
Notes: * llvm::createAsmStreamer: it has been moved to TargetRegistry.h * (anon ns)::WasmObjectWriter::updateCustomSectionRelocations: remnant of D46335 * COFFAsmParser::ParseSEHRegisterNumber: remnant of D66625 * llvm::CodeViewContext::isValidCVFileNumber: accidentally added by r279847
263 lines
9.0 KiB
C++
263 lines
9.0 KiB
C++
//===- MCCodeView.h - Machine Code CodeView support -------------*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// 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/StringMap.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/MC/MCFragment.h"
|
|
#include "llvm/MC/MCObjectStreamer.h"
|
|
#include <map>
|
|
#include <vector>
|
|
|
|
namespace llvm {
|
|
class MCContext;
|
|
class MCObjectStreamer;
|
|
class MCStreamer;
|
|
class CodeViewContext;
|
|
|
|
/// Instances of this class represent the information from a
|
|
/// .cv_loc directive.
|
|
class MCCVLoc {
|
|
const MCSymbol *Label = nullptr;
|
|
uint32_t FunctionId;
|
|
uint32_t FileNum;
|
|
uint32_t Line;
|
|
uint16_t Column;
|
|
uint16_t PrologueEnd : 1;
|
|
uint16_t IsStmt : 1;
|
|
|
|
private: // CodeViewContext manages these
|
|
friend class CodeViewContext;
|
|
MCCVLoc(const MCSymbol *Label, unsigned functionid, unsigned fileNum,
|
|
unsigned line, unsigned column, bool prologueend, bool isstmt)
|
|
: Label(Label), 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:
|
|
const MCSymbol *getLabel() const { return Label; }
|
|
|
|
unsigned getFunctionId() const { return FunctionId; }
|
|
|
|
/// Get the FileNum of this MCCVLoc.
|
|
unsigned getFileNum() const { return FileNum; }
|
|
|
|
/// Get the Line of this MCCVLoc.
|
|
unsigned getLine() const { return Line; }
|
|
|
|
/// Get the Column of this MCCVLoc.
|
|
unsigned getColumn() const { return Column; }
|
|
|
|
bool isPrologueEnd() const { return PrologueEnd; }
|
|
bool isStmt() const { return IsStmt; }
|
|
|
|
void setLabel(const MCSymbol *L) { Label = L; }
|
|
|
|
void setFunctionId(unsigned FID) { FunctionId = FID; }
|
|
|
|
/// Set the FileNum of this MCCVLoc.
|
|
void setFileNum(unsigned fileNum) { FileNum = fileNum; }
|
|
|
|
/// Set the Line of this MCCVLoc.
|
|
void setLine(unsigned line) { Line = line; }
|
|
|
|
/// 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; }
|
|
};
|
|
|
|
/// Information describing a function or inlined call site introduced by
|
|
/// .cv_func_id or .cv_inline_site_id. Accumulates information from .cv_loc
|
|
/// directives used with this function's id or the id of an inlined call site
|
|
/// within this function or inlined call site.
|
|
struct MCCVFunctionInfo {
|
|
/// If this represents an inlined call site, then ParentFuncIdPlusOne will be
|
|
/// the parent function id plus one. If this represents a normal function,
|
|
/// then there is no parent, and ParentFuncIdPlusOne will be FunctionSentinel.
|
|
/// If this struct is an unallocated slot in the function info vector, then
|
|
/// ParentFuncIdPlusOne will be zero.
|
|
unsigned ParentFuncIdPlusOne = 0;
|
|
|
|
enum : unsigned { FunctionSentinel = ~0U };
|
|
|
|
struct LineInfo {
|
|
unsigned File;
|
|
unsigned Line;
|
|
unsigned Col;
|
|
};
|
|
|
|
LineInfo InlinedAt;
|
|
|
|
/// The section of the first .cv_loc directive used for this function, or null
|
|
/// if none has been seen yet.
|
|
MCSection *Section = nullptr;
|
|
|
|
/// Map from inlined call site id to the inlined at location to use for that
|
|
/// call site. Call chains are collapsed, so for the call chain 'f -> g -> h',
|
|
/// the InlinedAtMap of 'f' will contain entries for 'g' and 'h' that both
|
|
/// list the line info for the 'g' call site.
|
|
DenseMap<unsigned, LineInfo> InlinedAtMap;
|
|
|
|
/// Returns true if this is function info has not yet been used in a
|
|
/// .cv_func_id or .cv_inline_site_id directive.
|
|
bool isUnallocatedFunctionInfo() const { return ParentFuncIdPlusOne == 0; }
|
|
|
|
/// Returns true if this represents an inlined call site, meaning
|
|
/// ParentFuncIdPlusOne is neither zero nor ~0U.
|
|
bool isInlinedCallSite() const {
|
|
return !isUnallocatedFunctionInfo() &&
|
|
ParentFuncIdPlusOne != FunctionSentinel;
|
|
}
|
|
|
|
unsigned getParentFuncId() const {
|
|
assert(isInlinedCallSite());
|
|
return ParentFuncIdPlusOne - 1;
|
|
}
|
|
};
|
|
|
|
/// Holds state from .cv_file and .cv_loc directives for later emission.
|
|
class CodeViewContext {
|
|
public:
|
|
CodeViewContext();
|
|
~CodeViewContext();
|
|
|
|
bool isValidFileNumber(unsigned FileNumber) const;
|
|
bool addFile(MCStreamer &OS, unsigned FileNumber, StringRef Filename,
|
|
ArrayRef<uint8_t> ChecksumBytes, uint8_t ChecksumKind);
|
|
|
|
/// Records the function id of a normal function. Returns false if the
|
|
/// function id has already been used, and true otherwise.
|
|
bool recordFunctionId(unsigned FuncId);
|
|
|
|
/// Records the function id of an inlined call site. Records the "inlined at"
|
|
/// location info of the call site, including what function or inlined call
|
|
/// site it was inlined into. Returns false if the function id has already
|
|
/// been used, and true otherwise.
|
|
bool recordInlinedCallSiteId(unsigned FuncId, unsigned IAFunc,
|
|
unsigned IAFile, unsigned IALine,
|
|
unsigned IACol);
|
|
|
|
/// Retreive the function info if this is a valid function id, or nullptr.
|
|
MCCVFunctionInfo *getCVFunctionInfo(unsigned FuncId);
|
|
|
|
/// Saves the information from the currently parsed .cv_loc directive
|
|
/// and sets CVLocSeen. When the next instruction is assembled an entry
|
|
/// in the line number table with this information and the address of the
|
|
/// instruction will be created.
|
|
void recordCVLoc(MCContext &Ctx, const MCSymbol *Label, unsigned FunctionId,
|
|
unsigned FileNo, unsigned Line, unsigned Column,
|
|
bool PrologueEnd, bool IsStmt);
|
|
|
|
/// Add a line entry.
|
|
void addLineEntry(const MCCVLoc &LineEntry);
|
|
|
|
std::vector<MCCVLoc> getFunctionLineEntries(unsigned FuncId);
|
|
|
|
std::pair<size_t, size_t> getLineExtent(unsigned FuncId);
|
|
|
|
ArrayRef<MCCVLoc> getLinesForExtent(size_t L, size_t R);
|
|
|
|
/// 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);
|
|
|
|
/// Encodes the binary annotations once we have a layout.
|
|
void encodeInlineLineTable(MCAsmLayout &Layout,
|
|
MCCVInlineLineTableFragment &F);
|
|
|
|
MCFragment *
|
|
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);
|
|
|
|
/// Emits the offset into the checksum table of the given file number.
|
|
void emitFileChecksumOffset(MCObjectStreamer &OS, unsigned FileNo);
|
|
|
|
/// Add something to the string table. Returns the final string as well as
|
|
/// offset into the string table.
|
|
std::pair<StringRef, unsigned> addToStringTable(StringRef S);
|
|
|
|
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();
|
|
|
|
/// Get a string table offset.
|
|
unsigned getStringTableOffset(StringRef S);
|
|
|
|
struct FileInfo {
|
|
unsigned StringTableOffset;
|
|
|
|
// Indicates if this FileInfo corresponds to an actual file, or hasn't been
|
|
// set yet.
|
|
bool Assigned = false;
|
|
|
|
uint8_t ChecksumKind;
|
|
|
|
ArrayRef<uint8_t> Checksum;
|
|
|
|
// Checksum offset stored as a symbol because it might be requested
|
|
// before it has been calculated, so a fixup may be needed.
|
|
MCSymbol *ChecksumTableOffset;
|
|
};
|
|
|
|
/// Array storing added file information.
|
|
SmallVector<FileInfo, 4> Files;
|
|
|
|
/// 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 MCCVLoc for each section.
|
|
std::vector<MCCVLoc> MCCVLines;
|
|
|
|
/// All known functions and inlined call sites, indexed by function id.
|
|
std::vector<MCCVFunctionInfo> Functions;
|
|
|
|
/// Indicate whether we have already laid out the checksum table addresses or
|
|
/// not.
|
|
bool ChecksumOffsetsAssigned = false;
|
|
};
|
|
|
|
} // end namespace llvm
|
|
#endif
|