forked from OSchip/llvm-project
[BOLT][DWARF] Move line info emission into BOLT
Summary: BOLT needs to generate line info tables using absolute addresses as well as using the standard MC way of labels attached to instructions. Move line table generation code under BOLT. Ideally, we should be able to extend existing interfaces in LLVM, but without other users of the interface it will be hard to justify the change. (cherry picked from FBD30723466)
This commit is contained in:
parent
ba1f503f1b
commit
d4a0e8526a
|
@ -1396,6 +1396,16 @@ void BinaryContext::printGlobalSymbols(raw_ostream& OS) const {
|
|||
}
|
||||
}
|
||||
|
||||
Expected<unsigned>
|
||||
BinaryContext::getDwarfFile(StringRef Directory, StringRef FileName,
|
||||
unsigned FileNumber,
|
||||
Optional<MD5::MD5Result> Checksum,
|
||||
Optional<StringRef> Source, unsigned CUID) {
|
||||
DwarfLineTable &Table = DwarfLineTablesCUMap[CUID];
|
||||
return Table.tryGetFile(Directory, FileName, Checksum, Source,
|
||||
Ctx->getDwarfVersion(), FileNumber);
|
||||
}
|
||||
|
||||
unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
|
||||
const uint32_t SrcCUID,
|
||||
unsigned FileIndex) {
|
||||
|
@ -1421,7 +1431,7 @@ unsigned BinaryContext::addDebugFilenameToUnit(const uint32_t DestCUID,
|
|||
dwarf::toString(FileNames[FileIndex - 1].Name))
|
||||
FileName = *FName;
|
||||
assert(FileName != "");
|
||||
return cantFail(Ctx->getDwarfFile(Dir, FileName, 0, None, None, DestCUID));
|
||||
return cantFail(getDwarfFile(Dir, FileName, 0, None, None, DestCUID));
|
||||
}
|
||||
|
||||
std::vector<BinaryFunction *> BinaryContext::getSortedFunctions() {
|
||||
|
@ -1545,12 +1555,12 @@ void BinaryContext::preprocessDebugInfo() {
|
|||
LineTable->Prologue.FileNames;
|
||||
|
||||
// Assign a unique label to every line table, one per CU.
|
||||
Ctx->getMCDwarfLineTable(CUID).setLabel(
|
||||
Ctx->getOrCreateSymbol(GlobalPrefix + "line_table_start" + Twine(CUID)));
|
||||
getDwarfLineTable(CUID).setLabel(Ctx->getOrCreateSymbol(
|
||||
GlobalPrefix + "line_table_start" + Twine(CUID)));
|
||||
|
||||
// Make sure empty debug line tables are registered too.
|
||||
if (FileNames.empty()) {
|
||||
cantFail(Ctx->getDwarfFile("", "<unknown>", 0, None, None, CUID));
|
||||
cantFail(getDwarfFile("", "<unknown>", 0, None, None, CUID));
|
||||
continue;
|
||||
}
|
||||
for (size_t I = 0, Size = FileNames.size(); I != Size; ++I) {
|
||||
|
@ -1566,7 +1576,7 @@ void BinaryContext::preprocessDebugInfo() {
|
|||
if (Optional<const char *> FName = dwarf::toString(FileNames[I].Name))
|
||||
FileName = *FName;
|
||||
assert(FileName != "");
|
||||
cantFail(Ctx->getDwarfFile(Dir, FileName, 0, None, None, CUID));
|
||||
cantFail(getDwarfFile(Dir, FileName, 0, None, None, CUID));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCObjectFileInfo.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
|
@ -207,6 +208,9 @@ class BinaryContext {
|
|||
/// Preprocess DWO debug information.
|
||||
void preprocessDWODebugInfo();
|
||||
|
||||
/// DWARF line info for CUs.
|
||||
std::map<unsigned, DwarfLineTable> DwarfLineTablesCUMap;
|
||||
|
||||
public:
|
||||
static std::unique_ptr<BinaryContext>
|
||||
createBinaryContext(const ObjectFile *File, bool IsPIC,
|
||||
|
@ -221,6 +225,19 @@ public:
|
|||
/// Get Number of DWOCUs in a map.
|
||||
uint32_t getNumDWOCUs() { return DWOCUs.size(); }
|
||||
|
||||
const std::map<unsigned, DwarfLineTable> &getDwarfLineTables() const {
|
||||
return DwarfLineTablesCUMap;
|
||||
}
|
||||
|
||||
DwarfLineTable &getDwarfLineTable(unsigned CUID) {
|
||||
return DwarfLineTablesCUMap[CUID];
|
||||
}
|
||||
|
||||
Expected<unsigned> getDwarfFile(StringRef Directory, StringRef FileName,
|
||||
unsigned FileNumber,
|
||||
Optional<MD5::MD5Result> Checksum,
|
||||
Optional<StringRef> Source, unsigned CUID);
|
||||
|
||||
/// [start memory address] -> [segment info] mapping.
|
||||
std::map<uint64_t, SegmentInfo> SegmentMapInfo;
|
||||
|
||||
|
|
|
@ -210,8 +210,10 @@ void BinaryEmitter::emitAll(StringRef OrgSecPrefix) {
|
|||
|
||||
emitFunctions();
|
||||
|
||||
if (opts::UpdateDebugSections)
|
||||
if (opts::UpdateDebugSections) {
|
||||
emitDebugLineInfoForOriginalFunctions();
|
||||
DwarfLineTable::emit(BC, Streamer);
|
||||
}
|
||||
|
||||
emitDataSections(OrgSecPrefix);
|
||||
|
||||
|
@ -654,7 +656,16 @@ SMLoc BinaryEmitter::emitLineInfo(const BinaryFunction &BF, SMLoc NewLoc,
|
|||
Flags,
|
||||
CurrentRow.Isa,
|
||||
CurrentRow.Discriminator);
|
||||
BC.Ctx->setDwarfCompileUnitID(FunctionUnitIndex);
|
||||
const MCDwarfLoc &DwarfLoc = BC.Ctx->getCurrentDwarfLoc();
|
||||
BC.Ctx->clearDwarfLocSeen();
|
||||
|
||||
MCSymbol *LineSym = BC.Ctx->createTempSymbol();
|
||||
Streamer.emitLabel(LineSym);
|
||||
|
||||
BC.getDwarfLineTable(FunctionUnitIndex)
|
||||
.getMCLineSections()
|
||||
.addLineEntry(MCDwarfLineEntry(LineSym, DwarfLoc),
|
||||
Streamer.getCurrentSectionOnly());
|
||||
|
||||
return NewLoc;
|
||||
}
|
||||
|
@ -1010,34 +1021,30 @@ void BinaryEmitter::emitDebugLineInfoForOriginalFunctions() {
|
|||
uint64_t Address = It.first;
|
||||
if (LineTable->lookupAddressRange({Address, 0}, Function.getMaxSize(),
|
||||
Results)) {
|
||||
MCLineSection &OutputLineTable =
|
||||
BC.Ctx->getMCDwarfLineTable(Unit->getOffset()).getMCLineSections();
|
||||
BinaryLineSection &OutputLineTable =
|
||||
BC.getDwarfLineTable(Unit->getOffset()).getBinaryLineSections();
|
||||
for (uint32_t RowIndex : Results) {
|
||||
const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
|
||||
BC.Ctx->setCurrentDwarfLoc(
|
||||
Row.File,
|
||||
Row.Line,
|
||||
Row.Column,
|
||||
Row.File, Row.Line, Row.Column,
|
||||
(DWARF2_FLAG_IS_STMT * Row.IsStmt) |
|
||||
(DWARF2_FLAG_BASIC_BLOCK * Row.BasicBlock) |
|
||||
(DWARF2_FLAG_PROLOGUE_END * Row.PrologueEnd) |
|
||||
(DWARF2_FLAG_EPILOGUE_BEGIN * Row.EpilogueBegin),
|
||||
Row.Isa,
|
||||
Row.Discriminator,
|
||||
Row.Address.Address);
|
||||
(DWARF2_FLAG_BASIC_BLOCK * Row.BasicBlock) |
|
||||
(DWARF2_FLAG_PROLOGUE_END * Row.PrologueEnd) |
|
||||
(DWARF2_FLAG_EPILOGUE_BEGIN * Row.EpilogueBegin),
|
||||
Row.Isa, Row.Discriminator);
|
||||
MCDwarfLoc Loc = BC.Ctx->getCurrentDwarfLoc();
|
||||
BC.Ctx->clearDwarfLocSeen();
|
||||
OutputLineTable.addLineEntry(MCDwarfLineEntry{nullptr, Loc},
|
||||
FunctionSection);
|
||||
OutputLineTable.addLineEntry(
|
||||
BinaryDwarfLineEntry{Row.Address.Address, Loc}, FunctionSection);
|
||||
}
|
||||
// Add an empty entry past the end of the function
|
||||
// for end_sequence mark.
|
||||
BC.Ctx->setCurrentDwarfLoc(0, 0, 0, 0, 0, 0,
|
||||
Address + Function.getMaxSize());
|
||||
BC.Ctx->setCurrentDwarfLoc(0, 0, 0, 0, 0, 0);
|
||||
MCDwarfLoc Loc = BC.Ctx->getCurrentDwarfLoc();
|
||||
BC.Ctx->clearDwarfLocSeen();
|
||||
OutputLineTable.addLineEntry(MCDwarfLineEntry{nullptr, Loc},
|
||||
FunctionSection);
|
||||
OutputLineTable.addLineEntry(
|
||||
BinaryDwarfLineEntry{Address + Function.getMaxSize(), Loc},
|
||||
FunctionSection);
|
||||
} else {
|
||||
LLVM_DEBUG(dbgs() << "BOLT-DEBUG: function " << Function
|
||||
<< " has no associated line number information\n");
|
||||
|
|
|
@ -705,7 +705,7 @@ void DWARFRewriter::updateLineTableOffsets() {
|
|||
|
||||
for (const std::unique_ptr<DWARFUnit> &CU : BC.DwCtx->compile_units()) {
|
||||
const unsigned CUID = CU->getOffset();
|
||||
MCSymbol *Label = BC.Ctx->getMCDwarfLineTable(CUID).getLabel();
|
||||
MCSymbol *Label = BC.getDwarfLineTable(CUID).getLabel();
|
||||
if (!Label)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "BinaryBasicBlock.h"
|
||||
#include "BinaryFunction.h"
|
||||
|
||||
#include "llvm/MC/MCObjectStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/EndianStream.h"
|
||||
|
@ -522,5 +523,204 @@ std::unique_ptr<DebugBufferVector> DebugAbbrevWriter::finalize() {
|
|||
return std::make_unique<DebugBufferVector>(ReturnBuffer);
|
||||
}
|
||||
|
||||
static void emitDwarfSetLineAddrAbs(MCStreamer &OS,
|
||||
MCDwarfLineTableParams Params,
|
||||
int64_t LineDelta, uint64_t Address,
|
||||
int PointerSize) {
|
||||
// emit the sequence to set the address
|
||||
OS.emitIntValue(dwarf::DW_LNS_extended_op, 1);
|
||||
OS.emitULEB128IntValue(PointerSize + 1);
|
||||
OS.emitIntValue(dwarf::DW_LNE_set_address, 1);
|
||||
OS.emitIntValue(Address, PointerSize);
|
||||
|
||||
// emit the sequence for the LineDelta (from 1) and a zero address delta.
|
||||
MCDwarfLineAddr::Emit(&OS, Params, LineDelta, 0);
|
||||
}
|
||||
|
||||
static inline void emitBinaryDwarfLineTable(
|
||||
MCStreamer *MCOS, MCDwarfLineTableParams Params,
|
||||
const BinaryLineSection::BinaryDwarfLineEntryCollection &LineEntries) {
|
||||
unsigned FileNum = 1;
|
||||
unsigned LastLine = 1;
|
||||
unsigned Column = 0;
|
||||
unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
|
||||
unsigned Isa = 0;
|
||||
unsigned Discriminator = 0;
|
||||
uint64_t LastAddress = -1ULL;
|
||||
const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
|
||||
|
||||
// Loop through each line entry and encode the dwarf line number table.
|
||||
for (auto It = LineEntries.begin(), Ie = LineEntries.end(); It != Ie; ++It) {
|
||||
const BinaryDwarfLineEntry &LineEntry = *It;
|
||||
int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
|
||||
|
||||
const uint64_t Address = LineEntry.getAddress();
|
||||
if (std::next(It) == Ie) {
|
||||
// If emitting absolute addresses, the last entry only carries address
|
||||
// info for the DW_LNE_end_sequence. This entry compensates for the lack
|
||||
// of the section context used to emit the end of section label.
|
||||
MCDwarfLineAddr::Emit(MCOS, Params, INT64_MAX, Address - LastAddress);
|
||||
return;
|
||||
}
|
||||
|
||||
if (FileNum != LineEntry.getFileNum()) {
|
||||
FileNum = LineEntry.getFileNum();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_file);
|
||||
MCOS->emitULEB128IntValue(FileNum);
|
||||
}
|
||||
if (Column != LineEntry.getColumn()) {
|
||||
Column = LineEntry.getColumn();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_column);
|
||||
MCOS->emitULEB128IntValue(Column);
|
||||
}
|
||||
if (Discriminator != LineEntry.getDiscriminator() &&
|
||||
MCOS->getContext().getDwarfVersion() >= 4) {
|
||||
Discriminator = LineEntry.getDiscriminator();
|
||||
unsigned Size = getULEB128Size(Discriminator);
|
||||
MCOS->emitInt8(dwarf::DW_LNS_extended_op);
|
||||
MCOS->emitULEB128IntValue(Size + 1);
|
||||
MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
|
||||
MCOS->emitULEB128IntValue(Discriminator);
|
||||
}
|
||||
if (Isa != LineEntry.getIsa()) {
|
||||
Isa = LineEntry.getIsa();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_isa);
|
||||
MCOS->emitULEB128IntValue(Isa);
|
||||
}
|
||||
if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
|
||||
Flags = LineEntry.getFlags();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
|
||||
}
|
||||
if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
|
||||
if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
|
||||
if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
|
||||
|
||||
if (LastAddress == -1ULL) {
|
||||
emitDwarfSetLineAddrAbs(*MCOS, Params, LineDelta, Address,
|
||||
AsmInfo->getCodePointerSize());
|
||||
} else {
|
||||
MCDwarfLineAddr::Emit(MCOS, Params, LineDelta, Address - LastAddress);
|
||||
}
|
||||
LastAddress = Address;
|
||||
|
||||
Discriminator = 0;
|
||||
LastLine = LineEntry.getLine();
|
||||
}
|
||||
}
|
||||
|
||||
static inline void emitDwarfLineTable(
|
||||
MCStreamer *MCOS, MCSection *Section,
|
||||
const MCLineSection::MCDwarfLineEntryCollection &LineEntries) {
|
||||
unsigned FileNum = 1;
|
||||
unsigned LastLine = 1;
|
||||
unsigned Column = 0;
|
||||
unsigned Flags = DWARF2_LINE_DEFAULT_IS_STMT ? DWARF2_FLAG_IS_STMT : 0;
|
||||
unsigned Isa = 0;
|
||||
unsigned Discriminator = 0;
|
||||
MCSymbol *LastLabel = nullptr;
|
||||
const MCAsmInfo *AsmInfo = MCOS->getContext().getAsmInfo();
|
||||
|
||||
// Loop through each MCDwarfLineEntry and encode the dwarf line number table.
|
||||
for (const MCDwarfLineEntry &LineEntry : LineEntries) {
|
||||
int64_t LineDelta = static_cast<int64_t>(LineEntry.getLine()) - LastLine;
|
||||
|
||||
if (FileNum != LineEntry.getFileNum()) {
|
||||
FileNum = LineEntry.getFileNum();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_file);
|
||||
MCOS->emitULEB128IntValue(FileNum);
|
||||
}
|
||||
if (Column != LineEntry.getColumn()) {
|
||||
Column = LineEntry.getColumn();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_column);
|
||||
MCOS->emitULEB128IntValue(Column);
|
||||
}
|
||||
if (Discriminator != LineEntry.getDiscriminator() &&
|
||||
MCOS->getContext().getDwarfVersion() >= 4) {
|
||||
Discriminator = LineEntry.getDiscriminator();
|
||||
unsigned Size = getULEB128Size(Discriminator);
|
||||
MCOS->emitInt8(dwarf::DW_LNS_extended_op);
|
||||
MCOS->emitULEB128IntValue(Size + 1);
|
||||
MCOS->emitInt8(dwarf::DW_LNE_set_discriminator);
|
||||
MCOS->emitULEB128IntValue(Discriminator);
|
||||
}
|
||||
if (Isa != LineEntry.getIsa()) {
|
||||
Isa = LineEntry.getIsa();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_isa);
|
||||
MCOS->emitULEB128IntValue(Isa);
|
||||
}
|
||||
if ((LineEntry.getFlags() ^ Flags) & DWARF2_FLAG_IS_STMT) {
|
||||
Flags = LineEntry.getFlags();
|
||||
MCOS->emitInt8(dwarf::DW_LNS_negate_stmt);
|
||||
}
|
||||
if (LineEntry.getFlags() & DWARF2_FLAG_BASIC_BLOCK)
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_basic_block);
|
||||
if (LineEntry.getFlags() & DWARF2_FLAG_PROLOGUE_END)
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_prologue_end);
|
||||
if (LineEntry.getFlags() & DWARF2_FLAG_EPILOGUE_BEGIN)
|
||||
MCOS->emitInt8(dwarf::DW_LNS_set_epilogue_begin);
|
||||
|
||||
MCSymbol *Label = LineEntry.getLabel();
|
||||
|
||||
// At this point we want to emit/create the sequence to encode the delta
|
||||
// in line numbers and the increment of the address from the previous
|
||||
// Label and the current Label.
|
||||
MCOS->emitDwarfAdvanceLineAddr(LineDelta, LastLabel, Label,
|
||||
AsmInfo->getCodePointerSize());
|
||||
Discriminator = 0;
|
||||
LastLine = LineEntry.getLine();
|
||||
LastLabel = Label;
|
||||
}
|
||||
|
||||
// Generate DWARF line end entry.
|
||||
MCOS->emitDwarfLineEndEntry(Section, LastLabel);
|
||||
}
|
||||
|
||||
void DwarfLineTable::emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
|
||||
Optional<MCDwarfLineStr> &LineStr) const {
|
||||
MCSymbol *LineEndSym = Header.Emit(MCOS, Params, LineStr).second;
|
||||
|
||||
// Put out the line tables.
|
||||
for (const auto &LineSec : MCLineSections.getMCLineEntries())
|
||||
emitDwarfLineTable(MCOS, LineSec.first, LineSec.second);
|
||||
|
||||
// Emit line tables for the original code.
|
||||
for (const auto &LineSec : BinaryLineSections.getBinaryLineEntries())
|
||||
emitBinaryDwarfLineTable(MCOS, Params, LineSec.second);
|
||||
|
||||
// This is the end of the section, so set the value of the symbol at the end
|
||||
// of this section (that was used in a previous expression).
|
||||
MCOS->emitLabel(LineEndSym);
|
||||
}
|
||||
|
||||
void DwarfLineTable::emit(BinaryContext &BC, MCStreamer &Streamer) {
|
||||
MCAssembler &Assembler =
|
||||
static_cast<MCObjectStreamer *>(&Streamer)->getAssembler();
|
||||
|
||||
MCDwarfLineTableParams Params = Assembler.getDWARFLinetableParams();
|
||||
|
||||
auto &LineTables = BC.getDwarfLineTables();
|
||||
|
||||
// Bail out early so we don't switch to the debug_line section needlessly and
|
||||
// in doing so create an unnecessary (if empty) section.
|
||||
if (LineTables.empty())
|
||||
return;
|
||||
|
||||
// In a v5 non-split line table, put the strings in a separate section.
|
||||
Optional<MCDwarfLineStr> LineStr(None);
|
||||
if (BC.Ctx->getDwarfVersion() >= 5)
|
||||
LineStr = MCDwarfLineStr(*BC.Ctx);
|
||||
|
||||
// Switch to the section where the table will be emitted into.
|
||||
Streamer.SwitchSection(BC.MOFI->getDwarfLineSection());
|
||||
|
||||
// Handle the rest of the Compile Units.
|
||||
for (auto &CUIDTablePair : LineTables) {
|
||||
CUIDTablePair.second.emitCU(&Streamer, Params, LineStr);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
|
||||
#include "llvm/MC/MCDwarf.h"
|
||||
#include "llvm/Support/SMLoc.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cstdint>
|
||||
|
@ -497,6 +498,76 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// Similar to MCDwarfLineEntry, but identifies the location by its address
|
||||
/// instead of MCLabel.
|
||||
class BinaryDwarfLineEntry : public MCDwarfLoc {
|
||||
uint64_t Address;
|
||||
|
||||
public:
|
||||
// Constructor to create an BinaryDwarfLineEntry given a symbol and the dwarf
|
||||
// loc.
|
||||
BinaryDwarfLineEntry(uint64_t Address, const MCDwarfLoc loc)
|
||||
: MCDwarfLoc(loc), Address(Address) {}
|
||||
|
||||
uint64_t getAddress() const { return Address; }
|
||||
};
|
||||
|
||||
/// Similar to MCLineSection, store line entries per CU but use absolute
|
||||
/// addresses for line locations.
|
||||
class BinaryLineSection {
|
||||
public:
|
||||
// Add an entry to this MCLineSection's line entries.
|
||||
void addLineEntry(const BinaryDwarfLineEntry &LineEntry, MCSection *Sec) {
|
||||
BinaryLineDivisions[Sec].push_back(LineEntry);
|
||||
}
|
||||
|
||||
using BinaryDwarfLineEntryCollection = std::vector<BinaryDwarfLineEntry>;
|
||||
using BinaryLineDivisionMap =
|
||||
MapVector<MCSection *, BinaryDwarfLineEntryCollection>;
|
||||
|
||||
private:
|
||||
// A collection of BinaryDwarfLineEntry for each section.
|
||||
BinaryLineDivisionMap BinaryLineDivisions;
|
||||
|
||||
public:
|
||||
// Returns the collection of BinaryDwarfLineEntry for a given Compile Unit ID.
|
||||
const BinaryLineDivisionMap &getBinaryLineEntries() const {
|
||||
return BinaryLineDivisions;
|
||||
}
|
||||
};
|
||||
|
||||
/// Line number information for all parts of the binary.
|
||||
class DwarfLineTable {
|
||||
MCDwarfLineTableHeader Header;
|
||||
MCLineSection MCLineSections;
|
||||
BinaryLineSection BinaryLineSections;
|
||||
|
||||
public:
|
||||
/// Emit line info for all units in the binary context.
|
||||
static void emit(BinaryContext &BC, MCStreamer &Streamer);
|
||||
|
||||
// Emit the Dwarf file and the line tables for a given CU.
|
||||
void emitCU(MCStreamer *MCOS, MCDwarfLineTableParams Params,
|
||||
Optional<MCDwarfLineStr> &LineStr) const;
|
||||
|
||||
Expected<unsigned> tryGetFile(StringRef &Directory, StringRef &FileName,
|
||||
Optional<MD5::MD5Result> Checksum,
|
||||
Optional<StringRef> Source,
|
||||
uint16_t DwarfVersion,
|
||||
unsigned FileNumber = 0) {
|
||||
return Header.tryGetFile(Directory, FileName, Checksum, Source,
|
||||
DwarfVersion, FileNumber);
|
||||
}
|
||||
|
||||
MCSymbol *getLabel() const { return Header.Label; }
|
||||
|
||||
void setLabel(MCSymbol *Label) { Header.Label = Label; }
|
||||
|
||||
MCLineSection &getMCLineSections() { return MCLineSections; }
|
||||
|
||||
BinaryLineSection &getBinaryLineSections() { return BinaryLineSections; }
|
||||
};
|
||||
|
||||
} // namespace bolt
|
||||
} // namespace llvm
|
||||
|
||||
|
|
Loading…
Reference in New Issue