14 #include "llvm/Config/config.h"
32 #define SPECIAL_ADDR(op) (((op) - DWARF2_LINE_OPCODE_BASE)/DWARF2_LINE_RANGE)
35 #define MAX_SPECIAL_ADDR_DELTA SPECIAL_ADDR(255)
40 #define DWARF2_LINE_OPCODE_BASE 13
44 #define DWARF2_LINE_BASE -5
47 #define DWARF2_LINE_RANGE 14
51 if (MinInsnLength == 1)
53 if (AddrDelta % MinInsnLength != 0) {
57 return AddrDelta / MinInsnLength;
135 unsigned FileNum = 1;
136 unsigned LastLine = 1;
147 if (FileNum != it->getFileNum()) {
148 FileNum = it->getFileNum();
152 if (Column != it->getColumn()) {
153 Column = it->getColumn();
157 if (Isa != it->getIsa()) {
163 Flags = it->getFlags();
173 int64_t LineDelta =
static_cast<int64_t
>(it->getLine()) - LastLine;
183 LastLine = it->getLine();
227 for (
unsigned Is = 1, Ie = MCLineTableSymbols.
size(); Is < Ie; Is++)
235 MCLineSections.
begin(), ie = MCLineSections.
end(); it != ie;
299 for (
unsigned i = 0; i < MCDwarfDirs.
size(); i++) {
308 for (
unsigned i = 1; i < MCDwarfFiles.
size(); i++) {
325 const std::vector<const MCSection *> &MCLineSectionOrder =
327 for (std::vector<const MCSection*>::const_iterator it =
328 MCLineSectionOrder.begin(), ie = MCLineSectionOrder.end(); it != ie;
336 && MCLineSectionOrder.begin() == MCLineSectionOrder.end()) {
356 uint64_t AddrDelta) {
367 uint64_t Temp, Opcode;
368 bool NeedCopy =
false;
376 if (LineDelta == INT64_MAX) {
404 if (LineDelta == 0 && AddrDelta == 0) {
444 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
466 EmitAbbrev(MCOS, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4);
467 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
468 EmitAbbrev(MCOS, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr);
469 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
470 EmitAbbrev(MCOS, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string);
472 if (!DwarfDebugFlags.
empty())
473 EmitAbbrev(MCOS, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string);
474 EmitAbbrev(MCOS, dwarf::DW_AT_producer, dwarf::DW_FORM_string);
475 EmitAbbrev(MCOS, dwarf::DW_AT_language, dwarf::DW_FORM_data2);
482 EmitAbbrev(MCOS, dwarf::DW_AT_name, dwarf::DW_FORM_string);
483 EmitAbbrev(MCOS, dwarf::DW_AT_decl_file, dwarf::DW_FORM_data4);
484 EmitAbbrev(MCOS, dwarf::DW_AT_decl_line, dwarf::DW_FORM_data4);
485 EmitAbbrev(MCOS, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr);
486 EmitAbbrev(MCOS, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag);
504 const MCSymbol *InfoSectionSymbol) {
519 int Length = 4 + 2 + 4 + 1 + 1;
525 int Pad = 2 * AddrSize - (Length & (2 * AddrSize - 1));
526 if (Pad == 2 * AddrSize)
532 Length += 2 * AddrSize;
534 Length += 2 * AddrSize;
544 if (InfoSectionSymbol)
553 for(
int i = 0; i < Pad; i++)
574 const MCSymbol *AbbrevSectionSymbol,
575 const MCSymbol *LineSectionSymbol) {
598 if (AbbrevSectionSymbol) {
616 if (LineSectionSymbol) {
636 if (MCDwarfDirs.
size() > 0) {
651 if (!DwarfDebugFlags.
empty()){
658 if (!DwarfDebugProducer.
empty()){
675 const std::vector<const MCGenDwarfLabelEntry *> &Entries =
677 for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
678 Entries.begin(), ie = Entries.end(); it != ie;
711 for (std::vector<const MCGenDwarfLabelEntry *>::const_iterator it =
712 Entries.begin(), ie = Entries.end(); it != ie;
733 bool CreateDwarfSectionSymbols =
735 if (!CreateDwarfSectionSymbols)
736 LineSectionSymbol = NULL;
737 MCSymbol *AbbrevSectionSymbol = NULL;
740 if (CreateDwarfSectionSymbols) {
745 if (CreateDwarfSectionSymbols) {
819 unsigned symbolEncoding) {
821 unsigned format = symbolEncoding & 0x0f;
840 unsigned symbolEncoding,
const char *comment = 0) {
852 unsigned symbolEncoding) {
863 class FrameEmitterImpl {
870 FrameEmitterImpl(
bool usingCFI,
bool isEH)
871 : CFAOffset(0), CIENum(0), UsingCFI(usingCFI), IsEH(isEH),
874 void setSectionStart(
const MCSymbol *Label) { SectionStart = Label; }
882 unsigned personalityEncoding,
885 unsigned lsdaEncoding);
889 void EmitCFIInstructions(
MCStreamer &streamer,
903 default: EncStr =
"<unknown encoding>";
break;
912 EncStr =
"pcrel udata4";
915 EncStr =
"pcrel sdata4";
918 EncStr =
"pcrel udata8";
921 EncStr =
"screl sdata8";
924 EncStr =
"indirect pcrel udata4";
927 EncStr =
"indirect pcrel sdata4";
930 EncStr =
"indirect pcrel udata8";
933 EncStr =
"indirect pcrel sdata8";
943 void FrameEmitterImpl::EmitCFIInstruction(
MCStreamer &Streamer,
978 const bool IsRelative =
1016 Streamer.
AddComment(
"DW_CFA_def_cfa_register");
1028 const bool IsRelative =
1034 Offset -= CFAOffset;
1035 Offset = Offset / dataAlignmentFactor;
1038 if (VerboseAsm) Streamer.
AddComment(
"DW_CFA_offset_extended_sf");
1044 }
else if (Reg < 64) {
1051 if (VerboseAsm) Streamer.
AddComment(
"DW_CFA_offset_extended");
1061 if (VerboseAsm) Streamer.
AddComment(
"DW_CFA_remember_state");
1065 if (VerboseAsm) Streamer.
AddComment(
"DW_CFA_restore_state");
1070 if (VerboseAsm) Streamer.
AddComment(
"DW_CFA_same_value");
1086 if (VerboseAsm) Streamer.
AddComment(
"Escape bytes");
1095 void FrameEmitterImpl::EmitCFIInstructions(
MCStreamer &streamer,
1098 for (
unsigned i = 0,
N = Instrs.
size(); i <
N; ++i) {
1102 if (Label && !Label->
isDefined())
continue;
1105 if (BaseLabel && Label) {
1107 if (ThisSym != BaseLabel) {
1110 BaseLabel = ThisSym;
1114 EmitCFIInstruction(streamer, Instr);
1119 void FrameEmitterImpl::EmitCompactUnwind(
MCStreamer &Streamer,
1148 if (!Encoding)
return;
1152 if (!DwarfEHFrameOnly && Frame.
Lsda)
1153 Encoding |= 0x40000000;
1158 if (VerboseAsm) Streamer.
AddComment(
"Range Start");
1164 if (VerboseAsm) Streamer.
AddComment(
"Range Length");
1169 if (VerboseAsm) Streamer.
AddComment(
"Compact Unwind Encoding: 0x" +
1175 if (VerboseAsm) Streamer.
AddComment(
"Personality Function");
1184 if (!DwarfEHFrameOnly && Frame.
Lsda)
1192 unsigned personalityEncoding,
1195 unsigned lsdaEncoding) {
1215 if (verboseAsm) streamer.
AddComment(
"CIE Length");
1219 unsigned CIE_ID = IsEH ? 0 : -1;
1220 if (verboseAsm) streamer.
AddComment(
"CIE ID Tag");
1224 if (verboseAsm) streamer.
AddComment(
"DW_CIE_VERSION");
1230 if (verboseAsm) streamer.
AddComment(
"CIE Augmentation");
1231 Augmentation +=
"z";
1233 Augmentation +=
"P";
1235 Augmentation +=
"L";
1236 Augmentation +=
"R";
1238 Augmentation +=
"S";
1244 if (verboseAsm) streamer.
AddComment(
"CIE Code Alignment Factor");
1248 if (verboseAsm) streamer.
AddComment(
"CIE Data Alignment Factor");
1252 if (verboseAsm) streamer.
AddComment(
"CIE Return Address Column");
1257 unsigned augmentationLength = 0;
1261 augmentationLength += 1;
1266 augmentationLength += 1;
1268 augmentationLength += 1;
1270 if (verboseAsm) streamer.
AddComment(
"Augmentation Size");
1277 "Personality Encoding");
1279 if (verboseAsm) streamer.
AddComment(
"Personality");
1294 const std::vector<MCCFIInstruction> &Instructions =
1296 EmitCFIInstructions(streamer, Instructions, NULL);
1302 return *sectionStart;
1323 if (verboseAsm) streamer.
AddComment(
"FDE Length");
1333 if (verboseAsm) streamer.
AddComment(
"FDE CIE Offset");
1347 EmitSymbol(streamer, *frame.
Begin, PCEncoding,
"FDE initial location");
1352 if (verboseAsm) streamer.
AddComment(
"FDE address range");
1357 unsigned augmentationLength = 0;
1362 if (verboseAsm) streamer.
AddComment(
"Augmentation size");
1368 "Language Specific Data Area");
1382 static const CIEKey getEmptyKey() {
return CIEKey(0, 0, -1,
false); }
1383 static const CIEKey getTombstoneKey() {
return CIEKey(0, -1, 0,
false); }
1385 CIEKey(
const MCSymbol* Personality_,
unsigned PersonalityEncoding_,
1386 unsigned LsdaEncoding_,
bool IsSignalFrame_) :
1387 Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
1388 LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) {
1391 unsigned PersonalityEncoding;
1392 unsigned LsdaEncoding;
1401 return CIEKey::getEmptyKey();
1404 return CIEKey::getTombstoneKey();
1407 return static_cast<unsigned>(
hash_combine(Key.Personality,
1408 Key.PersonalityEncoding,
1410 Key.IsSignalFrame));
1413 const CIEKey &RHS) {
1414 return LHS.Personality == RHS.Personality &&
1415 LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
1416 LHS.LsdaEncoding == RHS.LsdaEncoding &&
1417 LHS.IsSignalFrame == RHS.IsSignalFrame;
1423 bool UsingCFI,
bool IsEH) {
1428 FrameEmitterImpl Emitter(UsingCFI, IsEH);
1433 bool SectionEmitted =
false;
1434 for (
unsigned i = 0, n = FrameArray.
size(); i < n; ++i) {
1437 if (!SectionEmitted) {
1440 SectionEmitted =
true;
1442 Emitter.EmitCompactUnwind(Streamer, Frame);
1452 Emitter.setSectionStart(SectionStart);
1457 const MCSymbol *DummyDebugKey = NULL;
1458 for (
unsigned i = 0, n = FrameArray.
size(); i < n; ++i) {
1462 const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
1464 CIEStart = &Emitter.EmitCIE(Streamer, Frame.
Personality,
1469 FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
1481 uint64_t AddrDelta) {
1495 if (AddrDelta == 0) {
1496 }
else if (
isUIntN(6, AddrDelta)) {
1501 OS << uint8_t(AddrDelta);
1505 OS << uint8_t( AddrDelta & 0xff);
1506 OS << uint8_t((AddrDelta >> 8) & 0xff);
1511 OS << uint8_t( AddrDelta & 0xff);
1512 OS << uint8_t((AddrDelta >> 8) & 0xff);
1513 OS << uint8_t((AddrDelta >> 16) & 0xff);
1514 OS << uint8_t((AddrDelta >> 24) & 0xff);
bool isUInt< 8 >(uint64_t x)
const MCSymbol * Function
static void Emit(MCStreamer *MCOS, int64_t LineDelta, uint64_t AddrDelta)
Utility function to emit the encoding to a streamer.
unsigned getFileNumber() const
int getDwarfRegNum(unsigned RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number. Returns -1 if there is no equivalent va...
const MCAsmInfo * getAsmInfo() const
static int getDataAlignmentFactor(MCStreamer &streamer)
virtual void AddComment(const Twine &T)
bool getLinkerRequiresNonEmptyDwarfLines() const
const MCSection * getDwarfAbbrevSection() const
MCSymbol * getGenDwarfSectionStartSym()
virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, const MCSymbol *LastLabel, const MCSymbol *Label, unsigned PointerSize)=0
MCSymbol * getGenDwarfSectionEndSym()
static CIEKey getTombstoneKey()
#define DWARF2_FLAG_PROLOGUE_END
void EmitSLEB128IntValue(int64_t Value)
size_t size() const
size - Get the string size.
static void EmitEncodingByte(MCStreamer &Streamer, unsigned Encoding, StringRef Prefix)
static const MCConstantExpr * Create(int64_t Value, MCContext &Ctx)
void addLineEntry(const MCLineEntry &LineEntry, unsigned CUID)
const MCSection * getDwarfLineSection() const
MCLineEntryCollection::const_iterator const_iterator
StringRef substr(size_t Start, size_t N=npos) const
const MCLineEntryCollection & getMCLineEntries(unsigned CUID) const
const DenseMap< unsigned, MCSymbol * > & getMCLineTableSymbols() const
StringRef getDwarfDebugFlags()
static void Emit(MCStreamer *MCOS, const MCSymbol *LineSectionSymbol)
unsigned getRegister() const
ArrayRef< MCDwarfFrameInfo > getFrameInfos() const
MCSymbol * getMCLineTableSymbol(unsigned ID) const
void print(raw_ostream &OS) const
print - Print the value to the stream OS.
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.
virtual const MCExpr * getExprForPersonalitySymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
MCSymbol * GetOrCreateSymbol(StringRef Name)
static void Make(MCStreamer *MCOS, const MCSection *Section)
#define DWARF2_FLAG_IS_STMT
StringRef getDwarfDebugProducer()
MCSymbol * CreateTempSymbol()
static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta)
#define llvm_unreachable(msg)
MCSectionSubPair getCurrentSection() const
unsigned getLineNumber() const
virtual void EmitBytes(StringRef Data)=0
const std::vector< MCCFIInstruction > & getInitialFrameState() const
const std::vector< const MCSection * > & getMCLineSectionOrder() const
virtual bool isVerboseAsm() const
MCContext & getContext() const
const std::vector< const MCGenDwarfLabelEntry * > & getMCGenDwarfLabelEntries() const
const MCSection * getGenDwarfSection()
format_object1< T > format(const char *Fmt, const T &Val)
void SwitchSection(const MCSection *Section, const MCExpr *Subsection=0)
static void EmitGenDwarfAbbrev(MCStreamer *MCOS)
#define MAX_SPECIAL_ADDR_DELTA
void addMCLineSection(const MCSection *Sec, MCLineSection *Line)
void setGenDwarfSectionEndSym(MCSymbol *Sym)
unsigned getDwarfCompileUnitID()
void dump() const
dump - Print the value to stderr.
unsigned getGenDwarfFileNumber()
virtual void EmitIntValue(uint64_t Value, unsigned Size)
size_t size() const
size - Get the array size.
void EmitValue(const MCExpr *Value, unsigned Size)
#define DWARF2_LINE_RANGE
static const MCSymbolRefExpr * Create(const MCSymbol *Symbol, MCContext &Ctx)
static unsigned getSizeForEncoding(MCStreamer &streamer, unsigned symbolEncoding)
StringRef getName() const
getName - Get the base name of this MCDwarfFile.
const MCSection * getCompactUnwindSection() const
const MCSection * getDwarfInfoSection() const
static void EmitAbbrev(MCStreamer *MCOS, uint64_t Name, uint64_t Form)
bool isFunctionEHFrameSymbolPrivate() const
const SmallVectorImpl< StringRef > & getMCDwarfDirs(unsigned CUID=0)
const DenseMap< const MCSection *, MCLineSection * > & getMCLineSections() const
static const MCBinaryExpr * Create(Opcode Op, const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
#define DWARF2_FLAG_EPILOGUE_BEGIN
hash_code hash_combine(const T1 &arg1, const T2 &arg2, const T3 &arg3, const T4 &arg4, const T5 &arg5, const T6 &arg6)
static const MCSymbol * Emit(MCStreamer *MCOS)
static void EmitGenDwarfAranges(MCStreamer *MCOS, const MCSymbol *InfoSectionSymbol)
static const MCSymbol * EmitCU(MCStreamer *MCOS, unsigned ID)
unsigned getFDEEncoding(bool CFI) const
#define DWARF2_FLAG_BASIC_BLOCK
const MCDwarfLoc & getCurrentDwarfLoc()
unsigned PersonalityEncoding
virtual void EmitEHSymAttributes(const MCSymbol *Symbol, MCSymbol *EHSymbol)
static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding, const char *comment=0)
virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)=0
void generateCompactUnwindEncodings(MCAsmBackend *MAB)
#define DWARF2_LINE_OPCODE_BASE
unsigned getPointerSize() const
getPointerSize - Get the pointer size in bytes.
bool containEntriesForID(unsigned CUID) const
OpType getOperation() const
static void EmitDwarfLineTable(MCStreamer *MCOS, const MCSection *Section, const MCLineSection *LineSection, unsigned CUID)
const StringRef getValues() const
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
unsigned getMinInstAlignment() const
static unsigned getHashValue(const CIEKey &Key)
virtual void EmitLabel(MCSymbol *Symbol)
static bool isEqual(const CIEKey &LHS, const CIEKey &RHS)
static Twine utohexstr(const uint64_t &Val)
unsigned getRegister2() const
void addMCGenDwarfLabelEntry(const MCGenDwarfLabelEntry *E)
static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, raw_ostream &OS)
uint32_t CompactUnwindEncoding
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void encodeSLEB128(int64_t Value, raw_ostream &OS)
Utility function to encode a SLEB128 value to an output stream.
bool isUInt< 32 >(uint64_t x)
static CIEKey getEmptyKey()
StringRef str() const
Explicit conversion to StringRef.
unsigned FindLineNumber(SMLoc Loc, int BufferID=-1) const
bool isTemporary() const
isTemporary - Check if this is an assembler temporary symbol.
#define DWARF2_LINE_DEFAULT_IS_STMT
const SmallVectorImpl< MCDwarfFile * > & getMCDwarfFiles(unsigned CUID=0)
static uint64_t ScaleAddrDelta(MCContext &Context, uint64_t AddrDelta)
const MCRegisterInfo * getRegisterInfo() const
static void Emit(MCStreamer &streamer, MCAsmBackend *MAB, bool usingCFI, bool isEH)
StringRef getCompilationDir() const
Get the compilation directory for DW_AT_comp_dir This can be overridden by clients which want to cont...
static const MCExpr * MakeStartMinusEndExpr(const MCStreamer &MCOS, const MCSymbol &Start, const MCSymbol &End, int IntVal)
StringRef getName() const
getName - Get the symbol name.
std::string getName(ID id, ArrayRef< Type * > Tys=None)
static void EmitPersonality(MCStreamer &streamer, const MCSymbol &symbol, unsigned symbolEncoding)
static void Make(MCSymbol *Symbol, MCStreamer *MCOS, SourceMgr &SrcMgr, SMLoc &Loc)
const MCSymbol * Personality
virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label)
bool isStackGrowthDirectionUp() const
isStackGrowthDirectionUp - True if target stack grow up.
unsigned getCalleeSaveStackSlotSize() const
void EmitAbsValue(const MCExpr *Value, unsigned Size)
int FindBufferContainingLoc(SMLoc Loc) const
void EmitULEB128IntValue(uint64_t Value, unsigned Padding=0)
const MCSection * getDwarfARangesSection() const
static void EmitGenDwarfInfo(MCStreamer *MCOS, const MCSymbol *AbbrevSectionSymbol, const MCSymbol *LineSectionSymbol)
MCGenDwarfLabelEntry(StringRef name, unsigned fileNumber, unsigned lineNumber, MCSymbol *label)
const MCExpr * getExprForFDESymbol(const MCSymbol *Sym, unsigned Encoding, MCStreamer &Streamer) const
StringRef getName() const
MCAsmBackend - Generic interface to target specific assembler backends.
const MCObjectFileInfo * getObjectFileInfo() const
ValueT lookup(const KeyT &Val) const
bool isUInt< 16 >(uint64_t x)
unsigned getCompactUnwindDwarfEHFrameOnly() const
void encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned Padding=0)
Utility function to encode a ULEB128 value to an output stream.
void EmitSymbolValue(const MCSymbol *Sym, unsigned Size)
const MCSection * getDwarfFrameSection() const
MCSymbol * getLabel() const
const MCRegisterInfo & MRI
unsigned getRARegister() const
This method should return the register where the return address can be found.
Represents a location in source code.
bool isUIntN(unsigned N, uint64_t x)
MCSymbol * getLabel() const
bool doesDwarfUseRelocationsAcrossSections() const
bool empty() const
empty - Check if the string is empty.