aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/DebugInfo')
-rw-r--r--include/llvm/DebugInfo/CodeView/CVTypeVisitor.h4
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h13
-rw-r--r--include/llvm/DebugInfo/CodeView/CodeViewRegisters.def128
-rw-r--r--include/llvm/DebugInfo/CodeView/EnumTables.h11
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolDeserializer.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/SymbolRecord.h304
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeDeserializer.h2
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeRecordMapping.h1
-rw-r--r--include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h5
-rw-r--r--include/llvm/DebugInfo/DIContext.h14
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h4
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h68
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFAttribute.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFContext.h8
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h13
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h6
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h4
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h8
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h10
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugLine.h27
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h35
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h4
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h7
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFDie.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFExpression.h14
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFFormValue.h10
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFListTable.h77
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFObject.h30
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnit.h51
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h2
-rw-r--r--include/llvm/DebugInfo/DWARF/DWARFVerifier.h4
-rw-r--r--include/llvm/DebugInfo/GSYM/FileEntry.h7
-rw-r--r--include/llvm/DebugInfo/GSYM/FileWriter.h124
-rw-r--r--include/llvm/DebugInfo/GSYM/FunctionInfo.h154
-rw-r--r--include/llvm/DebugInfo/GSYM/GsymCreator.h229
-rw-r--r--include/llvm/DebugInfo/GSYM/GsymReader.h228
-rw-r--r--include/llvm/DebugInfo/GSYM/Header.h129
-rw-r--r--include/llvm/DebugInfo/GSYM/InlineInfo.h63
-rw-r--r--include/llvm/DebugInfo/GSYM/LineEntry.h7
-rw-r--r--include/llvm/DebugInfo/GSYM/LineTable.h198
-rw-r--r--include/llvm/DebugInfo/GSYM/Range.h33
-rw-r--r--include/llvm/DebugInfo/GSYM/StringTable.h7
-rw-r--r--include/llvm/DebugInfo/PDB/GenericError.h2
-rw-r--r--include/llvm/DebugInfo/PDB/Native/SymbolCache.h2
-rw-r--r--include/llvm/DebugInfo/PDB/PDBSymbol.h2
-rw-r--r--include/llvm/DebugInfo/Symbolize/Symbolize.h1
50 files changed, 1653 insertions, 415 deletions
diff --git a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
index 7d20bb0a7bde..7538cb2c2548 100644
--- a/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
+++ b/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
@@ -11,7 +11,6 @@
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -31,9 +30,6 @@ enum VisitorDataSource {
Error visitTypeRecord(CVType &Record, TypeIndex Index,
TypeVisitorCallbacks &Callbacks,
VisitorDataSource Source = VDS_BytesPresent);
-Error visitTypeRecord(CVType &Record, TypeIndex Index,
- TypeVisitorCallbackPipeline &Callbacks,
- VisitorDataSource Source = VDS_BytesPresent);
Error visitTypeRecord(CVType &Record, TypeVisitorCallbacks &Callbacks,
VisitorDataSource Source = VDS_BytesPresent);
diff --git a/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
index 00fb0cf4cc90..60829a51dc25 100644
--- a/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
+++ b/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
@@ -33,6 +33,9 @@ public:
virtual void EmitIntValue(uint64_t Value, unsigned Size) = 0;
virtual void EmitBinaryData(StringRef Data) = 0;
virtual void AddComment(const Twine &T) = 0;
+ virtual void AddRawComment(const Twine &T) = 0;
+ virtual bool isVerboseAsm() = 0;
+ virtual std::string getTypeName(TypeIndex TI) = 0;
virtual ~CodeViewRecordStreamer() = default;
};
@@ -206,6 +209,11 @@ public:
return 0;
}
+ void emitRawComment(const Twine &T) {
+ if (isStreaming() && Streamer->isVerboseAsm())
+ Streamer->AddRawComment(T);
+ }
+
private:
void emitEncodedSignedInteger(const int64_t &Value,
const Twine &Comment = "");
@@ -225,9 +233,10 @@ private:
}
void emitComment(const Twine &Comment) {
- if (isStreaming()) {
+ if (isStreaming() && Streamer->isVerboseAsm()) {
Twine TComment(Comment);
- Streamer->AddComment(TComment);
+ if (!TComment.isTriviallyEmpty())
+ Streamer->AddComment(TComment);
}
}
diff --git a/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def b/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
index 9767e49c44f5..ed5c143818e6 100644
--- a/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
+++ b/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
@@ -366,8 +366,134 @@ CV_REGISTER(AMD64_K7, 765)
#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_X86)
+#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM)
+
+// ARM registers
+
+CV_REGISTER(ARM_NOREG, 0)
+
+// General purpose 32-bit integer regisers
+
+CV_REGISTER(ARM_R0, 10)
+CV_REGISTER(ARM_R1, 11)
+CV_REGISTER(ARM_R2, 12)
+CV_REGISTER(ARM_R3, 13)
+CV_REGISTER(ARM_R4, 14)
+CV_REGISTER(ARM_R5, 15)
+CV_REGISTER(ARM_R6, 16)
+CV_REGISTER(ARM_R7, 17)
+CV_REGISTER(ARM_R8, 18)
+CV_REGISTER(ARM_R9, 19)
+CV_REGISTER(ARM_R10, 20)
+CV_REGISTER(ARM_R11, 21)
+CV_REGISTER(ARM_R12, 22)
+CV_REGISTER(ARM_SP, 23)
+CV_REGISTER(ARM_LR, 24)
+CV_REGISTER(ARM_PC, 25)
+
+// Status register
+
+CV_REGISTER(ARM_CPSR, 25)
+
+// ARM VFPv1 registers
+
+CV_REGISTER(ARM_FPSCR, 40)
+CV_REGISTER(ARM_FPEXC, 41)
+
+// ARM VFPv3/NEON registers
+
+CV_REGISTER(ARM_FS32, 200)
+CV_REGISTER(ARM_FS33, 201)
+CV_REGISTER(ARM_FS34, 202)
+CV_REGISTER(ARM_FS35, 203)
+CV_REGISTER(ARM_FS36, 204)
+CV_REGISTER(ARM_FS37, 205)
+CV_REGISTER(ARM_FS38, 206)
+CV_REGISTER(ARM_FS39, 207)
+CV_REGISTER(ARM_FS40, 208)
+CV_REGISTER(ARM_FS41, 209)
+CV_REGISTER(ARM_FS42, 210)
+CV_REGISTER(ARM_FS43, 211)
+CV_REGISTER(ARM_FS44, 212)
+CV_REGISTER(ARM_FS45, 213)
+CV_REGISTER(ARM_FS46, 214)
+CV_REGISTER(ARM_FS47, 215)
+CV_REGISTER(ARM_FS48, 216)
+CV_REGISTER(ARM_FS49, 217)
+CV_REGISTER(ARM_FS50, 218)
+CV_REGISTER(ARM_FS51, 219)
+CV_REGISTER(ARM_FS52, 220)
+CV_REGISTER(ARM_FS53, 221)
+CV_REGISTER(ARM_FS54, 222)
+CV_REGISTER(ARM_FS55, 223)
+CV_REGISTER(ARM_FS56, 224)
+CV_REGISTER(ARM_FS57, 225)
+CV_REGISTER(ARM_FS58, 226)
+CV_REGISTER(ARM_FS59, 227)
+CV_REGISTER(ARM_FS60, 228)
+CV_REGISTER(ARM_FS61, 229)
+CV_REGISTER(ARM_FS62, 230)
+CV_REGISTER(ARM_FS63, 231)
+
+CV_REGISTER(ARM_ND0, 300)
+CV_REGISTER(ARM_ND1, 301)
+CV_REGISTER(ARM_ND2, 302)
+CV_REGISTER(ARM_ND3, 303)
+CV_REGISTER(ARM_ND4, 304)
+CV_REGISTER(ARM_ND5, 305)
+CV_REGISTER(ARM_ND6, 306)
+CV_REGISTER(ARM_ND7, 307)
+CV_REGISTER(ARM_ND8, 308)
+CV_REGISTER(ARM_ND9, 309)
+CV_REGISTER(ARM_ND10, 310)
+CV_REGISTER(ARM_ND11, 311)
+CV_REGISTER(ARM_ND12, 312)
+CV_REGISTER(ARM_ND13, 313)
+CV_REGISTER(ARM_ND14, 314)
+CV_REGISTER(ARM_ND15, 315)
+CV_REGISTER(ARM_ND16, 316)
+CV_REGISTER(ARM_ND17, 317)
+CV_REGISTER(ARM_ND18, 318)
+CV_REGISTER(ARM_ND19, 319)
+CV_REGISTER(ARM_ND20, 320)
+CV_REGISTER(ARM_ND21, 321)
+CV_REGISTER(ARM_ND22, 322)
+CV_REGISTER(ARM_ND23, 323)
+CV_REGISTER(ARM_ND24, 324)
+CV_REGISTER(ARM_ND25, 325)
+CV_REGISTER(ARM_ND26, 326)
+CV_REGISTER(ARM_ND27, 327)
+CV_REGISTER(ARM_ND28, 328)
+CV_REGISTER(ARM_ND29, 329)
+CV_REGISTER(ARM_ND30, 330)
+CV_REGISTER(ARM_ND31, 331)
+
+CV_REGISTER(ARM_NQ0, 400)
+CV_REGISTER(ARM_NQ1, 401)
+CV_REGISTER(ARM_NQ2, 402)
+CV_REGISTER(ARM_NQ3, 403)
+CV_REGISTER(ARM_NQ4, 404)
+CV_REGISTER(ARM_NQ5, 405)
+CV_REGISTER(ARM_NQ6, 406)
+CV_REGISTER(ARM_NQ7, 407)
+CV_REGISTER(ARM_NQ8, 408)
+CV_REGISTER(ARM_NQ9, 409)
+CV_REGISTER(ARM_NQ10, 410)
+CV_REGISTER(ARM_NQ11, 411)
+CV_REGISTER(ARM_NQ12, 412)
+CV_REGISTER(ARM_NQ13, 413)
+CV_REGISTER(ARM_NQ14, 414)
+CV_REGISTER(ARM_NQ15, 415)
+
+#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM)
+
#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64)
+// arm64intr.h from MSVC defines ARM64_FPSR, which conflicts with
+// these declarations.
+#pragma push_macro("ARM64_FPSR")
+#undef ARM64_FPSR
+
// ARM64 registers
CV_REGISTER(ARM64_NOREG, 0)
@@ -556,4 +682,6 @@ CV_REGISTER(ARM64_Q31, 211)
CV_REGISTER(ARM64_FPSR, 220)
+#pragma pop_macro("ARM64_FPSR")
+
#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64)
diff --git a/include/llvm/DebugInfo/CodeView/EnumTables.h b/include/llvm/DebugInfo/CodeView/EnumTables.h
index ed126ed9e2ff..270cd4b8330c 100644
--- a/include/llvm/DebugInfo/CodeView/EnumTables.h
+++ b/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -37,6 +37,17 @@ ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames();
ArrayRef<EnumEntry<uint16_t>> getTrampolineNames();
ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
getImageSectionCharacteristicNames();
+ArrayRef<EnumEntry<uint16_t>> getClassOptionNames();
+ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames();
+ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames();
+ArrayRef<EnumEntry<uint16_t>> getMemberKindNames();
+ArrayRef<EnumEntry<uint8_t>> getPtrKindNames();
+ArrayRef<EnumEntry<uint8_t>> getPtrModeNames();
+ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames();
+ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames();
+ArrayRef<EnumEntry<uint8_t>> getCallingConventions();
+ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum();
+ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum();
} // end namespace codeview
} // end namespace llvm
diff --git a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
index 62761cb87c81..108abb291498 100644
--- a/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
+++ b/include/llvm/DebugInfo/CodeView/SymbolDeserializer.h
@@ -62,7 +62,7 @@ public:
Error visitSymbolBegin(CVSymbol &Record) override {
assert(!Mapping && "Already in a symbol mapping!");
- Mapping = llvm::make_unique<MappingInfo>(Record.content(), Container);
+ Mapping = std::make_unique<MappingInfo>(Record.content(), Container);
return Mapping->Mapping.visitSymbolBegin(Record);
}
Error visitSymbolEnd(CVSymbol &Record) override {
diff --git a/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index 5e9a7432b9b6..1aafa3ca9f1d 100644
--- a/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -73,17 +73,17 @@ public:
Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset)
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- uint32_t Parent;
- uint32_t End;
- uint32_t Next;
- uint32_t Offset;
- uint16_t Segment;
- uint16_t Length;
+ uint32_t Parent = 0;
+ uint32_t End = 0;
+ uint32_t Next = 0;
+ uint32_t Offset = 0;
+ uint16_t Segment = 0;
+ uint16_t Length = 0;
ThunkOrdinal Thunk;
StringRef Name;
ArrayRef<uint8_t> VariantData;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_TRAMPOLINE
@@ -94,13 +94,13 @@ public:
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
TrampolineType Type;
- uint16_t Size;
- uint32_t ThunkOffset;
- uint32_t TargetOffset;
- uint16_t ThunkSection;
- uint16_t TargetSection;
+ uint16_t Size = 0;
+ uint32_t ThunkOffset = 0;
+ uint32_t TargetOffset = 0;
+ uint16_t ThunkSection = 0;
+ uint16_t TargetSection = 0;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_SECTION
@@ -110,14 +110,14 @@ public:
SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset)
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- uint16_t SectionNumber;
- uint8_t Alignment;
- uint32_t Rva;
- uint32_t Length;
- uint32_t Characteristics;
+ uint16_t SectionNumber = 0;
+ uint8_t Alignment = 0;
+ uint32_t Rva = 0;
+ uint32_t Length = 0;
+ uint32_t Characteristics = 0;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_COFFGROUP
@@ -127,13 +127,13 @@ public:
CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset)
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- uint32_t Size;
- uint32_t Characteristics;
- uint32_t Offset;
- uint16_t Segment;
+ uint32_t Size = 0;
+ uint32_t Characteristics = 0;
+ uint32_t Offset = 0;
+ uint16_t Segment = 0;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
class ScopeEndSym : public SymbolRecord {
@@ -142,7 +142,7 @@ public:
ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
: SymbolRecord(Kind), RecordOffset(RecordOffset) {}
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
class CallerSym : public SymbolRecord {
@@ -153,7 +153,7 @@ public:
std::vector<TypeIndex> Indices;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
struct DecodedAnnotation {
@@ -333,7 +333,7 @@ private:
class InlineSiteSym : public SymbolRecord {
public:
explicit InlineSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- InlineSiteSym(uint32_t RecordOffset)
+ explicit InlineSiteSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::InlineSiteSym),
RecordOffset(RecordOffset) {}
@@ -342,12 +342,12 @@ public:
BinaryAnnotationIterator());
}
- uint32_t Parent;
- uint32_t End;
+ uint32_t Parent = 0;
+ uint32_t End = 0;
TypeIndex Inlinee;
std::vector<uint8_t> AnnotationData;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_PUB32
@@ -371,7 +371,7 @@ public:
class RegisterSym : public SymbolRecord {
public:
explicit RegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- RegisterSym(uint32_t RecordOffset)
+ explicit RegisterSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::RegisterSym),
RecordOffset(RecordOffset) {}
@@ -379,7 +379,7 @@ public:
RegisterId Register;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_PROCREF, S_LPROCREF
@@ -390,13 +390,13 @@ public:
: SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset) {
}
- uint32_t SumName;
- uint32_t SymOffset;
- uint16_t Module;
+ uint32_t SumName = 0;
+ uint32_t SymOffset = 0;
+ uint16_t Module = 0;
StringRef Name;
uint16_t modi() const { return Module - 1; }
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_LOCAL
@@ -410,7 +410,7 @@ public:
LocalSymFlags Flags;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
struct LocalVariableAddrRange {
@@ -440,11 +440,11 @@ public:
return RecordOffset + RelocationOffset;
}
- uint32_t Program;
+ uint32_t Program = 0;
LocalVariableAddrRange Range;
std::vector<LocalVariableAddrGap> Gaps;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_DEFRANGE_SUBFIELD
@@ -453,7 +453,7 @@ class DefRangeSubfieldSym : public SymbolRecord {
public:
explicit DefRangeSubfieldSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- DefRangeSubfieldSym(uint32_t RecordOffset)
+ explicit DefRangeSubfieldSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
RecordOffset(RecordOffset) {}
@@ -461,58 +461,62 @@ public:
return RecordOffset + RelocationOffset;
}
- uint32_t Program;
- uint16_t OffsetInParent;
+ uint32_t Program = 0;
+ uint16_t OffsetInParent = 0;
LocalVariableAddrRange Range;
std::vector<LocalVariableAddrGap> Gaps;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
+};
+
+struct DefRangeRegisterHeader {
+ ulittle16_t Register;
+ ulittle16_t MayHaveNoName;
};
// S_DEFRANGE_REGISTER
class DefRangeRegisterSym : public SymbolRecord {
public:
- struct Header {
- ulittle16_t Register;
- ulittle16_t MayHaveNoName;
- };
-
explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- DefRangeRegisterSym(uint32_t RecordOffset)
+ explicit DefRangeRegisterSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
RecordOffset(RecordOffset) {}
- uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
+ uint32_t getRelocationOffset() const { return RecordOffset + sizeof(DefRangeRegisterHeader); }
- Header Hdr;
+ DefRangeRegisterHeader Hdr;
LocalVariableAddrRange Range;
std::vector<LocalVariableAddrGap> Gaps;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
+};
+
+struct DefRangeSubfieldRegisterHeader {
+ ulittle16_t Register;
+ ulittle16_t MayHaveNoName;
+ ulittle32_t OffsetInParent;
};
// S_DEFRANGE_SUBFIELD_REGISTER
class DefRangeSubfieldRegisterSym : public SymbolRecord {
public:
- struct Header {
- ulittle16_t Register;
- ulittle16_t MayHaveNoName;
- ulittle32_t OffsetInParent;
- };
-
explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
: SymbolRecord(Kind) {}
- DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
+ explicit DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
RecordOffset(RecordOffset) {}
- uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
+ uint32_t getRelocationOffset() const { return RecordOffset + sizeof(DefRangeSubfieldRegisterHeader); }
- Header Hdr;
+ DefRangeSubfieldRegisterHeader Hdr;
LocalVariableAddrRange Range;
std::vector<LocalVariableAddrGap> Gaps;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
+};
+
+struct DefRangeFramePointerRelHeader {
+ little32_t Offset;
};
// S_DEFRANGE_FRAMEPOINTER_REL
@@ -522,7 +526,7 @@ class DefRangeFramePointerRelSym : public SymbolRecord {
public:
explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
: SymbolRecord(Kind) {}
- DefRangeFramePointerRelSym(uint32_t RecordOffset)
+ explicit DefRangeFramePointerRelSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
RecordOffset(RecordOffset) {}
@@ -530,22 +534,22 @@ public:
return RecordOffset + RelocationOffset;
}
- int32_t Offset;
+ DefRangeFramePointerRelHeader Hdr;
LocalVariableAddrRange Range;
std::vector<LocalVariableAddrGap> Gaps;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
+};
+
+struct DefRangeRegisterRelHeader {
+ ulittle16_t Register;
+ ulittle16_t Flags;
+ little32_t BasePointerOffset;
};
// S_DEFRANGE_REGISTER_REL
class DefRangeRegisterRelSym : public SymbolRecord {
public:
- struct Header {
- ulittle16_t Register;
- ulittle16_t Flags;
- little32_t BasePointerOffset;
- };
-
explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
@@ -563,13 +567,13 @@ public:
bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
- uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
+ uint32_t getRelocationOffset() const { return RecordOffset + sizeof(DefRangeRegisterRelHeader); }
- Header Hdr;
+ DefRangeRegisterRelHeader Hdr;
LocalVariableAddrRange Range;
std::vector<LocalVariableAddrGap> Gaps;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
@@ -581,9 +585,9 @@ public:
: SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
RecordOffset(RecordOffset) {}
- int32_t Offset;
+ int32_t Offset = 0;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_BLOCK32
@@ -599,14 +603,14 @@ public:
return RecordOffset + RelocationOffset;
}
- uint32_t Parent;
- uint32_t End;
- uint32_t CodeSize;
- uint32_t CodeOffset;
- uint16_t Segment;
+ uint32_t Parent = 0;
+ uint32_t End = 0;
+ uint32_t CodeSize = 0;
+ uint32_t CodeOffset = 0;
+ uint16_t Segment = 0;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_LABEL32
@@ -622,12 +626,12 @@ public:
return RecordOffset + RelocationOffset;
}
- uint32_t CodeOffset;
- uint16_t Segment;
+ uint32_t CodeOffset = 0;
+ uint16_t Segment = 0;
ProcSymFlags Flags;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_OBJNAME
@@ -635,82 +639,82 @@ class ObjNameSym : public SymbolRecord {
public:
explicit ObjNameSym() : SymbolRecord(SymbolRecordKind::ObjNameSym) {}
explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- ObjNameSym(uint32_t RecordOffset)
+ explicit ObjNameSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) {
}
- uint32_t Signature;
+ uint32_t Signature = 0;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_ENVBLOCK
class EnvBlockSym : public SymbolRecord {
public:
explicit EnvBlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- EnvBlockSym(uint32_t RecordOffset)
+ explicit EnvBlockSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::EnvBlockSym),
RecordOffset(RecordOffset) {}
std::vector<StringRef> Fields;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_EXPORT
class ExportSym : public SymbolRecord {
public:
explicit ExportSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- ExportSym(uint32_t RecordOffset)
+ explicit ExportSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset) {}
- uint16_t Ordinal;
+ uint16_t Ordinal = 0;
ExportFlags Flags;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_FILESTATIC
class FileStaticSym : public SymbolRecord {
public:
explicit FileStaticSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- FileStaticSym(uint32_t RecordOffset)
+ explicit FileStaticSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::FileStaticSym),
RecordOffset(RecordOffset) {}
TypeIndex Index;
- uint32_t ModFilenameOffset;
+ uint32_t ModFilenameOffset = 0;
LocalSymFlags Flags;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_COMPILE2
class Compile2Sym : public SymbolRecord {
public:
explicit Compile2Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- Compile2Sym(uint32_t RecordOffset)
+ explicit Compile2Sym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::Compile2Sym),
RecordOffset(RecordOffset) {}
CompileSym2Flags Flags;
CPUType Machine;
- uint16_t VersionFrontendMajor;
- uint16_t VersionFrontendMinor;
- uint16_t VersionFrontendBuild;
- uint16_t VersionBackendMajor;
- uint16_t VersionBackendMinor;
- uint16_t VersionBackendBuild;
+ uint16_t VersionFrontendMajor = 0;
+ uint16_t VersionFrontendMinor = 0;
+ uint16_t VersionFrontendBuild = 0;
+ uint16_t VersionBackendMajor = 0;
+ uint16_t VersionBackendMinor = 0;
+ uint16_t VersionBackendBuild = 0;
StringRef Version;
std::vector<StringRef> ExtraStrings;
uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_COMPILE3
@@ -718,20 +722,20 @@ class Compile3Sym : public SymbolRecord {
public:
Compile3Sym() : SymbolRecord(SymbolRecordKind::Compile3Sym) {}
explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- Compile3Sym(uint32_t RecordOffset)
+ explicit Compile3Sym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::Compile3Sym),
RecordOffset(RecordOffset) {}
CompileSym3Flags Flags;
CPUType Machine;
- uint16_t VersionFrontendMajor;
- uint16_t VersionFrontendMinor;
- uint16_t VersionFrontendBuild;
- uint16_t VersionFrontendQFE;
- uint16_t VersionBackendMajor;
- uint16_t VersionBackendMinor;
- uint16_t VersionBackendBuild;
- uint16_t VersionBackendQFE;
+ uint16_t VersionFrontendMajor = 0;
+ uint16_t VersionFrontendMinor = 0;
+ uint16_t VersionFrontendBuild = 0;
+ uint16_t VersionFrontendQFE = 0;
+ uint16_t VersionBackendMajor = 0;
+ uint16_t VersionBackendMinor = 0;
+ uint16_t VersionBackendBuild = 0;
+ uint16_t VersionBackendQFE = 0;
StringRef Version;
void setLanguage(SourceLanguage Lang) {
@@ -750,7 +754,7 @@ public:
(getFlags() & (CompileSym3Flags::PGO | CompileSym3Flags::LTCG));
}
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_FRAMEPROC
@@ -761,12 +765,12 @@ public:
: SymbolRecord(SymbolRecordKind::FrameProcSym),
RecordOffset(RecordOffset) {}
- uint32_t TotalFrameBytes;
- uint32_t PaddingFrameBytes;
- uint32_t OffsetToPadding;
- uint32_t BytesOfCalleeSavedRegisters;
- uint32_t OffsetOfExceptionHandler;
- uint16_t SectionIdOfExceptionHandler;
+ uint32_t TotalFrameBytes = 0;
+ uint32_t PaddingFrameBytes = 0;
+ uint32_t OffsetToPadding = 0;
+ uint32_t BytesOfCalleeSavedRegisters = 0;
+ uint32_t OffsetOfExceptionHandler = 0;
+ uint16_t SectionIdOfExceptionHandler = 0;
FrameProcedureOptions Flags;
/// Extract the register this frame uses to refer to local variables.
@@ -781,7 +785,7 @@ public:
EncodedFramePtrReg((uint32_t(Flags) >> 16U) & 0x3U), CPU);
}
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
private:
};
@@ -799,11 +803,11 @@ public:
return RecordOffset + RelocationOffset;
}
- uint32_t CodeOffset;
- uint16_t Segment;
+ uint32_t CodeOffset = 0;
+ uint16_t Segment = 0;
TypeIndex Type;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_HEAPALLOCSITE
@@ -820,12 +824,12 @@ public:
return RecordOffset + RelocationOffset;
}
- uint32_t CodeOffset;
- uint16_t Segment;
- uint16_t CallInstructionSize;
+ uint32_t CodeOffset = 0;
+ uint16_t Segment = 0;
+ uint16_t CallInstructionSize = 0;
TypeIndex Type;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_FRAMECOOKIE
@@ -841,12 +845,12 @@ public:
return RecordOffset + RelocationOffset;
}
- uint32_t CodeOffset;
- uint16_t Register;
+ uint32_t CodeOffset = 0;
+ uint16_t Register = 0;
FrameCookieKind CookieKind;
- uint8_t Flags;
+ uint8_t Flags = 0;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_UDT, S_COBOLUDT
@@ -859,20 +863,20 @@ public:
TypeIndex Type;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_BUILDINFO
class BuildInfoSym : public SymbolRecord {
public:
explicit BuildInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- BuildInfoSym(uint32_t RecordOffset)
+ explicit BuildInfoSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::BuildInfoSym),
RecordOffset(RecordOffset) {}
TypeIndex BuildId;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_BPREL32
@@ -883,11 +887,11 @@ public:
: SymbolRecord(SymbolRecordKind::BPRelativeSym),
RecordOffset(RecordOffset) {}
- int32_t Offset;
+ int32_t Offset = 0;
TypeIndex Type;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_REGREL32
@@ -898,19 +902,19 @@ public:
: SymbolRecord(SymbolRecordKind::RegRelativeSym),
RecordOffset(RecordOffset) {}
- uint32_t Offset;
+ uint32_t Offset = 0;
TypeIndex Type;
RegisterId Register;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_CONSTANT, S_MANCONSTANT
class ConstantSym : public SymbolRecord {
public:
explicit ConstantSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- ConstantSym(uint32_t RecordOffset)
+ explicit ConstantSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::ConstantSym),
RecordOffset(RecordOffset) {}
@@ -918,7 +922,7 @@ public:
APSInt Value;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
@@ -927,7 +931,7 @@ class DataSym : public SymbolRecord {
public:
explicit DataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
- DataSym(uint32_t RecordOffset)
+ explicit DataSym(uint32_t RecordOffset)
: SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset) {}
uint32_t getRelocationOffset() const {
@@ -935,11 +939,11 @@ public:
}
TypeIndex Type;
- uint32_t DataOffset;
- uint16_t Segment;
+ uint32_t DataOffset = 0;
+ uint16_t Segment = 0;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_LTHREAD32, S_GTHREAD32
@@ -957,11 +961,11 @@ public:
}
TypeIndex Type;
- uint32_t DataOffset;
- uint16_t Segment;
+ uint32_t DataOffset = 0;
+ uint16_t Segment = 0;
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_UNAMESPACE
@@ -974,7 +978,7 @@ public:
StringRef Name;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
// S_ANNOTATION
@@ -989,7 +993,7 @@ public:
uint16_t Segment = 0;
std::vector<StringRef> Strings;
- uint32_t RecordOffset;
+ uint32_t RecordOffset = 0;
};
using CVSymbol = CVRecord<SymbolKind>;
diff --git a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
index 081de32dd02c..2b17f5ccb13b 100644
--- a/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
+++ b/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
@@ -66,7 +66,7 @@ public:
Error visitTypeBegin(CVType &Record) override {
assert(!Mapping && "Already in a type mapping!");
- Mapping = llvm::make_unique<MappingInfo>(Record.content());
+ Mapping = std::make_unique<MappingInfo>(Record.content());
return Mapping->Mapping.visitTypeBegin(Record);
}
diff --git a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
index 4c309c10ff0c..c6044d5138a8 100644
--- a/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
+++ b/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
@@ -10,6 +10,7 @@
#define LLVM_DEBUGINFO_CODEVIEW_TYPERECORDMAPPING_H
#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
#include "llvm/Support/Error.h"
diff --git a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
index 169715be2d52..fb0b579d6a06 100644
--- a/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
+++ b/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
@@ -82,11 +82,6 @@ public:
Pipeline.push_back(&Callbacks);
}
- void addCallbackToPipelineFront(TypeVisitorCallbacks &Callbacks) {
- auto CallBackItr = Pipeline.begin();
- Pipeline.insert(CallBackItr, &Callbacks);
- }
-
#define TYPE_RECORD(EnumName, EnumVal, Name) \
Error visitKnownRecord(CVType &CVR, Name##Record &Record) override { \
return visitKnownRecordImpl(CVR, Record); \
diff --git a/include/llvm/DebugInfo/DIContext.h b/include/llvm/DebugInfo/DIContext.h
index d2a5318179eb..fbebfe634b63 100644
--- a/include/llvm/DebugInfo/DIContext.h
+++ b/include/llvm/DebugInfo/DIContext.h
@@ -28,6 +28,10 @@ namespace llvm {
/// A format-neutral container for source line information.
struct DILineInfo {
+ // DILineInfo contains "<invalid>" for function/filename it cannot fetch.
+ static constexpr const char *const BadString = "<invalid>";
+ // Use "??" instead of "<invalid>" to make our output closer to addr2line.
+ static constexpr const char *const Addr2LineBadString = "??";
std::string FileName;
std::string FunctionName;
Optional<StringRef> Source;
@@ -38,7 +42,7 @@ struct DILineInfo {
// DWARF-specific.
uint32_t Discriminator = 0;
- DILineInfo() : FileName("<invalid>"), FunctionName("<invalid>") {}
+ DILineInfo() : FileName(BadString), FunctionName(BadString) {}
bool operator==(const DILineInfo &RHS) const {
return Line == RHS.Line && Column == RHS.Column &&
@@ -61,9 +65,9 @@ struct DILineInfo {
void dump(raw_ostream &OS) {
OS << "Line info: ";
- if (FileName != "<invalid>")
+ if (FileName != BadString)
OS << "file '" << FileName << "', ";
- if (FunctionName != "<invalid>")
+ if (FunctionName != BadString)
OS << "function '" << FunctionName << "', ";
OS << "line " << Line << ", ";
OS << "column " << Column << ", ";
@@ -109,7 +113,7 @@ struct DIGlobal {
uint64_t Start = 0;
uint64_t Size = 0;
- DIGlobal() : Name("<invalid>") {}
+ DIGlobal() : Name(DILineInfo::BadString) {}
};
struct DILocal {
@@ -289,7 +293,7 @@ public:
LoadedObjectInfoHelper(Ts &&... Args) : Base(std::forward<Ts>(Args)...) {}
std::unique_ptr<llvm::LoadedObjectInfo> clone() const override {
- return llvm::make_unique<Derived>(static_cast<const Derived &>(*this));
+ return std::make_unique<Derived>(static_cast<const Derived &>(*this));
}
};
diff --git a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
index ccf2891c2e21..39ae53c4e7fe 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h
@@ -130,11 +130,11 @@ public:
/// \param Attr DWARF attribute to search for.
/// \param U the DWARFUnit the contains the DIE.
/// \returns Optional DWARF form value if the attribute was extracted.
- Optional<DWARFFormValue> getAttributeValue(const uint32_t DIEOffset,
+ Optional<DWARFFormValue> getAttributeValue(const uint64_t DIEOffset,
const dwarf::Attribute Attr,
const DWARFUnit &U) const;
- bool extract(DataExtractor Data, uint32_t* OffsetPtr);
+ bool extract(DataExtractor Data, uint64_t* OffsetPtr);
void dump(raw_ostream &OS) const;
// Return an optional byte size of all attribute data in this abbreviation
diff --git a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index 303375703d2e..c9042e593260 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -96,7 +96,7 @@ class AppleAcceleratorTable : public DWARFAcceleratorTable {
using AtomType = uint16_t;
using Form = dwarf::Form;
- uint32_t DIEOffsetBase;
+ uint64_t DIEOffsetBase;
SmallVector<std::pair<AtomType, Form>, 3> Atoms;
Optional<uint64_t> extractOffset(Optional<DWARFFormValue> Value) const;
@@ -109,7 +109,7 @@ class AppleAcceleratorTable : public DWARFAcceleratorTable {
/// Returns true if we should continue scanning for entries or false if we've
/// reached the last (sentinel) entry of encountered a parsing error.
bool dumpName(ScopedPrinter &W, SmallVectorImpl<DWARFFormValue> &AtomForms,
- uint32_t *DataOffset) const;
+ uint64_t *DataOffset) const;
public:
/// Apple-specific implementation of an Accelerator Entry.
@@ -119,7 +119,7 @@ public:
Entry(const HeaderData &Data);
Entry() = default;
- void extract(const AppleAcceleratorTable &AccelTable, uint32_t *Offset);
+ void extract(const AppleAcceleratorTable &AccelTable, uint64_t *Offset);
public:
Optional<uint64_t> getCUOffset() const override;
@@ -143,7 +143,7 @@ public:
class ValueIterator : public std::iterator<std::input_iterator_tag, Entry> {
const AppleAcceleratorTable *AccelTable = nullptr;
Entry Current; ///< The current entry.
- unsigned DataOffset = 0; ///< Offset into the section.
+ uint64_t DataOffset = 0; ///< Offset into the section.
unsigned Data = 0; ///< Current data entry.
unsigned NumData = 0; ///< Number of data entries.
@@ -151,7 +151,7 @@ public:
void Next();
public:
/// Construct a new iterator for the entries at \p DataOffset.
- ValueIterator(const AppleAcceleratorTable &AccelTable, unsigned DataOffset);
+ ValueIterator(const AppleAcceleratorTable &AccelTable, uint64_t DataOffset);
/// End marker.
ValueIterator() = default;
@@ -193,7 +193,7 @@ public:
/// DieOffset is the offset into the .debug_info section for the DIE
/// related to the input hash data offset.
/// DieTag is the tag of the DIE
- std::pair<uint32_t, dwarf::Tag> readAtoms(uint32_t &HashDataOffset);
+ std::pair<uint64_t, dwarf::Tag> readAtoms(uint64_t *HashDataOffset);
void dump(raw_ostream &OS) const override;
/// Look up all entries in the accelerator table matching \c Key.
@@ -245,7 +245,7 @@ public:
struct Header : public HeaderPOD {
SmallString<8> AugmentationString;
- Error extract(const DWARFDataExtractor &AS, uint32_t *Offset);
+ Error extract(const DWARFDataExtractor &AS, uint64_t *Offset);
void dump(ScopedPrinter &W) const;
};
@@ -354,12 +354,12 @@ public:
DataExtractor StrData;
uint32_t Index;
- uint32_t StringOffset;
- uint32_t EntryOffset;
+ uint64_t StringOffset;
+ uint64_t EntryOffset;
public:
NameTableEntry(const DataExtractor &StrData, uint32_t Index,
- uint32_t StringOffset, uint32_t EntryOffset)
+ uint64_t StringOffset, uint64_t EntryOffset)
: StrData(StrData), Index(Index), StringOffset(StringOffset),
EntryOffset(EntryOffset) {}
@@ -367,17 +367,17 @@ public:
uint32_t getIndex() const { return Index; }
/// Returns the offset of the name of the described entities.
- uint32_t getStringOffset() const { return StringOffset; }
+ uint64_t getStringOffset() const { return StringOffset; }
/// Return the string referenced by this name table entry or nullptr if the
/// string offset is not valid.
const char *getString() const {
- uint32_t Off = StringOffset;
+ uint64_t Off = StringOffset;
return StrData.getCStr(&Off);
}
/// Returns the offset of the first Entry in the list.
- uint32_t getEntryOffset() const { return EntryOffset; }
+ uint64_t getEntryOffset() const { return EntryOffset; }
};
/// Represents a single accelerator table within the DWARF v5 .debug_names
@@ -389,40 +389,40 @@ public:
// Base of the whole unit and of various important tables, as offsets from
// the start of the section.
- uint32_t Base;
- uint32_t CUsBase;
- uint32_t BucketsBase;
- uint32_t HashesBase;
- uint32_t StringOffsetsBase;
- uint32_t EntryOffsetsBase;
- uint32_t EntriesBase;
+ uint64_t Base;
+ uint64_t CUsBase;
+ uint64_t BucketsBase;
+ uint64_t HashesBase;
+ uint64_t StringOffsetsBase;
+ uint64_t EntryOffsetsBase;
+ uint64_t EntriesBase;
void dumpCUs(ScopedPrinter &W) const;
void dumpLocalTUs(ScopedPrinter &W) const;
void dumpForeignTUs(ScopedPrinter &W) const;
void dumpAbbreviations(ScopedPrinter &W) const;
- bool dumpEntry(ScopedPrinter &W, uint32_t *Offset) const;
+ bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
Optional<uint32_t> Hash) const;
void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
- Expected<AttributeEncoding> extractAttributeEncoding(uint32_t *Offset);
+ Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
Expected<std::vector<AttributeEncoding>>
- extractAttributeEncodings(uint32_t *Offset);
+ extractAttributeEncodings(uint64_t *Offset);
- Expected<Abbrev> extractAbbrev(uint32_t *Offset);
+ Expected<Abbrev> extractAbbrev(uint64_t *Offset);
public:
- NameIndex(const DWARFDebugNames &Section, uint32_t Base)
+ NameIndex(const DWARFDebugNames &Section, uint64_t Base)
: Section(Section), Base(Base) {}
/// Reads offset of compilation unit CU. CU is 0-based.
- uint32_t getCUOffset(uint32_t CU) const;
+ uint64_t getCUOffset(uint32_t CU) const;
uint32_t getCUCount() const { return Hdr.CompUnitCount; }
/// Reads offset of local type unit TU, TU is 0-based.
- uint32_t getLocalTUOffset(uint32_t TU) const;
+ uint64_t getLocalTUOffset(uint32_t TU) const;
uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
/// Reads signature of foreign type unit TU. TU is 0-based.
@@ -451,7 +451,7 @@ public:
return Abbrevs;
}
- Expected<Entry> getEntry(uint32_t *Offset) const;
+ Expected<Entry> getEntry(uint64_t *Offset) const;
/// Look up all entries in this Name Index matching \c Key.
iterator_range<ValueIterator> equal_range(StringRef Key) const;
@@ -460,8 +460,8 @@ public:
NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
Error extract();
- uint32_t getUnitOffset() const { return Base; }
- uint32_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; }
+ uint64_t getUnitOffset() const { return Base; }
+ uint64_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; }
void dump(ScopedPrinter &W) const;
friend class DWARFDebugNames;
@@ -479,12 +479,12 @@ public:
bool IsLocal;
Optional<Entry> CurrentEntry;
- unsigned DataOffset = 0; ///< Offset into the section.
+ uint64_t DataOffset = 0; ///< Offset into the section.
std::string Key; ///< The Key we are searching for.
Optional<uint32_t> Hash; ///< Hash of Key, if it has been computed.
bool getEntryAtCurrentOffset();
- Optional<uint32_t> findEntryOffsetInCurrentIndex();
+ Optional<uint64_t> findEntryOffsetInCurrentIndex();
bool findInCurrentIndex();
void searchFromStartOfCurrentIndex();
void next();
@@ -572,7 +572,7 @@ public:
private:
SmallVector<NameIndex, 0> NameIndices;
- DenseMap<uint32_t, const NameIndex *> CUToNameIndex;
+ DenseMap<uint64_t, const NameIndex *> CUToNameIndex;
public:
DWARFDebugNames(const DWARFDataExtractor &AccelSection,
@@ -591,7 +591,7 @@ public:
/// Return the Name Index covering the compile unit at CUOffset, or nullptr if
/// there is no Name Index covering that unit.
- const NameIndex *getCUNameIndex(uint32_t CUOffset);
+ const NameIndex *getCUNameIndex(uint64_t CUOffset);
};
} // end namespace llvm
diff --git a/include/llvm/DebugInfo/DWARF/DWARFAttribute.h b/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
index c8ad19ad6bf6..dfc778346dbe 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
@@ -23,7 +23,7 @@ namespace llvm {
/// attributes in a DWARFDie.
struct DWARFAttribute {
/// The debug info/types offset for this attribute.
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
/// The debug info/types section byte size of the data for this attribute.
uint32_t ByteSize = 0;
/// The attribute enumeration of this attribute.
diff --git a/include/llvm/DebugInfo/DWARF/DWARFContext.h b/include/llvm/DebugInfo/DWARF/DWARFContext.h
index 23cf21c3523f..fae163622edb 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -225,10 +225,10 @@ public:
DWARFCompileUnit *getDWOCompileUnitForHash(uint64_t Hash);
/// Return the compile unit that includes an offset (relative to .debug_info).
- DWARFCompileUnit *getCompileUnitForOffset(uint32_t Offset);
+ DWARFCompileUnit *getCompileUnitForOffset(uint64_t Offset);
/// Get a DIE given an exact offset.
- DWARFDie getDIEForOffset(uint32_t Offset);
+ DWARFDie getDIEForOffset(uint64_t Offset);
unsigned getMaxVersion() {
// Ensure info units have been parsed to discover MaxVersion
@@ -301,10 +301,10 @@ public:
std::function<void(Error)> RecoverableErrorCallback);
DataExtractor getStringExtractor() const {
- return DataExtractor(DObj->getStringSection(), false, 0);
+ return DataExtractor(DObj->getStrSection(), false, 0);
}
DataExtractor getLineStringExtractor() const {
- return DataExtractor(DObj->getLineStringSection(), false, 0);
+ return DataExtractor(DObj->getLineStrSection(), false, 0);
}
/// Wraps the returned DIEs for a given address.
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h b/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
index 7c2a159b71fa..980724c525d2 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDataExtractor.h
@@ -35,20 +35,25 @@ public:
/// Extracts a value and applies a relocation to the result if
/// one exists for the given offset.
- uint64_t getRelocatedValue(uint32_t Size, uint32_t *Off,
- uint64_t *SectionIndex = nullptr) const;
+ uint64_t getRelocatedValue(uint32_t Size, uint64_t *Off,
+ uint64_t *SectionIndex = nullptr,
+ Error *Err = nullptr) const;
/// Extracts an address-sized value and applies a relocation to the result if
/// one exists for the given offset.
- uint64_t getRelocatedAddress(uint32_t *Off, uint64_t *SecIx = nullptr) const {
+ uint64_t getRelocatedAddress(uint64_t *Off, uint64_t *SecIx = nullptr) const {
return getRelocatedValue(getAddressSize(), Off, SecIx);
}
+ uint64_t getRelocatedAddress(Cursor &C, uint64_t *SecIx = nullptr) const {
+ return getRelocatedValue(getAddressSize(), &getOffset(C), SecIx,
+ &getError(C));
+ }
/// Extracts a DWARF-encoded pointer in \p Offset using \p Encoding.
/// There is a DWARF encoding that uses a PC-relative adjustment.
/// For these values, \p AbsPosOffset is used to fix them, which should
/// reflect the absolute address of this pointer.
- Optional<uint64_t> getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
+ Optional<uint64_t> getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
uint64_t AbsPosOffset = 0) const;
size_t size() const { return Section == nullptr ? 0 : Section->Data.size(); }
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
index 28fd8484b4a9..1398e16252a9 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h
@@ -20,7 +20,7 @@ namespace llvm {
class raw_ostream;
class DWARFAbbreviationDeclarationSet {
- uint32_t Offset;
+ uint64_t Offset;
/// Code of the first abbreviation, if all abbreviations in the set have
/// consecutive codes. UINT32_MAX otherwise.
uint32_t FirstAbbrCode;
@@ -32,9 +32,9 @@ class DWARFAbbreviationDeclarationSet {
public:
DWARFAbbreviationDeclarationSet();
- uint32_t getOffset() const { return Offset; }
+ uint64_t getOffset() const { return Offset; }
void dump(raw_ostream &OS) const;
- bool extract(DataExtractor Data, uint32_t *OffsetPtr);
+ bool extract(DataExtractor Data, uint64_t *OffsetPtr);
const DWARFAbbreviationDeclaration *
getAbbreviationDeclaration(uint32_t AbbrCode) const;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
index a98bf282fe7c..4539b9c9d581 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAddr.h
@@ -45,7 +45,7 @@ public:
private:
dwarf::DwarfFormat Format;
- uint32_t HeaderOffset;
+ uint64_t HeaderOffset;
Header HeaderData;
uint32_t DataSize = 0;
std::vector<uint64_t> Addrs;
@@ -54,11 +54,11 @@ public:
void clear();
/// Extract an entire table, including all addresses.
- Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr,
+ Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr,
uint16_t Version, uint8_t AddrSize,
std::function<void(Error)> WarnCallback);
- uint32_t getHeaderOffset() const { return HeaderOffset; }
+ uint64_t getHeaderOffset() const { return HeaderOffset; }
uint8_t getAddrSize() const { return HeaderData.AddrSize; }
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
index 5b6c578bc3bf..ebe4ad6e24dd 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h
@@ -49,7 +49,7 @@ private:
using DescriptorColl = std::vector<Descriptor>;
using desc_iterator_range = iterator_range<DescriptorColl::const_iterator>;
- uint32_t Offset;
+ uint64_t Offset;
Header HeaderData;
DescriptorColl ArangeDescriptors;
@@ -57,7 +57,7 @@ public:
DWARFDebugArangeSet() { clear(); }
void clear();
- bool extract(DataExtractor data, uint32_t *offset_ptr);
+ bool extract(DataExtractor data, uint64_t *offset_ptr);
void dump(raw_ostream &OS) const;
uint32_t getCompileUnitDIEOffset() const { return HeaderData.CuOffset; }
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
index 03223fbc80a9..172f1d2c9dbe 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
@@ -28,7 +28,7 @@ private:
void extract(DataExtractor DebugArangesData);
/// Call appendRange multiple times and then call construct.
- void appendRange(uint32_t CUOffset, uint64_t LowPC, uint64_t HighPC);
+ void appendRange(uint64_t CUOffset, uint64_t LowPC, uint64_t HighPC);
void construct();
struct Range {
@@ -60,10 +60,10 @@ private:
struct RangeEndpoint {
uint64_t Address;
- uint32_t CUOffset;
+ uint64_t CUOffset;
bool IsRangeStart;
- RangeEndpoint(uint64_t Address, uint32_t CUOffset, bool IsRangeStart)
+ RangeEndpoint(uint64_t Address, uint64_t CUOffset, bool IsRangeStart)
: Address(Address), CUOffset(CUOffset), IsRangeStart(IsRangeStart) {}
bool operator<(const RangeEndpoint &Other) const {
@@ -76,7 +76,7 @@ private:
std::vector<RangeEndpoint> Endpoints;
RangeColl Aranges;
- DenseSet<uint32_t> ParsedCUOffsets;
+ DenseSet<uint64_t> ParsedCUOffsets;
};
} // end namespace llvm
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
index d960f4bc9b1c..c6539df0d756 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h
@@ -69,7 +69,7 @@ public:
/// starting at *Offset and ending at EndOffset. *Offset is updated
/// to EndOffset upon successful parsing, or indicates the offset
/// where a problem occurred in case an error is returned.
- Error parse(DataExtractor Data, uint32_t *Offset, uint32_t EndOffset);
+ Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset);
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
unsigned IndentLevel = 1) const;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h
index f50063b24370..ded960337ec6 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h
@@ -22,7 +22,7 @@ class DWARFUnit;
/// DWARFDebugInfoEntry - A DIE with only the minimum required data.
class DWARFDebugInfoEntry {
/// Offset within the .debug_info of the start of this entry.
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
/// The integer depth of this DIE within the compile unit DIEs where the
/// compile/type unit DIE has a depth of zero.
@@ -36,14 +36,14 @@ public:
/// Extracts a debug info entry, which is a child of a given unit,
/// starting at a given offset. If DIE can't be extracted, returns false and
/// doesn't change OffsetPtr.
- bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr);
+ bool extractFast(const DWARFUnit &U, uint64_t *OffsetPtr);
/// High performance extraction should use this call.
- bool extractFast(const DWARFUnit &U, uint32_t *OffsetPtr,
- const DWARFDataExtractor &DebugInfoData, uint32_t UEndOffset,
+ bool extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
+ const DWARFDataExtractor &DebugInfoData, uint64_t UEndOffset,
uint32_t Depth);
- uint32_t getOffset() const { return Offset; }
+ uint64_t getOffset() const { return Offset; }
uint32_t getDepth() const { return Depth; }
dwarf::Tag getTag() const {
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index e7425c192373..c2be8304ad84 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -18,6 +18,7 @@
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
#include "llvm/Support/MD5.h"
+#include "llvm/Support/Path.h"
#include <cstdint>
#include <map>
#include <string>
@@ -128,13 +129,15 @@ public:
bool hasFileAtIndex(uint64_t FileIndex) const;
- bool getFileNameByIndex(uint64_t FileIndex, StringRef CompDir,
- DILineInfoSpecifier::FileLineInfoKind Kind,
- std::string &Result) const;
+ bool
+ getFileNameByIndex(uint64_t FileIndex, StringRef CompDir,
+ DILineInfoSpecifier::FileLineInfoKind Kind,
+ std::string &Result,
+ sys::path::Style Style = sys::path::Style::native) const;
void clear();
void dump(raw_ostream &OS, DIDumpOptions DumpOptions) const;
- Error parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
+ Error parse(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
const DWARFContext &Ctx, const DWARFUnit *U = nullptr);
};
@@ -278,7 +281,7 @@ public:
/// Parse prologue and all rows.
Error parse(
- DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
+ DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
const DWARFContext &Ctx, const DWARFUnit *U,
std::function<void(Error)> RecoverableErrorCallback,
raw_ostream *OS = nullptr);
@@ -305,9 +308,9 @@ public:
std::vector<uint32_t> &Result) const;
};
- const LineTable *getLineTable(uint32_t Offset) const;
+ const LineTable *getLineTable(uint64_t Offset) const;
Expected<const LineTable *> getOrParseLineTable(
- DWARFDataExtractor &DebugLineData, uint32_t Offset,
+ DWARFDataExtractor &DebugLineData, uint64_t Offset,
const DWARFContext &Ctx, const DWARFUnit *U,
std::function<void(Error)> RecoverableErrorCallback);
@@ -350,17 +353,17 @@ public:
bool done() const { return Done; }
/// Get the offset the parser has reached.
- uint32_t getOffset() const { return Offset; }
+ uint64_t getOffset() const { return Offset; }
private:
- DWARFUnit *prepareToParse(uint32_t Offset);
- void moveToNextTable(uint32_t OldOffset, const Prologue &P);
+ DWARFUnit *prepareToParse(uint64_t Offset);
+ void moveToNextTable(uint64_t OldOffset, const Prologue &P);
LineToUnitMap LineToUnit;
DWARFDataExtractor &DebugLineData;
const DWARFContext &Context;
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
bool Done = false;
};
@@ -377,7 +380,7 @@ private:
struct Sequence Sequence;
};
- using LineTableMapTy = std::map<uint32_t, LineTable>;
+ using LineTableMapTy = std::map<uint64_t, LineTable>;
using LineTableIter = LineTableMapTy::iterator;
using LineTableConstIter = LineTableMapTy::const_iterator;
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
index cced6048e811..c79d98e34f6e 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
@@ -11,6 +11,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include <cstdint>
@@ -29,19 +30,20 @@ public:
/// The ending address of the instruction range.
uint64_t End;
/// The location of the variable within the specified range.
- SmallVector<char, 4> Loc;
+ SmallVector<uint8_t, 4> Loc;
};
/// A list of locations that contain one variable.
struct LocationList {
/// The beginning offset where this location list is stored in the debug_loc
/// section.
- unsigned Offset;
+ uint64_t Offset;
/// All the locations in which the variable is stored.
SmallVector<Entry, 2> Entries;
/// Dump this list on OS.
- void dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize,
- const MCRegisterInfo *MRI, DWARFUnit *U, uint64_t BaseAddress,
+ void dump(raw_ostream &OS, uint64_t BaseAddress, bool IsLittleEndian,
+ unsigned AddressSize, const MCRegisterInfo *MRI, DWARFUnit *U,
+ DIDumpOptions DumpOpts,
unsigned Indent) const;
};
@@ -58,7 +60,7 @@ private:
public:
/// Print the location lists found within the debug_loc section.
- void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo,
+ void dump(raw_ostream &OS, const MCRegisterInfo *RegInfo, DIDumpOptions DumpOpts,
Optional<uint64_t> Offset) const;
/// Parse the debug_loc section accessible via the 'data' parameter using the
@@ -68,25 +70,29 @@ public:
/// Return the location list at the given offset or nullptr.
LocationList const *getLocationListAtOffset(uint64_t Offset) const;
- Optional<LocationList> parseOneLocationList(DWARFDataExtractor Data,
- uint32_t *Offset);
+ Expected<LocationList>
+ parseOneLocationList(const DWARFDataExtractor &Data, uint64_t *Offset);
};
class DWARFDebugLoclists {
public:
struct Entry {
uint8_t Kind;
+ uint64_t Offset;
uint64_t Value0;
uint64_t Value1;
- SmallVector<char, 4> Loc;
+ SmallVector<uint8_t, 4> Loc;
+ void dump(raw_ostream &OS, uint64_t &BaseAddr, bool IsLittleEndian,
+ unsigned AddressSize, const MCRegisterInfo *MRI, DWARFUnit *U,
+ DIDumpOptions DumpOpts, unsigned Indent, size_t MaxEncodingStringLength) const;
};
struct LocationList {
- unsigned Offset;
+ uint64_t Offset;
SmallVector<Entry, 2> Entries;
void dump(raw_ostream &OS, uint64_t BaseAddr, bool IsLittleEndian,
unsigned AddressSize, const MCRegisterInfo *RegInfo,
- DWARFUnit *U, unsigned Indent) const;
+ DWARFUnit *U, DIDumpOptions DumpOpts, unsigned Indent) const;
};
private:
@@ -99,15 +105,16 @@ private:
bool IsLittleEndian;
public:
- void parse(DataExtractor data, unsigned Version);
+ void parse(DataExtractor data, uint64_t Offset, uint64_t EndOffset, uint16_t Version);
void dump(raw_ostream &OS, uint64_t BaseAddr, const MCRegisterInfo *RegInfo,
- Optional<uint64_t> Offset) const;
+ DIDumpOptions DumpOpts, Optional<uint64_t> Offset) const;
/// Return the location list at the given offset or nullptr.
LocationList const *getLocationListAtOffset(uint64_t Offset) const;
- static Optional<LocationList>
- parseOneLocationList(DataExtractor Data, unsigned *Offset, unsigned Version);
+ static Expected<LocationList> parseOneLocationList(const DataExtractor &Data,
+ uint64_t *Offset,
+ unsigned Version);
};
} // end namespace llvm
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
index 99e91ca90319..ae57306b90e1 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugPubTable.h
@@ -25,7 +25,7 @@ class DWARFDebugPubTable {
public:
struct Entry {
/// Section offset from the beginning of the compilation unit.
- uint32_t SecOffset;
+ uint64_t SecOffset;
/// An entry of the various gnu_pub* debug sections.
dwarf::PubIndexEntryDescriptor Descriptor;
@@ -50,7 +50,7 @@ public:
/// The offset from the beginning of the .debug_info section of the
/// compilation unit header referenced by the set.
- uint32_t Offset;
+ uint64_t Offset;
/// The size in bytes of the contents of the .debug_info section generated
/// to represent that compilation unit.
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index a66f60292343..2f72c642a2d5 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -53,14 +53,13 @@ public:
assert(AddressSize == 4 || AddressSize == 8);
if (AddressSize == 4)
return StartAddress == -1U;
- else
- return StartAddress == -1ULL;
+ return StartAddress == -1ULL;
}
};
private:
/// Offset in .debug_ranges section.
- uint32_t Offset;
+ uint64_t Offset;
uint8_t AddressSize;
std::vector<RangeListEntry> Entries;
@@ -69,7 +68,7 @@ public:
void clear();
void dump(raw_ostream &OS) const;
- Error extract(const DWARFDataExtractor &data, uint32_t *offset_ptr);
+ Error extract(const DWARFDataExtractor &data, uint64_t *offset_ptr);
const std::vector<RangeListEntry> &getEntries() { return Entries; }
/// getAbsoluteRanges - Returns absolute address ranges defined by this range
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index 167ddde3ec3d..952c41e188c7 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -34,7 +34,7 @@ struct RangeListEntry : public DWARFListEntryBase {
uint64_t Value0;
uint64_t Value1;
- Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr);
+ Error extract(DWARFDataExtractor Data, uint64_t End, uint64_t *OffsetPtr);
void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
uint64_t &CurrentBase, DIDumpOptions DumpOpts,
llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
diff --git a/include/llvm/DebugInfo/DWARF/DWARFDie.h b/include/llvm/DebugInfo/DWARF/DWARFDie.h
index 21e68f983bb3..f7f08b4a499d 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFDie.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFDie.h
@@ -63,7 +63,7 @@ public:
/// Get the absolute offset into the debug info or types section.
///
/// \returns the DIE offset or -1U if invalid.
- uint32_t getOffset() const {
+ uint64_t getOffset() const {
assert(isValid() && "must check validity prior to calling");
return Die->getOffset();
}
diff --git a/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/include/llvm/DebugInfo/DWARF/DWARFExpression.h
index f066dd58d606..456d9df957ad 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFExpression.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFExpression.h
@@ -77,18 +77,18 @@ public:
uint8_t Opcode; ///< The Op Opcode, DW_OP_<something>.
Description Desc;
bool Error;
- uint32_t EndOffset;
+ uint64_t EndOffset;
uint64_t Operands[2];
- uint32_t OperandEndOffsets[2];
+ uint64_t OperandEndOffsets[2];
public:
Description &getDescription() { return Desc; }
uint8_t getCode() { return Opcode; }
uint64_t getRawOperand(unsigned Idx) { return Operands[Idx]; }
- uint32_t getOperandEndOffset(unsigned Idx) { return OperandEndOffsets[Idx]; }
- uint32_t getEndOffset() { return EndOffset; }
+ uint64_t getOperandEndOffset(unsigned Idx) { return OperandEndOffsets[Idx]; }
+ uint64_t getEndOffset() { return EndOffset; }
bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
- uint32_t Offset);
+ uint64_t Offset);
bool isError() { return Error; }
bool print(raw_ostream &OS, const DWARFExpression *Expr,
const MCRegisterInfo *RegInfo, DWARFUnit *U, bool isEH);
@@ -101,9 +101,9 @@ public:
Operation> {
friend class DWARFExpression;
const DWARFExpression *Expr;
- uint32_t Offset;
+ uint64_t Offset;
Operation Op;
- iterator(const DWARFExpression *Expr, uint32_t Offset)
+ iterator(const DWARFExpression *Expr, uint64_t Offset)
: Expr(Expr), Offset(Offset) {
Op.Error =
Offset >= Expr->Data.getData().size() ||
diff --git a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index 731e71ed9eae..6fec6fcb6b34 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -70,7 +70,7 @@ public:
static DWARFFormValue createFromBlockValue(dwarf::Form F,
ArrayRef<uint8_t> D);
static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit,
- uint32_t *OffsetPtr);
+ uint64_t *OffsetPtr);
dwarf::Form getForm() const { return Form; }
uint64_t getRawUValue() const { return Value.uval; }
@@ -87,12 +87,12 @@ public:
/// in \p FormParams is needed to interpret some forms. The optional
/// \p Context and \p Unit allows extracting information if the form refers
/// to other sections (e.g., .debug_str).
- bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr,
+ bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
dwarf::FormParams FormParams,
const DWARFContext *Context = nullptr,
const DWARFUnit *Unit = nullptr);
- bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr,
+ bool extractValue(const DWARFDataExtractor &Data, uint64_t *OffsetPtr,
dwarf::FormParams FormParams, const DWARFUnit *U) {
return extractValue(Data, OffsetPtr, FormParams, nullptr, U);
}
@@ -128,7 +128,7 @@ public:
/// \param OffsetPtr A reference to the offset that will be updated.
/// \param Params DWARF parameters to help interpret forms.
/// \returns true on success, false if the form was not skipped.
- bool skipValue(DataExtractor DebugInfoData, uint32_t *OffsetPtr,
+ bool skipValue(DataExtractor DebugInfoData, uint64_t *OffsetPtr,
const dwarf::FormParams Params) const {
return DWARFFormValue::skipValue(Form, DebugInfoData, OffsetPtr, Params);
}
@@ -144,7 +144,7 @@ public:
/// \param FormParams DWARF parameters to help interpret forms.
/// \returns true on success, false if the form was not skipped.
static bool skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
- uint32_t *OffsetPtr,
+ uint64_t *OffsetPtr,
const dwarf::FormParams FormParams);
private:
diff --git a/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/include/llvm/DebugInfo/DWARF/DWARFListTable.h
index a1ea69b040f0..496fdb2477f9 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -26,7 +26,7 @@ namespace llvm {
/// entries.
struct DWARFListEntryBase {
/// The offset at which the entry is located in the section.
- uint32_t Offset;
+ uint64_t Offset;
/// The DWARF encoding (DW_RLE_* or DW_LLE_*).
uint8_t EntryKind;
/// The index of the section this entry belongs to.
@@ -46,8 +46,8 @@ public:
const ListEntries &getEntries() const { return Entries; }
bool empty() const { return Entries.empty(); }
void clear() { Entries.clear(); }
- Error extract(DWARFDataExtractor Data, uint32_t HeaderOffset, uint32_t End,
- uint32_t *OffsetPtr, StringRef SectionName,
+ Error extract(DWARFDataExtractor Data, uint64_t HeaderOffset, uint64_t End,
+ uint64_t *OffsetPtr, StringRef SectionName,
StringRef ListStringName);
};
@@ -57,7 +57,7 @@ class DWARFListTableHeader {
struct Header {
/// The total length of the entries for this table, not including the length
/// field itself.
- uint32_t Length = 0;
+ uint64_t Length = 0;
/// The DWARF version number.
uint16_t Version;
/// The size in bytes of an address on the target architecture. For
@@ -75,12 +75,12 @@ class DWARFListTableHeader {
/// The offset table, which contains offsets to the individual list entries.
/// It is used by forms such as DW_FORM_rnglistx.
/// FIXME: Generate the table and use the appropriate forms.
- std::vector<uint32_t> Offsets;
+ std::vector<uint64_t> Offsets;
/// The table's format, either DWARF32 or DWARF64.
dwarf::DwarfFormat Format;
/// The offset at which the header (and hence the table) is located within
/// its section.
- uint32_t HeaderOffset;
+ uint64_t HeaderOffset;
/// The name of the section the list is located in.
StringRef SectionName;
/// A characterization of the list for dumping purposes, e.g. "range" or
@@ -95,28 +95,40 @@ public:
HeaderData = {};
Offsets.clear();
}
- uint32_t getHeaderOffset() const { return HeaderOffset; }
+ uint64_t getHeaderOffset() const { return HeaderOffset; }
uint8_t getAddrSize() const { return HeaderData.AddrSize; }
- uint32_t getLength() const { return HeaderData.Length; }
+ uint64_t getLength() const { return HeaderData.Length; }
uint16_t getVersion() const { return HeaderData.Version; }
StringRef getSectionName() const { return SectionName; }
StringRef getListTypeString() const { return ListTypeString; }
dwarf::DwarfFormat getFormat() const { return Format; }
+ /// Return the size of the table header including the length but not including
+ /// the offsets.
+ static uint8_t getHeaderSize(dwarf::DwarfFormat Format) {
+ switch (Format) {
+ case dwarf::DwarfFormat::DWARF32:
+ return 12;
+ case dwarf::DwarfFormat::DWARF64:
+ return 20;
+ }
+ llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
+ }
+
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) const;
- Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+ Optional<uint64_t> getOffsetEntry(uint32_t Index) const {
if (Index < Offsets.size())
return Offsets[Index];
return None;
}
/// Extract the table header and the array of offsets.
- Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);
+ Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
/// Returns the length of the table, including the length field, or 0 if the
/// length has not been determined (e.g. because the table has not yet been
/// parsed, or there was a problem in parsing).
- uint32_t length() const;
+ uint64_t length() const;
};
/// A class representing a table of lists as specified in the DWARF v5
@@ -128,7 +140,7 @@ template <typename DWARFListType> class DWARFListTableBase {
DWARFListTableHeader Header;
/// A mapping between file offsets and lists. It is used to find a particular
/// list based on an offset (obtained from DW_AT_ranges, for example).
- std::map<uint32_t, DWARFListType> ListMap;
+ std::map<uint64_t, DWARFListType> ListMap;
/// This string is displayed as a heading before the list is dumped
/// (e.g. "ranges:").
StringRef HeaderString;
@@ -144,17 +156,18 @@ public:
ListMap.clear();
}
/// Extract the table header and the array of offsets.
- Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint32_t *OffsetPtr) {
+ Error extractHeaderAndOffsets(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
return Header.extract(Data, OffsetPtr);
}
/// Extract an entire table, including all list entries.
- Error extract(DWARFDataExtractor Data, uint32_t *OffsetPtr);
+ Error extract(DWARFDataExtractor Data, uint64_t *OffsetPtr);
/// Look up a list based on a given offset. Extract it and enter it into the
/// list map if necessary.
- Expected<DWARFListType> findList(DWARFDataExtractor Data, uint32_t Offset);
+ Expected<DWARFListType> findList(DWARFDataExtractor Data, uint64_t Offset);
- uint32_t getHeaderOffset() const { return Header.getHeaderOffset(); }
+ uint64_t getHeaderOffset() const { return Header.getHeaderOffset(); }
uint8_t getAddrSize() const { return Header.getAddrSize(); }
+ dwarf::DwarfFormat getFormat() const { return Header.getFormat(); }
void dump(raw_ostream &OS,
llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
@@ -162,37 +175,31 @@ public:
DIDumpOptions DumpOpts = {}) const;
/// Return the contents of the offset entry designated by a given index.
- Optional<uint32_t> getOffsetEntry(uint32_t Index) const {
+ Optional<uint64_t> getOffsetEntry(uint32_t Index) const {
return Header.getOffsetEntry(Index);
}
/// Return the size of the table header including the length but not including
/// the offsets. This is dependent on the table format, which is unambiguously
/// derived from parsing the table.
uint8_t getHeaderSize() const {
- switch (Header.getFormat()) {
- case dwarf::DwarfFormat::DWARF32:
- return 12;
- case dwarf::DwarfFormat::DWARF64:
- return 20;
- }
- llvm_unreachable("Invalid DWARF format (expected DWARF32 or DWARF64");
+ return DWARFListTableHeader::getHeaderSize(getFormat());
}
- uint32_t length() { return Header.length(); }
+ uint64_t length() { return Header.length(); }
};
template <typename DWARFListType>
Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,
- uint32_t *OffsetPtr) {
+ uint64_t *OffsetPtr) {
clear();
if (Error E = extractHeaderAndOffsets(Data, OffsetPtr))
return E;
Data.setAddressSize(Header.getAddrSize());
- uint32_t End = getHeaderOffset() + Header.length();
+ uint64_t End = getHeaderOffset() + Header.length();
while (*OffsetPtr < End) {
DWARFListType CurrentList;
- uint32_t Off = *OffsetPtr;
+ uint64_t Off = *OffsetPtr;
if (Error E = CurrentList.extract(Data, getHeaderOffset(), End, OffsetPtr,
Header.getSectionName(),
Header.getListTypeString()))
@@ -208,13 +215,13 @@ Error DWARFListTableBase<DWARFListType>::extract(DWARFDataExtractor Data,
template <typename ListEntryType>
Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
- uint32_t HeaderOffset, uint32_t End,
- uint32_t *OffsetPtr,
+ uint64_t HeaderOffset, uint64_t End,
+ uint64_t *OffsetPtr,
StringRef SectionName,
StringRef ListTypeString) {
if (*OffsetPtr < HeaderOffset || *OffsetPtr >= End)
return createStringError(errc::invalid_argument,
- "invalid %s list offset 0x%" PRIx32,
+ "invalid %s list offset 0x%" PRIx64,
ListTypeString.data(), *OffsetPtr);
Entries.clear();
while (*OffsetPtr < End) {
@@ -227,7 +234,7 @@ Error DWARFListType<ListEntryType>::extract(DWARFDataExtractor Data,
}
return createStringError(errc::illegal_byte_sequence,
"no end of list marker detected at end of %s table "
- "starting at offset 0x%" PRIx32,
+ "starting at offset 0x%" PRIx64,
SectionName.data(), HeaderOffset);
}
@@ -261,15 +268,15 @@ void DWARFListTableBase<DWARFListType>::dump(
template <typename DWARFListType>
Expected<DWARFListType>
DWARFListTableBase<DWARFListType>::findList(DWARFDataExtractor Data,
- uint32_t Offset) {
+ uint64_t Offset) {
auto Entry = ListMap.find(Offset);
if (Entry != ListMap.end())
return Entry->second;
// Extract the list from the section and enter it into the list map.
DWARFListType List;
- uint32_t End = getHeaderOffset() + Header.length();
- uint32_t StartingOffset = Offset;
+ uint64_t End = getHeaderOffset() + Header.length();
+ uint64_t StartingOffset = Offset;
if (Error E =
List.extract(Data, getHeaderOffset(), End, &Offset,
Header.getSectionName(), Header.getListTypeString()))
diff --git a/include/llvm/DebugInfo/DWARF/DWARFObject.h b/include/llvm/DebugInfo/DWARF/DWARFObject.h
index 1bba74a25d0e..88fe3f434edc 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFObject.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFObject.h
@@ -39,20 +39,20 @@ public:
virtual StringRef getAbbrevSection() const { return ""; }
virtual const DWARFSection &getLocSection() const { return Dummy; }
virtual const DWARFSection &getLoclistsSection() const { return Dummy; }
- virtual StringRef getARangeSection() const { return ""; }
- virtual StringRef getDebugFrameSection() const { return ""; }
- virtual StringRef getEHFrameSection() const { return ""; }
+ virtual StringRef getArangesSection() const { return ""; }
+ virtual const DWARFSection &getFrameSection() const { return Dummy; }
+ virtual const DWARFSection &getEHFrameSection() const { return Dummy; }
virtual const DWARFSection &getLineSection() const { return Dummy; }
- virtual StringRef getLineStringSection() const { return ""; }
- virtual StringRef getStringSection() const { return ""; }
- virtual const DWARFSection &getRangeSection() const { return Dummy; }
+ virtual StringRef getLineStrSection() const { return ""; }
+ virtual StringRef getStrSection() const { return ""; }
+ virtual const DWARFSection &getRangesSection() const { return Dummy; }
virtual const DWARFSection &getRnglistsSection() const { return Dummy; }
virtual StringRef getMacinfoSection() const { return ""; }
- virtual const DWARFSection &getPubNamesSection() const { return Dummy; }
- virtual const DWARFSection &getPubTypesSection() const { return Dummy; }
- virtual const DWARFSection &getGnuPubNamesSection() const { return Dummy; }
- virtual const DWARFSection &getGnuPubTypesSection() const { return Dummy; }
- virtual const DWARFSection &getStringOffsetSection() const { return Dummy; }
+ virtual const DWARFSection &getPubnamesSection() const { return Dummy; }
+ virtual const DWARFSection &getPubtypesSection() const { return Dummy; }
+ virtual const DWARFSection &getGnuPubnamesSection() const { return Dummy; }
+ virtual const DWARFSection &getGnuPubtypesSection() const { return Dummy; }
+ virtual const DWARFSection &getStrOffsetsSection() const { return Dummy; }
virtual void
forEachInfoDWOSections(function_ref<void(const DWARFSection &)> F) const {}
virtual void
@@ -60,11 +60,11 @@ public:
virtual StringRef getAbbrevDWOSection() const { return ""; }
virtual const DWARFSection &getLineDWOSection() const { return Dummy; }
virtual const DWARFSection &getLocDWOSection() const { return Dummy; }
- virtual StringRef getStringDWOSection() const { return ""; }
- virtual const DWARFSection &getStringOffsetDWOSection() const {
+ virtual StringRef getStrDWOSection() const { return ""; }
+ virtual const DWARFSection &getStrOffsetsDWOSection() const {
return Dummy;
}
- virtual const DWARFSection &getRangeDWOSection() const { return Dummy; }
+ virtual const DWARFSection &getRangesDWOSection() const { return Dummy; }
virtual const DWARFSection &getRnglistsDWOSection() const { return Dummy; }
virtual const DWARFSection &getAddrSection() const { return Dummy; }
virtual const DWARFSection &getAppleNamesSection() const { return Dummy; }
@@ -72,7 +72,7 @@ public:
virtual const DWARFSection &getAppleNamespacesSection() const {
return Dummy;
}
- virtual const DWARFSection &getDebugNamesSection() const { return Dummy; }
+ virtual const DWARFSection &getNamesSection() const { return Dummy; }
virtual const DWARFSection &getAppleObjCSection() const { return Dummy; }
virtual StringRef getCUIndexSection() const { return ""; }
virtual StringRef getGdbIndexSection() const { return ""; }
diff --git a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
index 90d89375fd35..c95bdcbd8a43 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
@@ -34,7 +34,7 @@ public:
LS, LE, IsDWO, UnitVector) {}
uint64_t getTypeHash() const { return getHeader().getTypeHash(); }
- uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); }
+ uint64_t getTypeOffset() const { return getHeader().getTypeOffset(); }
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
// Enable LLVM-style RTTI.
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index f9f90db31890..51de114a3506 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -45,7 +45,7 @@ class DWARFUnit;
/// parse the header before deciding what specific kind of unit to construct.
class DWARFUnitHeader {
// Offset within section.
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
// Version, address size, and DWARF format.
dwarf::FormParams FormParams;
uint64_t Length = 0;
@@ -56,7 +56,7 @@ class DWARFUnitHeader {
// For type units only.
uint64_t TypeHash = 0;
- uint32_t TypeOffset = 0;
+ uint64_t TypeOffset = 0;
// For v5 split or skeleton compile units only.
Optional<uint64_t> DWOId;
@@ -70,10 +70,10 @@ class DWARFUnitHeader {
public:
/// Parse a unit header from \p debug_info starting at \p offset_ptr.
bool extract(DWARFContext &Context, const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO,
+ uint64_t *offset_ptr, DWARFSectionKind Kind = DW_SECT_INFO,
const DWARFUnitIndex *Index = nullptr,
const DWARFUnitIndex::Entry *Entry = nullptr);
- uint32_t getOffset() const { return Offset; }
+ uint64_t getOffset() const { return Offset; }
const dwarf::FormParams &getFormParams() const { return FormParams; }
uint16_t getVersion() const { return FormParams.Version; }
dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
@@ -91,16 +91,17 @@ public:
}
const DWARFUnitIndex::Entry *getIndexEntry() const { return IndexEntry; }
uint64_t getTypeHash() const { return TypeHash; }
- uint32_t getTypeOffset() const { return TypeOffset; }
+ uint64_t getTypeOffset() const { return TypeOffset; }
uint8_t getUnitType() const { return UnitType; }
bool isTypeUnit() const {
return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
}
uint8_t getSize() const { return Size; }
- uint32_t getNextUnitOffset() const {
- return Offset + Length +
- (FormParams.Format == llvm::dwarf::DwarfFormat::DWARF64 ? 4 : 0) +
- FormParams.getDwarfOffsetByteSize();
+ uint8_t getUnitLengthFieldByteSize() const {
+ return dwarf::getUnitLengthFieldByteSize(FormParams.Format);
+ }
+ uint64_t getNextUnitOffset() const {
+ return Offset + Length + getUnitLengthFieldByteSize();
}
};
@@ -110,7 +111,7 @@ const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
/// Describe a collection of units. Intended to hold all units either from
/// .debug_info and .debug_types, or from .debug_info.dwo and .debug_types.dwo.
class DWARFUnitVector final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
- std::function<std::unique_ptr<DWARFUnit>(uint32_t, DWARFSectionKind,
+ std::function<std::unique_ptr<DWARFUnit>(uint64_t, DWARFSectionKind,
const DWARFSection *,
const DWARFUnitIndex::Entry *)>
Parser;
@@ -121,7 +122,7 @@ public:
using iterator = typename UnitVector::iterator;
using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;
- DWARFUnit *getUnitForOffset(uint32_t Offset) const;
+ DWARFUnit *getUnitForOffset(uint64_t Offset) const;
DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E);
/// Read units from a .debug_info or .debug_types section. Calls made
@@ -197,7 +198,7 @@ class DWARFUnit {
DWARFUnitHeader Header;
const DWARFDebugAbbrev *Abbrev;
const DWARFSection *RangeSection;
- uint32_t RangeSectionBase;
+ uint64_t RangeSectionBase;
/// We either keep track of the location list section or its data, depending
/// on whether we are handling a split DWARF section or not.
union {
@@ -275,7 +276,7 @@ public:
const DWARFSection &getInfoSection() const { return InfoSection; }
const DWARFSection *getLocSection() const { return LocSection; }
StringRef getLocSectionData() const { return LocSectionData; }
- uint32_t getOffset() const { return Header.getOffset(); }
+ uint64_t getOffset() const { return Header.getOffset(); }
const dwarf::FormParams &getFormParams() const {
return Header.getFormParams();
}
@@ -285,10 +286,10 @@ public:
uint8_t getDwarfOffsetByteSize() const {
return Header.getDwarfOffsetByteSize();
}
- uint32_t getLength() const { return Header.getLength(); }
+ uint64_t getLength() const { return Header.getLength(); }
uint8_t getUnitType() const { return Header.getUnitType(); }
bool isTypeUnit() const { return Header.isTypeUnit(); }
- uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
+ uint64_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
const DWARFSection &getLineSection() const { return LineSection; }
StringRef getStringSection() const { return StringSection; }
const DWARFSection &getStringOffsetSection() const {
@@ -303,7 +304,7 @@ public:
/// Recursively update address to Die map.
void updateAddressDieMap(DWARFDie Die);
- void setRangesSection(const DWARFSection *RS, uint32_t Base) {
+ void setRangesSection(const DWARFSection *RS, uint64_t Base) {
RangeSection = RS;
RangeSectionBase = Base;
}
@@ -322,7 +323,7 @@ public:
/// .debug_ranges section. If the extraction is unsuccessful, an error
/// is returned. Successful extraction requires that the compile unit
/// has already been extracted.
- Error extractRangeList(uint32_t RangeListOffset,
+ Error extractRangeList(uint64_t RangeListOffset,
DWARFDebugRangeList &RangeList) const;
void clear();
@@ -405,7 +406,7 @@ public:
/// Return a vector of address ranges resulting from a (possibly encoded)
/// range list starting at a given offset in the appropriate ranges section.
- Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint32_t Offset);
+ Expected<DWARFAddressRangesVector> findRnglistFromOffset(uint64_t Offset);
/// Return a vector of address ranges retrieved from an encoded range
/// list whose offset is found via a table lookup given an index (DWARF v5
@@ -415,7 +416,7 @@ public:
/// Return a rangelist's offset based on an index. The index designates
/// an entry in the rangelist table's offset array and is supplied by
/// DW_FORM_rnglistx.
- Optional<uint32_t> getRnglistOffset(uint32_t Index) {
+ Optional<uint64_t> getRnglistOffset(uint32_t Index) {
if (RngListTable)
return RngListTable->getOffsetEntry(Index);
return None;
@@ -470,7 +471,7 @@ public:
/// unit's DIE vector.
///
/// The unit needs to have its DIEs extracted for this method to work.
- DWARFDie getDIEForOffset(uint32_t Offset) {
+ DWARFDie getDIEForOffset(uint64_t Offset) {
extractDIEsIfNeeded(false);
assert(!DieArray.empty());
auto It =
@@ -495,15 +496,19 @@ public:
}
virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
+
+ Error tryExtractDIEsIfNeeded(bool CUDieOnly);
+
private:
/// Size in bytes of the .debug_info data associated with this compile unit.
size_t getDebugInfoSize() const {
- return Header.getLength() + 4 - getHeaderSize();
+ return Header.getLength() + Header.getUnitLengthFieldByteSize() -
+ getHeaderSize();
}
/// extractDIEsIfNeeded - Parses a compile unit and indexes its DIEs if it
- /// hasn't already been done. Returns the number of DIEs parsed at this call.
- size_t extractDIEsIfNeeded(bool CUDieOnly);
+ /// hasn't already been done
+ void extractDIEsIfNeeded(bool CUDieOnly);
/// extractDIEsToVector - Appends all parsed DIEs to a vector.
void extractDIEsToVector(bool AppendCUDie, bool AppendNonCUDIEs,
diff --git a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
index fc8c707c512e..684103aac2fc 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFUnitIndex.h
@@ -37,7 +37,7 @@ class DWARFUnitIndex {
uint32_t NumUnits;
uint32_t NumBuckets = 0;
- bool parse(DataExtractor IndexData, uint32_t *OffsetPtr);
+ bool parse(DataExtractor IndexData, uint64_t *OffsetPtr);
void dump(raw_ostream &OS) const;
};
diff --git a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
index f1268f220272..a4a3a11d441b 100644
--- a/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
+++ b/include/llvm/DebugInfo/DWARF/DWARFVerifier.h
@@ -94,7 +94,7 @@ private:
/// A map that tracks all references (converted absolute references) so we
/// can verify each reference points to a valid DIE and not an offset that
/// lies between to valid DIEs.
- std::map<uint64_t, std::set<uint32_t>> ReferenceToDIEOffsets;
+ std::map<uint64_t, std::set<uint64_t>> ReferenceToDIEOffsets;
uint32_t NumDebugLineErrors = 0;
// Used to relax some checks that do not currently work portably
bool IsObjectFile;
@@ -138,7 +138,7 @@ private:
///
/// \returns true if the header is verified successfully, false otherwise.
bool verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
- uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
+ uint64_t *Offset, unsigned UnitIndex, uint8_t &UnitType,
bool &isUnitDWARF64);
/// Verifies the header of a unit in a .debug_info or .debug_types section.
diff --git a/include/llvm/DebugInfo/GSYM/FileEntry.h b/include/llvm/DebugInfo/GSYM/FileEntry.h
index 228b4efa0656..49e7fc9c4291 100644
--- a/include/llvm/DebugInfo/GSYM/FileEntry.h
+++ b/include/llvm/DebugInfo/GSYM/FileEntry.h
@@ -1,9 +1,8 @@
//===- FileEntry.h ----------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/DebugInfo/GSYM/FileWriter.h b/include/llvm/DebugInfo/GSYM/FileWriter.h
new file mode 100644
index 000000000000..cd568765a4f2
--- /dev/null
+++ b/include/llvm/DebugInfo/GSYM/FileWriter.h
@@ -0,0 +1,124 @@
+//===- FileWriter.h ---------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_GSYM_FILEWRITER_H
+#define LLVM_DEBUGINFO_GSYM_FILEWRITER_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace llvm {
+class raw_pwrite_stream;
+
+namespace gsym {
+
+/// A simplified binary data writer class that doesn't require targets, target
+/// definitions, architectures, or require any other optional compile time
+/// libraries to be enabled via the build process. This class needs the ability
+/// to seek to different spots in the binary stream that is produces to fixup
+/// offsets and sizes.
+class FileWriter {
+ llvm::raw_pwrite_stream &OS;
+ llvm::support::endianness ByteOrder;
+public:
+ FileWriter(llvm::raw_pwrite_stream &S, llvm::support::endianness B)
+ : OS(S), ByteOrder(B) {}
+ ~FileWriter();
+ /// Write a single uint8_t value into the stream at the current file
+ /// position.
+ ///
+ /// \param Value The value to write into the stream.
+ void writeU8(uint8_t Value);
+
+ /// Write a single uint16_t value into the stream at the current file
+ /// position. The value will be byte swapped if needed to match the byte
+ /// order specified during construction.
+ ///
+ /// \param Value The value to write into the stream.
+ void writeU16(uint16_t Value);
+
+ /// Write a single uint32_t value into the stream at the current file
+ /// position. The value will be byte swapped if needed to match the byte
+ /// order specified during construction.
+ ///
+ /// \param Value The value to write into the stream.
+ void writeU32(uint32_t Value);
+
+ /// Write a single uint64_t value into the stream at the current file
+ /// position. The value will be byte swapped if needed to match the byte
+ /// order specified during construction.
+ ///
+ /// \param Value The value to write into the stream.
+ void writeU64(uint64_t Value);
+
+ /// Write the value into the stream encoded using signed LEB128 at the
+ /// current file position.
+ ///
+ /// \param Value The value to write into the stream.
+ void writeSLEB(int64_t Value);
+
+ /// Write the value into the stream encoded using unsigned LEB128 at the
+ /// current file position.
+ ///
+ /// \param Value The value to write into the stream.
+ void writeULEB(uint64_t Value);
+
+ /// Write an array of uint8_t values into the stream at the current file
+ /// position.
+ ///
+ /// \param Data An array of values to write into the stream.
+ void writeData(llvm::ArrayRef<uint8_t> Data);
+
+ /// Write a NULL terminated C string into the stream at the current file
+ /// position. The entire contents of Str will be written into the steam at
+ /// the current file position and then an extra NULL termation byte will be
+ /// written. It is up to the user to ensure that Str doesn't contain any NULL
+ /// characters unless the additional NULL characters are desired.
+ ///
+ /// \param Str The value to write into the stream.
+ void writeNullTerminated(llvm::StringRef Str);
+
+ /// Fixup a uint32_t value at the specified offset in the stream. This
+ /// function will save the current file position, seek to the specified
+ /// offset, overwrite the data using Value, and then restore the file
+ /// position to the previous file position.
+ ///
+ /// \param Value The value to write into the stream.
+ /// \param Offset The offset at which to write the Value within the stream.
+ void fixup32(uint32_t Value, uint64_t Offset);
+
+ /// Pad with zeroes at the current file position until the current file
+ /// position matches the specified alignment.
+ ///
+ /// \param Align An integer speciying the desired alignment. This does not
+ /// need to be a power of two.
+ void alignTo(size_t Align);
+
+ /// Return the current offset within the file.
+ ///
+ /// \return The unsigned offset from the start of the file of the current
+ /// file position.
+ uint64_t tell();
+
+ llvm::raw_pwrite_stream &get_stream() {
+ return OS;
+ }
+
+private:
+ FileWriter(const FileWriter &rhs) = delete;
+ void operator=(const FileWriter &rhs) = delete;
+};
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_FILEWRITER_H
diff --git a/include/llvm/DebugInfo/GSYM/FunctionInfo.h b/include/llvm/DebugInfo/GSYM/FunctionInfo.h
index eedb1e638fd1..63e18bb2ecd5 100644
--- a/include/llvm/DebugInfo/GSYM/FunctionInfo.h
+++ b/include/llvm/DebugInfo/GSYM/FunctionInfo.h
@@ -1,17 +1,17 @@
//===- FunctionInfo.h -------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
#define LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
+#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/GSYM/InlineInfo.h"
-#include "llvm/DebugInfo/GSYM/LineEntry.h"
+#include "llvm/DebugInfo/GSYM/LineTable.h"
#include "llvm/DebugInfo/GSYM/Range.h"
#include "llvm/DebugInfo/GSYM/StringTable.h"
#include <tuple>
@@ -21,41 +21,125 @@ namespace llvm {
class raw_ostream;
namespace gsym {
-/// Function information in GSYM files encodes information for one
-/// contiguous address range. The name of the function is encoded as
-/// a string table offset and allows multiple functions with the same
-/// name to share the name string in the string table. Line tables are
-/// stored in a sorted vector of gsym::LineEntry objects and are split
-/// into line tables for each function. If a function has a discontiguous
-/// range, it will be split into two gsym::FunctionInfo objects. If the
-/// function has inline functions, the information will be encoded in
-/// the "Inline" member, see gsym::InlineInfo for more information.
+/// Function information in GSYM files encodes information for one contiguous
+/// address range. If a function has discontiguous address ranges, they will
+/// need to be encoded using multiple FunctionInfo objects.
+///
+/// ENCODING
+///
+/// The function information gets the function start address as an argument
+/// to the FunctionInfo::decode(...) function. This information is calculated
+/// from the GSYM header and an address offset from the GSYM address offsets
+/// table. The encoded FunctionInfo information must be alinged to a 4 byte
+/// boundary.
+///
+/// The encoded data for a FunctionInfo starts with fixed data that all
+/// function info objects have:
+///
+/// ENCODING NAME DESCRIPTION
+/// ========= =========== ====================================================
+/// uint32_t Size The size in bytes of this function.
+/// uint32_t Name The string table offset of the function name.
+///
+/// The optional data in a FunctionInfo object follows this fixed information
+/// and consists of a stream of tuples that consist of:
+///
+/// ENCODING NAME DESCRIPTION
+/// ========= =========== ====================================================
+/// uint32_t InfoType An "InfoType" enumeration that describes the type
+/// of optional data that is encoded.
+/// uint32_t InfoLength The size in bytes of the encoded data that
+/// immediately follows this length if this value is
+/// greater than zero.
+/// uint8_t[] InfoData Encoded bytes that represent the data for the
+/// "InfoType". These bytes are only present if
+/// "InfoLength" is greater than zero.
+///
+/// The "InfoType" is an enumeration:
+///
+/// enum InfoType {
+/// EndOfList = 0u,
+/// LineTableInfo = 1u,
+/// InlineInfo = 2u
+/// };
+///
+/// This stream of tuples is terminated by a "InfoType" whose value is
+/// InfoType::EndOfList and a zero for "InfoLength". This signifies the end of
+/// the optional information list. This format allows us to add new optional
+/// information data to a FunctionInfo object over time and allows older
+/// clients to still parse the format and skip over any data that they don't
+/// understand or want to parse.
+///
+/// So the function information encoding essientially looks like:
+///
+/// struct {
+/// uint32_t Size;
+/// uint32_t Name;
+/// struct {
+/// uint32_t InfoType;
+/// uint32_t InfoLength;
+/// uint8_t InfoData[InfoLength];
+/// }[N];
+/// }
+///
+/// Where "N" is the number of tuples.
struct FunctionInfo {
AddressRange Range;
uint32_t Name; ///< String table offset in the string table.
- std::vector<gsym::LineEntry> Lines;
- InlineInfo Inline;
+ llvm::Optional<LineTable> OptLineTable;
+ llvm::Optional<InlineInfo> Inline;
FunctionInfo(uint64_t Addr = 0, uint64_t Size = 0, uint32_t N = 0)
: Range(Addr, Addr + Size), Name(N) {}
+ /// Query if a FunctionInfo has rich debug info.
+ ///
+ /// \returns A bool that indicates if this object has something else than
+ /// range and name. When converting information from a symbol table and from
+ /// debug info, we might end up with multiple FunctionInfo objects for the
+ /// same range and we need to be able to tell which one is the better object
+ /// to use.
bool hasRichInfo() const {
- /// Returns whether we have something else than range and name. When
- /// converting information from a symbol table and from debug info, we
- /// might end up with multiple FunctionInfo objects for the same range
- /// and we need to be able to tell which one is the better object to use.
- return !Lines.empty() || Inline.isValid();
+ return OptLineTable.hasValue() || Inline.hasValue();
}
+ /// Query if a FunctionInfo object is valid.
+ ///
+ /// Address and size can be zero and there can be no line entries for a
+ /// symbol so the only indication this entry is valid is if the name is
+ /// not zero. This can happen when extracting information from symbol
+ /// tables that do not encode symbol sizes. In that case only the
+ /// address and name will be filled in.
+ ///
+ /// \returns A boolean indicating if this FunctionInfo is valid.
bool isValid() const {
- /// Address and size can be zero and there can be no line entries for a
- /// symbol so the only indication this entry is valid is if the name is
- /// not zero. This can happen when extracting information from symbol
- /// tables that do not encode symbol sizes. In that case only the
- /// address and name will be filled in.
return Name != 0;
}
+ /// Decode an object from a binary data stream.
+ ///
+ /// \param Data The binary stream to read the data from. This object must
+ /// have the data for the object starting at offset zero. The data
+ /// can contain more data than needed.
+ ///
+ /// \param BaseAddr The FunctionInfo's start address and will be used as the
+ /// base address when decoding any contained information like the line table
+ /// and the inline info.
+ ///
+ /// \returns An FunctionInfo or an error describing the issue that was
+ /// encountered during decoding.
+ static llvm::Expected<FunctionInfo> decode(DataExtractor &Data,
+ uint64_t BaseAddr);
+
+ /// Encode this object into FileWriter stream.
+ ///
+ /// \param O The binary stream to write the data to at the current file
+ /// position.
+ ///
+ /// \returns An error object that indicates failure or the offset of the
+ /// function info that was successfully written into the stream.
+ llvm::Expected<uint64_t> encode(FileWriter &O) const;
+
uint64_t startAddress() const { return Range.Start; }
uint64_t endAddress() const { return Range.End; }
uint64_t size() const { return Range.size(); }
@@ -66,14 +150,14 @@ struct FunctionInfo {
void clear() {
Range = {0, 0};
Name = 0;
- Lines.clear();
- Inline.clear();
+ OptLineTable = None;
+ Inline = None;
}
};
inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) {
return LHS.Range == RHS.Range && LHS.Name == RHS.Name &&
- LHS.Lines == RHS.Lines && LHS.Inline == RHS.Inline;
+ LHS.OptLineTable == RHS.OptLineTable && LHS.Inline == RHS.Inline;
}
inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
return !(LHS == RHS);
@@ -89,14 +173,10 @@ inline bool operator<(const FunctionInfo &LHS, const FunctionInfo &RHS) {
return LHS.Range < RHS.Range;
// Then sort by inline
- if (LHS.Inline.isValid() != RHS.Inline.isValid())
- return RHS.Inline.isValid();
-
- // If the number of lines is the same, then compare line table entries
- if (LHS.Lines.size() == RHS.Lines.size())
- return LHS.Lines < RHS.Lines;
- // Then sort by number of line table entries (more is better)
- return LHS.Lines.size() < RHS.Lines.size();
+ if (LHS.Inline.hasValue() != RHS.Inline.hasValue())
+ return RHS.Inline.hasValue();
+
+ return LHS.OptLineTable < RHS.OptLineTable;
}
raw_ostream &operator<<(raw_ostream &OS, const FunctionInfo &R);
diff --git a/include/llvm/DebugInfo/GSYM/GsymCreator.h b/include/llvm/DebugInfo/GSYM/GsymCreator.h
new file mode 100644
index 000000000000..12c8187132ba
--- /dev/null
+++ b/include/llvm/DebugInfo/GSYM/GsymCreator.h
@@ -0,0 +1,229 @@
+//===- GsymCreator.h --------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H
+#define LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H
+
+#include <functional>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <thread>
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Path.h"
+
+namespace llvm {
+
+namespace gsym {
+class FileWriter;
+
+/// GsymCreator is used to emit GSYM data to a stand alone file or section
+/// within a file.
+///
+/// The GsymCreator is designed to be used in 3 stages:
+/// - Create FunctionInfo objects and add them
+/// - Finalize the GsymCreator object
+/// - Save to file or section
+///
+/// The first stage involves creating FunctionInfo objects from another source
+/// of information like compiler debug info metadata, DWARF or Breakpad files.
+/// Any strings in the FunctionInfo or contained information, like InlineInfo
+/// or LineTable objects, should get the string table offsets by calling
+/// GsymCreator::insertString(...). Any file indexes that are needed should be
+/// obtained by calling GsymCreator::insertFile(...). All of the function calls
+/// in GsymCreator are thread safe. This allows multiple threads to create and
+/// add FunctionInfo objects while parsing debug information.
+///
+/// Once all of the FunctionInfo objects have been added, the
+/// GsymCreator::finalize(...) must be called prior to saving. This function
+/// will sort the FunctionInfo objects, finalize the string table, and do any
+/// other passes on the information needed to prepare the information to be
+/// saved.
+///
+/// Once the object has been finalized, it can be saved to a file or section.
+///
+/// ENCODING
+///
+/// GSYM files are designed to be memory mapped into a process as shared, read
+/// only data, and used as is.
+///
+/// The GSYM file format when in a stand alone file consists of:
+/// - Header
+/// - Address Table
+/// - Function Info Offsets
+/// - File Table
+/// - String Table
+/// - Function Info Data
+///
+/// HEADER
+///
+/// The header is fully described in "llvm/DebugInfo/GSYM/Header.h".
+///
+/// ADDRESS TABLE
+///
+/// The address table immediately follows the header in the file and consists
+/// of Header.NumAddresses address offsets. These offsets are sorted and can be
+/// binary searched for efficient lookups. Addresses in the address table are
+/// stored as offsets from a 64 bit base address found in Header.BaseAddress.
+/// This allows the address table to contain 8, 16, or 32 offsets. This allows
+/// the address table to not require full 64 bit addresses for each address.
+/// The resulting GSYM size is smaller and causes fewer pages to be touched
+/// during address lookups when the address table is smaller. The size of the
+/// address offsets in the address table is specified in the header in
+/// Header.AddrOffSize. The first offset in the address table is alinged to
+/// Header.AddrOffSize alignement to ensure efficient access when loaded into
+/// memory.
+///
+/// FUNCTION INFO OFFSETS TABLE
+///
+/// The function info offsets table immediately follows the address table and
+/// consists of Header.NumAddresses 32 bit file offsets: one for each address
+/// in the address table. This data is algined to a 4 byte boundary. The
+/// offsets in this table are the relative offsets from the start offset of the
+/// GSYM header and point to the function info data for each address in the
+/// address table. Keeping this data separate from the address table helps to
+/// reduce the number of pages that are touched when address lookups occur on a
+/// GSYM file.
+///
+/// FILE TABLE
+///
+/// The file table immediately follows the function info offsets table. The
+/// encoding of the FileTable is:
+///
+/// struct FileTable {
+/// uint32_t Count;
+/// FileEntry Files[];
+/// };
+///
+/// The file table starts with a 32 bit count of the number of files that are
+/// used in all of the function info, followed by that number of FileEntry
+/// structures. The file table is aligned to a 4 byte boundary, Each file in
+/// the file table is represented with a FileEntry structure.
+/// See "llvm/DebugInfo/GSYM/FileEntry.h" for details.
+///
+/// STRING TABLE
+///
+/// The string table follows the file table in stand alone GSYM files and
+/// contains all strings for everything contained in the GSYM file. Any string
+/// data should be added to the string table and any references to strings
+/// inside GSYM information must be stored as 32 bit string table offsets into
+/// this string table. The string table always starts with an empty string at
+/// offset zero and is followed by any strings needed by the GSYM information.
+/// The start of the string table is not aligned to any boundary.
+///
+/// FUNCTION INFO DATA
+///
+/// The function info data is the payload that contains information about the
+/// address that is being looked up. It contains all of the encoded
+/// FunctionInfo objects. Each encoded FunctionInfo's data is pointed to by an
+/// entry in the Function Info Offsets Table. For details on the exact encoding
+/// of FunctionInfo objects, see "llvm/DebugInfo/GSYM/FunctionInfo.h".
+class GsymCreator {
+ // Private member variables require Mutex protections
+ mutable std::recursive_mutex Mutex;
+ std::vector<FunctionInfo> Funcs;
+ StringTableBuilder StrTab;
+ DenseMap<llvm::gsym::FileEntry, uint32_t> FileEntryToIndex;
+ std::vector<llvm::gsym::FileEntry> Files;
+ std::vector<uint8_t> UUID;
+ bool Finalized = false;
+
+public:
+
+ GsymCreator();
+
+ /// Save a GSYM file to a stand alone file.
+ ///
+ /// \param Path The file path to save the GSYM file to.
+ /// \param ByteOrder The endianness to use when saving the file.
+ /// \returns An error object that indicates success or failure of the save.
+ llvm::Error save(StringRef Path, llvm::support::endianness ByteOrder) const;
+
+ /// Encode a GSYM into the file writer stream at the current position.
+ ///
+ /// \param O The stream to save the binary data to
+ /// \returns An error object that indicates success or failure of the save.
+ llvm::Error encode(FileWriter &O) const;
+
+ /// Insert a string into the GSYM string table.
+ ///
+ /// All strings used by GSYM files must be uniqued by adding them to this
+ /// string pool and using the returned offset for any string values.
+ ///
+ /// \param S The string to insert into the string table.
+ /// \returns The unique 32 bit offset into the string table.
+ uint32_t insertString(StringRef S);
+
+ /// Insert a file into this GSYM creator.
+ ///
+ /// Inserts a file by adding a FileEntry into the "Files" member variable if
+ /// the file has not already been added. The file path is split into
+ /// directory and filename which are both added to the string table. This
+ /// allows paths to be stored efficiently by reusing the directories that are
+ /// common between multiple files.
+ ///
+ /// \param Path The path to the file to insert.
+ /// \param Style The path style for the "Path" parameter.
+ /// \returns The unique file index for the inserted file.
+ uint32_t insertFile(StringRef Path,
+ sys::path::Style Style = sys::path::Style::native);
+
+ /// Add a function info to this GSYM creator.
+ ///
+ /// All information in the FunctionInfo object must use the
+ /// GsymCreator::insertString(...) function when creating string table
+ /// offsets for names and other strings.
+ ///
+ /// \param FI The function info object to emplace into our functions list.
+ void addFunctionInfo(FunctionInfo &&FI);
+
+ /// Finalize the data in the GSYM creator prior to saving the data out.
+ ///
+ /// Finalize must be called after all FunctionInfo objects have been added
+ /// and before GsymCreator::save() is called.
+ ///
+ /// \param OS Output stream to report duplicate function infos, overlapping
+ /// function infos, and function infos that were merged or removed.
+ /// \returns An error object that indicates success or failure of the
+ /// finalize.
+ llvm::Error finalize(llvm::raw_ostream &OS);
+
+ /// Set the UUID value.
+ ///
+ /// \param UUIDBytes The new UUID bytes.
+ void setUUID(llvm::ArrayRef<uint8_t> UUIDBytes) {
+ UUID.assign(UUIDBytes.begin(), UUIDBytes.end());
+ }
+
+ /// Thread safe iteration over all function infos.
+ ///
+ /// \param Callback A callback function that will get called with each
+ /// FunctionInfo. If the callback returns false, stop iterating.
+ void forEachFunctionInfo(
+ std::function<bool(FunctionInfo &)> const &Callback);
+
+ /// Thread safe const iteration over all function infos.
+ ///
+ /// \param Callback A callback function that will get called with each
+ /// FunctionInfo. If the callback returns false, stop iterating.
+ void forEachFunctionInfo(
+ std::function<bool(const FunctionInfo &)> const &Callback) const;
+
+};
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_GSYMCREATOR_H
diff --git a/include/llvm/DebugInfo/GSYM/GsymReader.h b/include/llvm/DebugInfo/GSYM/GsymReader.h
new file mode 100644
index 000000000000..113bcee9c9a3
--- /dev/null
+++ b/include/llvm/DebugInfo/GSYM/GsymReader.h
@@ -0,0 +1,228 @@
+//===- GsymReader.h ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_GSYM_GSYMREADER_H
+#define LLVM_DEBUGINFO_GSYM_GSYMREADER_H
+
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/DebugInfo/GSYM/Header.h"
+#include "llvm/DebugInfo/GSYM/LineEntry.h"
+#include "llvm/DebugInfo/GSYM/StringTable.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/ErrorOr.h"
+
+#include <inttypes.h>
+#include <memory>
+#include <stdint.h>
+#include <string>
+#include <vector>
+
+namespace llvm {
+class MemoryBuffer;
+class raw_ostream;
+
+namespace gsym {
+
+/// GsymReader is used to read GSYM data from a file or buffer.
+///
+/// This class is optimized for very quick lookups when the endianness matches
+/// the host system. The Header, address table, address info offsets, and file
+/// table is designed to be mmap'ed as read only into memory and used without
+/// any parsing needed. If the endianness doesn't match, we swap these objects
+/// and tables into GsymReader::SwappedData and then point our header and
+/// ArrayRefs to this swapped internal data.
+///
+/// GsymReader objects must use one of the static functions to create an
+/// instance: GsymReader::openFile(...) and GsymReader::copyBuffer(...).
+
+class GsymReader {
+ GsymReader(std::unique_ptr<MemoryBuffer> Buffer);
+ llvm::Error parse();
+
+ std::unique_ptr<MemoryBuffer> MemBuffer;
+ StringRef GsymBytes;
+ llvm::support::endianness Endian;
+ const Header *Hdr = nullptr;
+ ArrayRef<uint8_t> AddrOffsets;
+ ArrayRef<uint32_t> AddrInfoOffsets;
+ ArrayRef<FileEntry> Files;
+ StringTable StrTab;
+ /// When the GSYM file's endianness doesn't match the host system then
+ /// we must decode all data structures that need to be swapped into
+ /// local storage and set point the ArrayRef objects above to these swapped
+ /// copies.
+ struct SwappedData {
+ Header Hdr;
+ std::vector<uint8_t> AddrOffsets;
+ std::vector<uint32_t> AddrInfoOffsets;
+ std::vector<FileEntry> Files;
+ };
+ std::unique_ptr<SwappedData> Swap;
+
+public:
+ GsymReader(GsymReader &&RHS);
+ ~GsymReader();
+
+ /// Construct a GsymReader from a file on disk.
+ ///
+ /// \param Path The file path the GSYM file to read.
+ /// \returns An expected GsymReader that contains the object or an error
+ /// object that indicates reason for failing to read the GSYM.
+ static llvm::Expected<GsymReader> openFile(StringRef Path);
+
+ /// Construct a GsymReader from a buffer.
+ ///
+ /// \param Bytes A set of bytes that will be copied and owned by the
+ /// returned object on success.
+ /// \returns An expected GsymReader that contains the object or an error
+ /// object that indicates reason for failing to read the GSYM.
+ static llvm::Expected<GsymReader> copyBuffer(StringRef Bytes);
+
+ /// Access the GSYM header.
+ /// \returns A native endian version of the GSYM header.
+ const Header &getHeader() const;
+
+ /// Get the full function info for an address.
+ ///
+ /// \param Addr A virtual address from the orignal object file to lookup.
+ /// \returns An expected FunctionInfo that contains the function info object
+ /// or an error object that indicates reason for failing to lookup the
+ /// address,
+ llvm::Expected<FunctionInfo> getFunctionInfo(uint64_t Addr) const;
+
+ /// Get a string from the string table.
+ ///
+ /// \param Offset The string table offset for the string to retrieve.
+ /// \returns The string from the strin table.
+ StringRef getString(uint32_t Offset) const { return StrTab[Offset]; }
+
+protected:
+ /// Gets an address from the address table.
+ ///
+ /// Addresses are stored as offsets frrom the gsym::Header::BaseAddress.
+ ///
+ /// \param Index A index into the address table.
+ /// \returns A resolved virtual address for adddress in the address table
+ /// or llvm::None if Index is out of bounds.
+ Optional<uint64_t> getAddress(size_t Index) const;
+
+ /// Get the a file entry for the suppplied file index.
+ ///
+ /// Used to convert any file indexes in the FunctionInfo data back into
+ /// files. This function can be used for iteration, but is more commonly used
+ /// for random access when doing lookups.
+ ///
+ /// \param Index An index into the file table.
+ /// \returns An optional FileInfo that will be valid if the file index is
+ /// valid, or llvm::None if the file index is out of bounds,
+ Optional<FileEntry> getFile(uint32_t Index) const {
+ if (Index < Files.size())
+ return Files[Index];
+ return llvm::None;
+ }
+
+ /// Get an appropriate address info offsets array.
+ ///
+ /// The address table in the GSYM file is stored as array of 1, 2, 4 or 8
+ /// byte offsets from the The gsym::Header::BaseAddress. The table is stored
+ /// internally as a array of bytes that are in the correct endianness. When
+ /// we access this table we must get an array that matches those sizes. This
+ /// templatized helper function is used when accessing address offsets in the
+ /// AddrOffsets member variable.
+ ///
+ /// \returns An ArrayRef of an appropriate address offset size.
+ template <class T> ArrayRef<T>
+ getAddrOffsets() const {
+ return ArrayRef<T>(reinterpret_cast<const T *>(AddrOffsets.data()),
+ AddrOffsets.size()/sizeof(T));
+ }
+
+ /// Get an appropriate address from the address table.
+ ///
+ /// The address table in the GSYM file is stored as array of 1, 2, 4 or 8
+ /// byte address offsets from the The gsym::Header::BaseAddress. The table is
+ /// stored internally as a array of bytes that are in the correct endianness.
+ /// In order to extract an address from the address table we must access the
+ /// address offset using the correct size and then add it to the BaseAddress
+ /// in the header.
+ ///
+ /// \param Index An index into the AddrOffsets array.
+ /// \returns An virtual address that matches the original object file for the
+ /// address as the specified index, or llvm::None if Index is out of bounds.
+ template <class T> Optional<uint64_t>
+ addressForIndex(size_t Index) const {
+ ArrayRef<T> AIO = getAddrOffsets<T>();
+ if (Index < AIO.size())
+ return AIO[Index] + Hdr->BaseAddress;
+ return llvm::None;
+ }
+ /// Lookup an address offset in the AddrOffsets table.
+ ///
+ /// Given an address offset, look it up using a binary search of the
+ /// AddrOffsets table.
+ ///
+ /// \param AddrOffset An address offset, that has already been computed by
+ /// subtracting the gsym::Header::BaseAddress.
+ /// \returns The matching address offset index. This index will be used to
+ /// extract the FunctionInfo data's offset from the AddrInfoOffsets array.
+ template <class T>
+ uint64_t getAddressOffsetIndex(const uint64_t AddrOffset) const {
+ ArrayRef<T> AIO = getAddrOffsets<T>();
+ const auto Begin = AIO.begin();
+ const auto End = AIO.end();
+ auto Iter = std::lower_bound(Begin, End, AddrOffset);
+ if (Iter == End || AddrOffset < *Iter)
+ --Iter;
+ return std::distance(Begin, Iter);
+ }
+
+ /// Create a GSYM from a memory buffer.
+ ///
+ /// Called by both openFile() and copyBuffer(), this function does all of the
+ /// work of parsing the GSYM file and returning an error.
+ ///
+ /// \param MemBuffer A memory buffer that will transfer ownership into the
+ /// GsymReader.
+ /// \returns An expected GsymReader that contains the object or an error
+ /// object that indicates reason for failing to read the GSYM.
+ static llvm::Expected<llvm::gsym::GsymReader>
+ create(std::unique_ptr<MemoryBuffer> &MemBuffer);
+
+
+ /// Given an address, find the address index.
+ ///
+ /// Binary search the address table and find the matching address index.
+ ///
+ /// \param Addr A virtual address that matches the original object file
+ /// to lookup.
+ /// \returns An index into the address table. This index can be used to
+ /// extract the FunctionInfo data's offset from the AddrInfoOffsets array.
+ /// Returns an error if the address isn't in the GSYM with details of why.
+ Expected<uint64_t> getAddressIndex(const uint64_t Addr) const;
+
+ /// Given an address index, get the offset for the FunctionInfo.
+ ///
+ /// Looking up an address is done by finding the corresponding address
+ /// index for the address. This index is then used to get the offset of the
+ /// FunctionInfo data that we will decode using this function.
+ ///
+ /// \param Index An index into the address table.
+ /// \returns An optional GSYM data offset for the offset of the FunctionInfo
+ /// that needs to be decoded.
+ Optional<uint64_t> getAddressInfoOffset(size_t Index) const;
+};
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_GSYMREADER_H
diff --git a/include/llvm/DebugInfo/GSYM/Header.h b/include/llvm/DebugInfo/GSYM/Header.h
new file mode 100644
index 000000000000..6652c59c97a6
--- /dev/null
+++ b/include/llvm/DebugInfo/GSYM/Header.h
@@ -0,0 +1,129 @@
+//===- Header.h -------------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_GSYM_HEADER_H
+#define LLVM_DEBUGINFO_GSYM_HEADER_H
+
+#include "llvm/Support/Error.h"
+
+#include <cstddef>
+#include <cstdint>
+
+namespace llvm {
+class raw_ostream;
+class DataExtractor;
+
+namespace gsym {
+class FileWriter;
+
+constexpr uint32_t GSYM_MAGIC = 0x4753594d; // 'GSYM'
+constexpr uint32_t GSYM_CIGAM = 0x4d595347; // 'MYSG'
+constexpr uint32_t GSYM_VERSION = 1;
+constexpr size_t GSYM_MAX_UUID_SIZE = 20;
+
+/// The GSYM header.
+///
+/// The GSYM header is found at the start of a stand alone GSYM file, or as
+/// the first bytes in a section when GSYM is contained in a section of an
+/// executable file (ELF, mach-o, COFF).
+///
+/// The structure is encoded exactly as it appears in the structure definition
+/// with no gaps between members. Alignment should not change from system to
+/// system as the members were laid out so that they shouldn't align
+/// differently on different architectures.
+///
+/// When endianness of the system loading a GSYM file matches, the file can
+/// be mmap'ed in and a pointer to the header can be cast to the first bytes
+/// of the file (stand alone GSYM file) or section data (GSYM in a section).
+/// When endianness is swapped, the Header::decode() function should be used to
+/// decode the header.
+struct Header {
+ /// The magic bytes should be set to GSYM_MAGIC. This helps detect if a file
+ /// is a GSYM file by scanning the first 4 bytes of a file or section.
+ /// This value might appear byte swapped
+ uint32_t Magic;
+ /// The version can number determines how the header is decoded and how each
+ /// InfoType in FunctionInfo is encoded/decoded. As version numbers increase,
+ /// "Magic" and "Version" members should always appear at offset zero and 4
+ /// respectively to ensure clients figure out if they can parse the format.
+ uint16_t Version;
+ /// The size in bytes of each address offset in the address offsets table.
+ uint8_t AddrOffSize;
+ /// The size in bytes of the UUID encoded in the "UUID" member.
+ uint8_t UUIDSize;
+ /// The 64 bit base address that all address offsets in the address offsets
+ /// table are relative to. Storing a full 64 bit address allows our address
+ /// offsets table to be smaller on disk.
+ uint64_t BaseAddress;
+ /// The number of addresses stored in the address offsets table.
+ uint32_t NumAddresses;
+ /// The file relative offset of the start of the string table for strings
+ /// contained in the GSYM file. If the GSYM in contained in a stand alone
+ /// file this will be the file offset of the start of the string table. If
+ /// the GSYM is contained in a section within an executable file, this can
+ /// be the offset of the first string used in the GSYM file and can possibly
+ /// span one or more executable string tables. This allows the strings to
+ /// share string tables in an ELF or mach-o file.
+ uint32_t StrtabOffset;
+ /// The size in bytes of the string table. For a stand alone GSYM file, this
+ /// will be the exact size in bytes of the string table. When the GSYM data
+ /// is in a section within an executable file, this size can span one or more
+ /// sections that contains strings. This allows any strings that are already
+ /// stored in the executable file to be re-used, and any extra strings could
+ /// be added to another string table and the string table offset and size
+ /// can be set to span all needed string tables.
+ uint32_t StrtabSize;
+ /// The UUID of the original executable file. This is stored to allow
+ /// matching a GSYM file to an executable file when symbolication is
+ /// required. Only the first "UUIDSize" bytes of the UUID are valid. Any
+ /// bytes in the UUID value that appear after the first UUIDSize bytes should
+ /// be set to zero.
+ uint8_t UUID[GSYM_MAX_UUID_SIZE];
+
+ /// Check if a header is valid and return an error if anything is wrong.
+ ///
+ /// This function can be used prior to encoding a header to ensure it is
+ /// valid, or after decoding a header to ensure it is valid and supported.
+ ///
+ /// Check a correctly byte swapped header for errors:
+ /// - check magic value
+ /// - check that version number is supported
+ /// - check that the address offset size is supported
+ /// - check that the UUID size is valid
+ ///
+ /// \returns An error if anything is wrong in the header, or Error::success()
+ /// if there are no errors.
+ llvm::Error checkForError() const;
+
+ /// Decode an object from a binary data stream.
+ ///
+ /// \param Data The binary stream to read the data from. This object must
+ /// have the data for the object starting at offset zero. The data
+ /// can contain more data than needed.
+ ///
+ /// \returns A Header or an error describing the issue that was
+ /// encountered during decoding.
+ static llvm::Expected<Header> decode(DataExtractor &Data);
+
+ /// Encode this object into FileWriter stream.
+ ///
+ /// \param O The binary stream to write the data to at the current file
+ /// position.
+ ///
+ /// \returns An error object that indicates success or failure of the
+ /// encoding process.
+ llvm::Error encode(FileWriter &O) const;
+};
+
+bool operator==(const Header &LHS, const Header &RHS);
+raw_ostream &operator<<(raw_ostream &OS, const llvm::gsym::Header &H);
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_HEADER_H
diff --git a/include/llvm/DebugInfo/GSYM/InlineInfo.h b/include/llvm/DebugInfo/GSYM/InlineInfo.h
index 222430622932..48fd9a7c1308 100644
--- a/include/llvm/DebugInfo/GSYM/InlineInfo.h
+++ b/include/llvm/DebugInfo/GSYM/InlineInfo.h
@@ -1,9 +1,8 @@
//===- InlineInfo.h ---------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
@@ -12,6 +11,7 @@
#include "llvm/ADT/Optional.h"
#include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/Support/Error.h"
#include <stdint.h>
#include <vector>
@@ -31,6 +31,30 @@ namespace gsym {
/// Any clients that encode information will need to ensure the ranges are
/// all contined correctly or lookups could fail. Add ranges in these objects
/// must be contained in the top level FunctionInfo address ranges as well.
+///
+/// ENCODING
+///
+/// When saved to disk, the inline info encodes all ranges to be relative to
+/// a parent address range. This will be the FunctionInfo's start address if
+/// the InlineInfo is directly contained in a FunctionInfo, or a the start
+/// address of the containing parent InlineInfo's first "Ranges" member. This
+/// allows address ranges to be efficiently encoded using ULEB128 encodings as
+/// we encode the offset and size of each range instead of full addresses. This
+/// also makes any encoded addresses easy to relocate as we just need to
+/// relocate the FunctionInfo's start address.
+///
+/// - The AddressRanges member "Ranges" is encoded using an approriate base
+/// address as described above.
+/// - UINT8 boolean value that specifies if the InlineInfo object has children.
+/// - UINT32 string table offset that points to the name of the inline
+/// function.
+/// - ULEB128 integer that specifies the file of the call site that called
+/// this function.
+/// - ULEB128 integer that specifies the source line of the call site that
+/// called this function.
+/// - if this object has children, enocode each child InlineInfo using the
+/// the first address range's start address as the base address.
+///
struct InlineInfo {
uint32_t Name; ///< String table offset in the string table.
@@ -62,6 +86,37 @@ struct InlineInfo {
/// \returns optional vector of InlineInfo objects that describe the
/// inline call stack for a given address, false otherwise.
llvm::Optional<InlineArray> getInlineStack(uint64_t Addr) const;
+
+ /// Decode an InlineInfo object from a binary data stream.
+ ///
+ /// \param Data The binary stream to read the data from. This object must
+ /// have the data for the InlineInfo object starting at offset zero. The data
+ /// can contain more data than needed.
+ ///
+ /// \param BaseAddr The base address to use when decoding all address ranges.
+ /// This will be the FunctionInfo's start address if this object is directly
+ /// contained in a FunctionInfo object, or the start address of the first
+ /// address range in an InlineInfo object of this object is a child of
+ /// another InlineInfo object.
+ /// \returns An InlineInfo or an error describing the issue that was
+ /// encountered during decoding.
+ static llvm::Expected<InlineInfo> decode(DataExtractor &Data,
+ uint64_t BaseAddr);
+
+ /// Encode this InlineInfo object into FileWriter stream.
+ ///
+ /// \param O The binary stream to write the data to at the current file
+ /// position.
+ ///
+ /// \param BaseAddr The base address to use when encoding all address ranges.
+ /// This will be the FunctionInfo's start address if this object is directly
+ /// contained in a FunctionInfo object, or the start address of the first
+ /// address range in an InlineInfo object of this object is a child of
+ /// another InlineInfo object.
+ ///
+ /// \returns An error object that indicates success or failure or the
+ /// encoding process.
+ llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const;
};
inline bool operator==(const InlineInfo &LHS, const InlineInfo &RHS) {
diff --git a/include/llvm/DebugInfo/GSYM/LineEntry.h b/include/llvm/DebugInfo/GSYM/LineEntry.h
index 6b9380940bd3..aac7c48e067e 100644
--- a/include/llvm/DebugInfo/GSYM/LineEntry.h
+++ b/include/llvm/DebugInfo/GSYM/LineEntry.h
@@ -1,9 +1,8 @@
//===- LineEntry.h ----------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/DebugInfo/GSYM/LineTable.h b/include/llvm/DebugInfo/GSYM/LineTable.h
new file mode 100644
index 000000000000..3cdbccb08ced
--- /dev/null
+++ b/include/llvm/DebugInfo/GSYM/LineTable.h
@@ -0,0 +1,198 @@
+//===- LineTable.h ----------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_DEBUGINFO_GSYM_LINETABLE_H
+#define LLVM_DEBUGINFO_GSYM_LINETABLE_H
+
+#include "llvm/DebugInfo/GSYM/LineEntry.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <vector>
+
+namespace llvm {
+namespace gsym {
+
+struct FunctionInfo;
+class FileWriter;
+
+/// LineTable class contains deserialized versions of line tables for each
+/// function's address ranges.
+///
+/// When saved to disk, the line table is encoded using a modified version of
+/// the DWARF line tables that only tracks address to source file and line.
+///
+/// ENCODING
+///
+/// The line table starts with a small prolog that contains the following
+/// values:
+///
+/// ENCODING NAME DESCRIPTION
+/// ======== =========== ====================================================
+/// SLEB MinDelta The min line delta for special opcodes that advance
+/// the address and line number.
+/// SLEB MaxDelta The max line delta for single byte opcodes that
+/// advance the address and line number.
+/// ULEB FirstLine The value of the first source line number to
+/// initialize the LineEntry with.
+///
+/// Once these prolog items are read, we initialize a LineEntry struct with
+/// the start address of the function from the FunctionInfo's address range,
+/// a default file index of 1, and the line number set to "FirstLine" from
+/// the prolog above:
+///
+/// LineEntry Row(BaseAddr, 1, FirstLine);
+///
+/// The line table state machine is now initialized and ready to be parsed.
+/// The stream that follows this encodes the line entries in a compact
+/// form. Some opcodes cause "Row" to be modified and some opcodes may also
+/// push "Row" onto the end of the "LineTable.Lines" vector. The end result
+/// is a vector of LineEntry structs that is sorted in ascending address
+/// order.
+///
+/// NORMAL OPCODES
+///
+/// The opcodes 0 through 3 are normal in opcodes. Their encoding and
+/// descriptions are listed below:
+///
+/// ENCODING ENUMERATION VALUE DESCRIPTION
+/// ======== ================ ===== ========================================
+/// LTOC_EndSequence 0x00 Parsing is done.
+/// ULEB LTOC_SetFile 0x01 Row.File = ULEB
+/// ULEB LTOC_AdvancePC 0x02 Row.Addr += ULEB, push "Row".
+/// SLEB LTOC_AdvanceLine 0x03 Row.Line += SLEB
+/// LTOC_FirstSpecial 0x04 First special opcode (see SPECIAL
+/// OPCODES below).
+///
+/// SPECIAL OPCODES
+///
+/// Opcodes LTOC_FirstSpecial through 255 are special opcodes that always
+/// increment both the Row.Addr and Row.Line and push "Row" onto the
+/// LineEntry.Lines array. They do this by using some of the bits to
+/// increment/decrement the source line number, and some of the bits to
+/// increment the address. Line numbers can go up or down when making line
+/// tables, where addresses always only increase since line tables are sorted
+/// by address.
+///
+/// In order to calculate the amount to increment the line and address for
+/// these special opcodes, we calculate the number of values reserved for the
+/// line increment/decrement using the "MinDelta" and "MaxDelta" from the
+/// prolog:
+///
+/// const int64_t LineRange = MaxDelta - MinDelta + 1;
+///
+/// Then we can adjust the opcode to not include any of the normal opcodes:
+///
+/// const uint8_t AdjustedOp = Opcode - LTOC_FirstSpecial;
+///
+/// And we can calculate the line offset, and address offset:
+///
+/// const int64_t LineDelta = MinDelta + (AdjustedOp % LineRange);
+/// const uint64_t AddrDelta = (AdjustedOp / LineRange);
+///
+/// And use these to modify our "Row":
+///
+/// Row.Line += LineDelta;
+/// Row.Addr += AddrDelta;
+///
+/// And push a row onto the line table:
+///
+/// Lines.push_back(Row);
+///
+/// This is verify similar to the way that DWARF encodes its line tables. The
+/// only difference is the DWARF line tables have more normal opcodes and the
+/// "Row" contains more members, like source column number, bools for end of
+/// prologue, beginnging of epilogue, is statement and many others. There are
+/// also more complex rules that happen for the extra normal opcodes. By
+/// leaving these extra opcodes out, we leave more bits for the special
+/// opcodes that allows us to encode line tables in fewer bytes than standard
+/// DWARF encodings.
+///
+/// Opcodes that will push "Row" onto the LineEntry.Lines include the
+/// LTOC_AdvancePC opcode and all special opcodes. All other opcodes
+/// only modify the current "Row", or cause the line table to end.
+class LineTable {
+ typedef std::vector<gsym::LineEntry> Collection;
+ Collection Lines; ///< All line entries in the line table.
+public:
+ static LineEntry lookup(DataExtractor &Data, uint64_t BaseAddr,
+ uint64_t Addr);
+
+ /// Decode an LineTable object from a binary data stream.
+ ///
+ /// \param Data The binary stream to read the data from. This object must
+ /// have the data for the LineTable object starting at offset zero. The data
+ /// can contain more data than needed.
+ ///
+ /// \param BaseAddr The base address to use when decoding the line table.
+ /// This will be the FunctionInfo's start address and will be used to
+ /// initialize the line table row prior to parsing any opcodes.
+ ///
+ /// \returns An LineTable or an error describing the issue that was
+ /// encountered during decoding.
+ static llvm::Expected<LineTable> decode(DataExtractor &Data,
+ uint64_t BaseAddr);
+ /// Encode this LineTable object into FileWriter stream.
+ ///
+ /// \param O The binary stream to write the data to at the current file
+ /// position.
+ ///
+ /// \param BaseAddr The base address to use when decoding the line table.
+ /// This will be the FunctionInfo's start address.
+ ///
+ /// \returns An error object that indicates success or failure or the
+ /// encoding process.
+ llvm::Error encode(FileWriter &O, uint64_t BaseAddr) const;
+ bool empty() const { return Lines.empty(); }
+ void clear() { Lines.clear(); }
+ void push(const LineEntry &LE) {
+ Lines.push_back(LE);
+ }
+ size_t isValid() const {
+ return !Lines.empty();
+ }
+ size_t size() const {
+ return Lines.size();
+ }
+ LineEntry &get(size_t i) {
+ assert(i < Lines.size());
+ return Lines[i];
+ }
+ const LineEntry &get(size_t i) const {
+ assert(i < Lines.size());
+ return Lines[i];
+ }
+ LineEntry &operator[](size_t i) {
+ return get(i);
+ }
+ const LineEntry &operator[](size_t i) const {
+ return get(i);
+ }
+ bool operator==(const LineTable &RHS) const {
+ return Lines == RHS.Lines;
+ }
+ bool operator!=(const LineTable &RHS) const {
+ return Lines != RHS.Lines;
+ }
+ bool operator<(const LineTable &RHS) const {
+ const auto LHSSize = Lines.size();
+ const auto RHSSize = RHS.Lines.size();
+ if (LHSSize == RHSSize)
+ return Lines < RHS.Lines;
+ return LHSSize < RHSSize;
+ }
+ Collection::const_iterator begin() const { return Lines.begin(); }
+ Collection::const_iterator end() const { return Lines.end(); }
+
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const gsym::LineTable &LT);
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_LINETABLE_H
diff --git a/include/llvm/DebugInfo/GSYM/Range.h b/include/llvm/DebugInfo/GSYM/Range.h
index 772ff244c5b7..37cfec713f26 100644
--- a/include/llvm/DebugInfo/GSYM/Range.h
+++ b/include/llvm/DebugInfo/GSYM/Range.h
@@ -1,9 +1,8 @@
-//===- AddressRange.h -------------------------------------------*- C++ -*-===//
+//===- Range.h --------------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
@@ -21,10 +20,13 @@
#define HEX64(v) llvm::format_hex(v, 18)
namespace llvm {
+class DataExtractor;
class raw_ostream;
namespace gsym {
+class FileWriter;
+
/// A class that represents an address range. The range is specified using
/// a start and an end address.
struct AddressRange {
@@ -47,6 +49,18 @@ struct AddressRange {
bool operator<(const AddressRange &R) const {
return std::make_pair(Start, End) < std::make_pair(R.Start, R.End);
}
+ /// AddressRange objects are encoded and decoded to be relative to a base
+ /// address. This will be the FunctionInfo's start address if the AddressRange
+ /// is directly contained in a FunctionInfo, or a base address of the
+ /// containing parent AddressRange or AddressRanges. This allows address
+ /// ranges to be efficiently encoded using ULEB128 encodings as we encode the
+ /// offset and size of each range instead of full addresses. This also makes
+ /// encoded addresses easy to relocate as we just need to relocate one base
+ /// address.
+ /// @{
+ void decode(DataExtractor &Data, uint64_t BaseAddr, uint64_t &Offset);
+ void encode(FileWriter &O, uint64_t BaseAddr) const;
+ /// @}
};
raw_ostream &operator<<(raw_ostream &OS, const AddressRange &R);
@@ -66,6 +80,7 @@ public:
void clear() { Ranges.clear(); }
bool empty() const { return Ranges.empty(); }
bool contains(uint64_t Addr) const;
+ bool contains(AddressRange Range) const;
void insert(AddressRange Range);
size_t size() const { return Ranges.size(); }
bool operator==(const AddressRanges &RHS) const {
@@ -77,6 +92,14 @@ public:
}
Collection::const_iterator begin() const { return Ranges.begin(); }
Collection::const_iterator end() const { return Ranges.end(); }
+
+ /// Address ranges are decoded and encoded to be relative to a base address.
+ /// See the AddressRange comment for the encode and decode methods for full
+ /// details.
+ /// @{
+ void decode(DataExtractor &Data, uint64_t BaseAddr, uint64_t &Offset);
+ void encode(FileWriter &O, uint64_t BaseAddr) const;
+ /// @}
};
raw_ostream &operator<<(raw_ostream &OS, const AddressRanges &AR);
diff --git a/include/llvm/DebugInfo/GSYM/StringTable.h b/include/llvm/DebugInfo/GSYM/StringTable.h
index 0001b8b82743..a96ae5899da3 100644
--- a/include/llvm/DebugInfo/GSYM/StringTable.h
+++ b/include/llvm/DebugInfo/GSYM/StringTable.h
@@ -1,9 +1,8 @@
//===- StringTable.h --------------------------------------------*- C++ -*-===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// 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
//
//===----------------------------------------------------------------------===//
diff --git a/include/llvm/DebugInfo/PDB/GenericError.h b/include/llvm/DebugInfo/PDB/GenericError.h
index ec85d92d2a92..af93be931b8e 100644
--- a/include/llvm/DebugInfo/PDB/GenericError.h
+++ b/include/llvm/DebugInfo/PDB/GenericError.h
@@ -20,7 +20,7 @@ enum class pdb_error_code {
dia_sdk_not_present,
dia_failed_loading,
signature_out_of_date,
- external_cmdline_ref,
+ no_matching_pch,
unspecified,
};
} // namespace pdb
diff --git a/include/llvm/DebugInfo/PDB/Native/SymbolCache.h b/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
index 0b15ab474f71..4adf3b394c2e 100644
--- a/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
+++ b/include/llvm/DebugInfo/PDB/Native/SymbolCache.h
@@ -87,7 +87,7 @@ public:
// Initial construction must not access the cache, since it must be done
// atomically.
- auto Result = llvm::make_unique<ConcreteSymbolT>(
+ auto Result = std::make_unique<ConcreteSymbolT>(
Session, Id, std::forward<Args>(ConstructorArgs)...);
Result->SymbolId = Id;
diff --git a/include/llvm/DebugInfo/PDB/PDBSymbol.h b/include/llvm/DebugInfo/PDB/PDBSymbol.h
index d9004a8894d9..0d95a2467556 100644
--- a/include/llvm/DebugInfo/PDB/PDBSymbol.h
+++ b/include/llvm/DebugInfo/PDB/PDBSymbol.h
@@ -131,7 +131,7 @@ public:
auto BaseIter = RawSymbol->findChildren(T::Tag);
if (!BaseIter)
return nullptr;
- return llvm::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
+ return std::make_unique<ConcreteSymbolEnumerator<T>>(std::move(BaseIter));
}
std::unique_ptr<IPDBEnumSymbols> findAllChildren(PDB_SymType Type) const;
std::unique_ptr<IPDBEnumSymbols> findAllChildren() const;
diff --git a/include/llvm/DebugInfo/Symbolize/Symbolize.h b/include/llvm/DebugInfo/Symbolize/Symbolize.h
index d3da28ca0b7b..11599fc1797d 100644
--- a/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -39,6 +39,7 @@ public:
bool UseSymbolTable = true;
bool Demangle = true;
bool RelativeAddresses = false;
+ bool UntagAddresses = false;
std::string DefaultArch;
std::vector<std::string> DsymHints;
std::string FallbackDebugPath;