15 #include "llvm/Config/config.h"
34 #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
37 #define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255)
42 #define DWARF2_LINE_OPCODE_BASE 13
46 #define DWARF2_LINE_BASE -5
49 #define DWARF2_LINE_RANGE 14
53 if (MinInsnLength == 1)
55 if (AddrDelta % MinInsnLength != 0) {
59 return AddrDelta / MinInsnLength;
89 .addLineEntry(LineEntry, Section);
120 unsigned FileNum = 1;
121 unsigned LastLine = 1;
125 unsigned Discriminator = 0;
129 for (
auto it = LineEntries.begin(),
130 ie = LineEntries.end();
133 if (FileNum != it->getFileNum()) {
134 FileNum = it->getFileNum();
138 if (Column != it->getColumn()) {
139 Column = it->getColumn();
143 if (Discriminator != it->getDiscriminator()) {
144 Discriminator = it->getDiscriminator();
151 if (Isa != it->getIsa()) {
157 Flags = it->getFlags();
167 int64_t LineDelta =
static_cast<int64_t
>(it->getLine()) - LastLine;
177 LastLine = it->getLine();
207 if (LineTables.empty())
214 for (
const auto &CUIDTablePair : LineTables)
215 CUIDTablePair.second.EmitCU(MCOS);
223 static const char StandardOpcodeLengths[] = {
239 return Emit(MCOS, StandardOpcodeLengths);
244 assert(!isa<MCSymbolRefExpr>(Expr));
258 std::pair<MCSymbol *, MCSymbol *>
301 for (
char Length : StandardOpcodeLengths)
329 return std::make_pair(LineStartSym, LineEndSym);
345 unsigned FileNumber) {
346 return Header.
getFile(Directory, FileName, FileNumber);
351 unsigned FileNumber) {
354 if (FileName.
empty()) {
355 FileName =
"<stdin>";
358 assert(!FileName.
empty());
359 if (FileNumber == 0) {
362 "Don't mix autonumbered and explicit numbered line table usage");
367 if (!IterBool.second)
368 return IterBool.first->second;
377 if (!File.
Name.empty())
380 if (Directory.
empty()) {
383 if (!tFileName.
empty()) {
385 if (!Directory.
empty())
386 FileName = tFileName;
393 if (Directory.
empty()) {
411 File.
Name = FileName;
420 uint64_t AddrDelta) {
431 uint64_t Temp, Opcode;
432 bool NeedCopy =
false;
440 if (LineDelta == INT64_MAX) {
443 else if (AddrDelta) {
468 if (LineDelta == 0 && AddrDelta == 0) {
532 if (!DwarfDebugFlags.
empty())
564 const MCSymbol *InfoSectionSymbol) {
573 int Length = 4 + 2 + 4 + 1 + 1;
579 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
580 if (Pad == 2 * AddrSize)
586 Length += 2 * AddrSize * Sections.size();
588 Length += 2 * AddrSize;
598 if (InfoSectionSymbol)
608 for(
int i = 0; i < Pad; i++)
614 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
615 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
616 assert(StartSymbol &&
"StartSymbol must not be NULL");
617 assert(EndSymbol &&
"EndSymbol must not be NULL");
622 *StartSymbol, *EndSymbol, 0);
636 const MCSymbol *AbbrevSectionSymbol,
638 const MCSymbol *RangesSectionSymbol) {
662 if (AbbrevSectionSymbol ==
nullptr)
680 if (LineSectionSymbol)
686 if (RangesSectionSymbol) {
699 const auto TextSection = Sections.begin();
700 assert(TextSection != Sections.end() &&
"No text section found");
702 MCSymbol *StartSymbol = (*TextSection)->getBeginSymbol();
703 MCSymbol *EndSymbol = (*TextSection)->getEndSymbol(context);
704 assert(StartSymbol &&
"StartSymbol must not be NULL");
705 assert(EndSymbol &&
"EndSymbol must not be NULL");
721 if (MCDwarfDirs.
size() > 0) {
738 if (!DwarfDebugFlags.
empty()){
745 if (!DwarfDebugProducer.
empty())
758 const std::vector<MCGenDwarfLabelEntry> &Entries =
760 for (
const auto &Entry : Entries) {
809 const MCSymbol *StartSymbol = Sec->getBeginSymbol();
810 MCSymbol *EndSymbol = Sec->getEndSymbol(context);
811 assert(StartSymbol &&
"StartSymbol must not be NULL");
812 assert(EndSymbol &&
"EndSymbol must not be NULL");
818 MCOS->
EmitValue(SectionStartAddr, AddrSize);
822 *StartSymbol, *EndSymbol, 0);
841 bool CreateDwarfSectionSymbols =
843 MCSymbol *LineSectionSymbol =
nullptr;
844 if (CreateDwarfSectionSymbols)
846 MCSymbol *AbbrevSectionSymbol =
nullptr;
847 MCSymbol *InfoSectionSymbol =
nullptr;
848 MCSymbol *RangesSectionSymbol = NULL;
860 const bool UseRangesSection =
863 CreateDwarfSectionSymbols |= UseRangesSection;
866 if (CreateDwarfSectionSymbols) {
871 if (CreateDwarfSectionSymbols) {
875 if (UseRangesSection) {
877 if (CreateDwarfSectionSymbols) {
883 assert((RangesSectionSymbol != NULL) || !UseRangesSection);
890 if (UseRangesSection)
898 RangesSectionSymbol);
955 unsigned symbolEncoding) {
957 unsigned format = symbolEncoding & 0x0f;
976 unsigned symbolEncoding,
bool isEH) {
990 unsigned symbolEncoding) {
1001 class FrameEmitterImpl {
1003 int InitialCFAOffset;
1007 FrameEmitterImpl(
bool isEH)
1008 : CFAOffset(0), InitialCFAOffset(0), IsEH(isEH), SectionStart(nullptr) {
1019 unsigned personalityEncoding,
1022 unsigned lsdaEncoding,
1050 Reg1 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg1,
true),
false);
1051 Reg2 = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg2,
true),
false);
1070 const bool IsRelative =
1087 Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg,
true),
false);
1099 Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg,
true),
false);
1108 const bool IsRelative =
1113 Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg,
true),
false);
1117 Offset -= CFAOffset;
1118 Offset = Offset / dataAlignmentFactor;
1124 }
else if (Reg < 64) {
1149 Reg = MRI->getDwarfRegNum(MRI->getLLVMRegNum(Reg,
true),
false);
1164 for (
unsigned i = 0,
N = Instrs.
size(); i <
N; ++i) {
1168 if (Label && !Label->
isDefined())
continue;
1171 if (BaseLabel && Label) {
1173 if (ThisSym != BaseLabel) {
1175 BaseLabel = ThisSym;
1179 EmitCFIInstruction(streamer, Instr);
1212 if (!Encoding)
return;
1216 if (!DwarfEHFrameOnly && Frame.
Lsda)
1217 Encoding |= 0x40000000;
1242 if (!DwarfEHFrameOnly && Frame.
Lsda)
1251 switch (DwarfVersion) {
1264 unsigned personalityEncoding,
1267 unsigned lsdaEncoding,
1284 unsigned CIE_ID = IsEH ? 0 : -1;
1294 Augmentation +=
"z";
1296 Augmentation +=
"P";
1298 Augmentation +=
"L";
1299 Augmentation +=
"R";
1301 Augmentation +=
"S";
1306 if (CIEVersion >= 4) {
1321 if (CIEVersion == 1) {
1323 "DWARF 2 encodes return_address_register in one byte");
1332 unsigned augmentationLength = 0;
1336 augmentationLength += 1;
1341 augmentationLength += 1;
1343 augmentationLength += 1;
1366 const std::vector<MCCFIInstruction> &Instructions =
1368 EmitCFIInstructions(streamer, Instructions,
nullptr);
1371 InitialCFAOffset = CFAOffset;
1377 return *sectionStart;
1388 CFAOffset = InitialCFAOffset;
1411 unsigned PCEncoding =
1423 unsigned augmentationLength = 0;
1446 static const CIEKey getEmptyKey() {
1447 return CIEKey(
nullptr, 0, -1,
false,
false);
1449 static const CIEKey getTombstoneKey() {
1450 return CIEKey(
nullptr, -1, 0,
false,
false);
1453 CIEKey(
const MCSymbol *Personality_,
unsigned PersonalityEncoding_,
1454 unsigned LsdaEncoding_,
bool IsSignalFrame_,
bool IsSimple_)
1455 : Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
1456 LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_),
1457 IsSimple(IsSimple_) {}
1459 unsigned PersonalityEncoding;
1460 unsigned LsdaEncoding;
1470 return CIEKey::getEmptyKey();
1473 return CIEKey::getTombstoneKey();
1476 return static_cast<unsigned>(
hash_combine(Key.Personality,
1477 Key.PersonalityEncoding,
1483 const CIEKey &RHS) {
1484 return LHS.Personality == RHS.Personality &&
1485 LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
1486 LHS.LsdaEncoding == RHS.LsdaEncoding &&
1487 LHS.IsSignalFrame == RHS.IsSignalFrame &&
1488 LHS.IsSimple == RHS.IsSimple;
1499 FrameEmitterImpl Emitter(IsEH);
1505 bool SectionEmitted =
false;
1506 for (
unsigned i = 0, n = FrameArray.
size(); i < n; ++i) {
1509 if (!SectionEmitted) {
1512 SectionEmitted =
true;
1514 NeedsEHFrameSection |=
1517 Emitter.EmitCompactUnwind(Streamer, Frame);
1521 if (!NeedsEHFrameSection)
return;
1530 Emitter.setSectionStart(SectionStart);
1535 const MCSymbol *DummyDebugKey =
nullptr;
1537 for (
unsigned i = 0, n = FrameArray.
size(); i < n; ++i) {
1554 const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
1556 CIEStart = &Emitter.EmitCIE(Streamer, Frame.
Personality,
1562 FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
1571 uint64_t AddrDelta) {
1585 if (AddrDelta == 0) {
1586 }
else if (
isUIntN(6, AddrDelta)) {
1591 OS << uint8_t(AddrDelta);
static const MCExpr * forceExpAbs(MCStreamer &OS, const MCExpr *Expr)
bool isUInt< 8 >(uint64_t x)
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry &E)
Instances of this class represent a uniqued identifier for a section in the current translation unit...
void push_back(const T &Elt)
static void Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
const MCAsmInfo * getAsmInfo() const
unsigned getFDEEncoding() const
static int getDataAlignmentFactor(MCStreamer &streamer)
void EmitBytes(StringRef Data) override
Emit the bytes in Data into the output.
static CIEKey getTombstoneKey()
#define DWARF2_FLAG_PROLOGUE_END
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
void EmitSLEB128IntValue(int64_t Value)
Special case of EmitSLEB128Value that avoids the client having to pass in a MCExpr for constant integ...
size_t size() const
size - Get the string size.
void EmitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
void EmitLabel(MCSymbol *Symbol) override
Emit a label for Symbol into the current section.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
void write(value_type Val)
void Emit(MCStreamer &MCOS) const
const SmallVectorImpl< MCDwarfFile > & getMCDwarfFiles(unsigned CUID=0)
virtual void EmitBytes(StringRef Data)
Emit the bytes in Data into the output.
StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta)
A raw_ostream that writes to an SmallVector or SmallString.
ArrayRef< MCDwarfFrameInfo > getDwarfFrameInfos() const
virtual MCSymbol * getDwarfLineTableSymbol(unsigned CUID)
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol, const MCSymbol *RangesSectionSymbol)
uint16_t getDwarfVersion() const
StringRef getDwarfDebugFlags()
void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)
unsigned getRegister() const
std::vector< MCCFIInstruction > Instructions
static void Encode(MCContext &Context, int64_t LineDelta, uint64_t AddrDelta, raw_ostream &OS)
Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
static const MCBinaryExpr * create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
#define DWARF2_FLAG_IS_STMT
StringRef getDwarfDebugProducer()
bool getSupportsCompactUnwindWithoutEHFrame() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MCSectionSubPair getCurrentSection() const
Return the current section that the streamer is emitting code to.
void EmitCU(MCObjectStreamer *MCOS) const
void finalizeDwarfSections(MCStreamer &MCOS)
Remove empty sections from SectionStartEndSyms, to avoid generating useless debug info for them...
Base class for the full range of assembler expressions which are needed for parsing.
Reg
All possible values of the reg field in the ModR/M byte.
const std::vector< MCCFIInstruction > & getInitialFrameState() const
static void emitFDESymbol(MCObjectStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, bool isEH)
MCDwarfLineTable & getMCDwarfLineTable(unsigned CUID)
MCContext & getContext() const
bool isLittleEndian() const
True if the target is little endian.
const SmallVectorImpl< std::string > & getMCDwarfDirs(unsigned CUID=0)
virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value)
Emit an assignment of Value to Symbol.
Context object for machine code objects.
StringRef getValues() const
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
#define MAX_SPECIAL_ADDR_DELTA
unsigned getDwarfCompileUnitID()
Streaming object file generation interface.
Instances of this class represent the information from a dwarf .loc directive.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
unsigned getGenDwarfFileNumber()
virtual void EmitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers...
size_t size() const
size - Get the array size.
#define DWARF2_LINE_RANGE
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
format_object< Ts...> format(const char *Fmt, const Ts &...Vals)
These are helper functions used to produce formatted output.
LLVM_CONSTEXPR size_t array_lengthof(T(&)[N])
Find the length of an array.
This class is intended to be used as a base class for asm properties and features specific to the tar...
MCSection * getDwarfLineSection() const
bool needsDwarfSectionOffsetDirective() const
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
StringRef filename(StringRef path)
Get filename.
Streaming machine code generation interface.
static unsigned getCIEVersion(bool IsEH, unsigned DwarfVersion)
MCSection * getCompactUnwindSection() const
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
MCSymbol * createTempSymbol(bool CanBeUnnamed=true)
Create and return a new assembler temporary symbol with a unique but unspecified name.
virtual void EmitFill(uint64_t NumBytes, uint8_t FillValue)
Emit NumBytes bytes worth of the value specified by FillValue.
#define DWARF2_FLAG_EPILOGUE_BEGIN
virtual void SwitchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
static void emitAbsValue(MCStreamer &OS, const MCExpr *Value, unsigned Size)
static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)
cl::opt< int > DwarfVersion("dwarf-version", cl::desc("Dwarf version"), cl::init(0))
#define DWARF2_FLAG_BASIC_BLOCK
const MCDwarfLoc & getCurrentDwarfLoc()
unsigned PersonalityEncoding
This owns the files read by a parser, handles include stacks, and handles diagnostic wrangling...
std::vector< MCLineEntry > MCLineEntryCollection
void generateCompactUnwindEncodings(MCAsmBackend *MAB)
#define DWARF2_LINE_OPCODE_BASE
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0) override
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
unsigned getPointerSize() const
Get the pointer size in bytes.
const SetVector< MCSection * > & getGenDwarfSectionSyms()
OpType getOperation() const
bool isDefined() const
isDefined - Check if this symbol is defined (i.e., it has an address).
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
unsigned getMinInstAlignment() const
void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label)
bool doDwarfFDESymbolsUseAbsDiff() const
static unsigned getHashValue(const CIEKey &Key)
virtual void EmitLabel(MCSymbol *Symbol)
Emit a label for Symbol into the current section.
static bool isEqual(const CIEKey &LHS, const CIEKey &RHS)
static void EmitDwarfLineTable(MCObjectStreamer *MCOS, MCSection *Section, const MCLineSection::MCLineEntryCollection &LineEntries)
unsigned getRegister2() const
static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, raw_ostream &OS)
uint32_t CompactUnwindEncoding
static void EmitGenDwarfRanges(MCStreamer *MCOS)
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
void encodeSLEB128(int64_t Value, raw_ostream &OS)
Utility function to encode a SLEB128 value to an output stream.
const std::vector< MCGenDwarfLabelEntry > & getMCGenDwarfLabelEntries() const
bool isUInt< 32 >(uint64_t x)
StringRef parent_path(StringRef path)
Get parent path.
static CIEKey getEmptyKey()
unsigned FindLineNumber(SMLoc Loc, unsigned BufferID=0) const
Find the line number for the specified location in the specified file.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
StringRef get_separator()
Return the preferred separator for this platform.
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
static void Emit(MCStreamer *MCOS)
#define DWARF2_LINE_DEFAULT_IS_STMT
static StringRef toStringRef(bool B)
Construct a string ref from a boolean.
static uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta)
const MCRegisterInfo * getRegisterInfo() const
StringRef str()
Flushes the stream contents to the target vector and return a StringRef for the vector contents...
StringRef getCompilationDir() const
Get the compilation directory for DW_AT_comp_dir This can be overridden by clients which want to cont...
MCSection * getDwarfARangesSection() const
Adapter to write values to a stream in a particular byte order.
static const MCExpr * MakeStartMinusEndExpr(const MCStreamer &MCOS, const MCSymbol &Start, const MCSymbol &End, int IntVal)
Instances of this class represent the line information for the dwarf line table entries.
StringRef getName() const
getName - Get the symbol name.
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
const std::map< unsigned, MCDwarfLineTable > & getMCDwarfLineTables() const
const MCSymbol * Personality
bool isStackGrowthDirectionUp() const
True if target stack grow up.
MCSection * getDwarfFrameSection() const
static void Make(MCObjectStreamer *MCOS, MCSection *Section)
unsigned getCalleeSaveStackSlotSize() const
Get the callee-saved register stack slot size in bytes.
const MCLineDivisionMap & getMCLineEntries() const
bool hasAggressiveSymbolFolding() const
void EmitValue(const MCExpr *Value, unsigned Size, const SMLoc &Loc=SMLoc())
void EmitULEB128IntValue(uint64_t Value, unsigned Padding=0)
Special case of EmitULEB128Value that avoids the client having to pass in a MCExpr for constant integ...
MCSymbol * endSection(MCSection *Section)
unsigned FindBufferContainingLoc(SMLoc Loc) const
Return the ID of the buffer containing the specified location.
MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber, MCSymbol *label)
virtual const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
LLVM Value Representation.
Generic interface to target specific assembler backends.
const MCObjectFileInfo * getObjectFileInfo() const
MCSection * getDwarfInfoSection() const
MCSection * getDwarfRangesSection() const
bool isUInt< 16 >(uint64_t x)
unsigned getCompactUnwindDwarfEHFrameOnly() const
static void emitEncodingByte(MCObjectStreamer &Streamer, unsigned Encoding)
This class implements an extremely fast bulk output stream that can only output to a stream...
void encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned Padding=0)
Utility function to encode a ULEB128 value to an output stream.
static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH)
StringRef - Represent a constant reference to a string, i.e.
Instances of this class represent the name of the dwarf .file directive and its associated dwarf file...
unsigned getRARegister() const
This method should return the register where the return address can be found.
MCSection * getDwarfAbbrevSection() const
Represents a location in source code.
unsigned getFile(StringRef &Directory, StringRef &FileName, unsigned FileNumber=0)
bool isUIntN(unsigned N, uint64_t x)
isUIntN - Checks if an unsigned integer fits into the given (dynamic) bit width.
MCSymbol * getLabel() const
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
bool doesDwarfUseRelocationsAcrossSections() const
bool empty() const
empty - Check if the string is empty.
static void Emit(MCObjectStreamer *MCOS)