Update prebuilt Clang to r365631c1 from Android.
The version we had was segfaulting.
Bug: 132420445
Change-Id: Icb45a6fe0b4e2166f7895e669df1157cec9fb4e0
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVRecord.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVRecord.h
index 1df3d16..784c47e 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVRecord.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVRecord.h
@@ -24,17 +24,31 @@
namespace codeview {
+/// CVRecord is a fat pointer (base + size pair) to a symbol or type record.
+/// Carrying the size separately instead of trusting the size stored in the
+/// record prefix provides some extra safety and flexibility.
template <typename Kind> class CVRecord {
public:
- CVRecord() : Type(static_cast<Kind>(0)) {}
+ CVRecord() = default;
- CVRecord(Kind K, ArrayRef<uint8_t> Data) : Type(K), RecordData(Data) {}
+ CVRecord(ArrayRef<uint8_t> Data) : RecordData(Data) {}
- bool valid() const { return Type != static_cast<Kind>(0); }
+ CVRecord(const RecordPrefix *P, size_t Size)
+ : RecordData(reinterpret_cast<const uint8_t *>(P), Size) {}
+
+ bool valid() const { return kind() != Kind(0); }
uint32_t length() const { return RecordData.size(); }
- Kind kind() const { return Type; }
+
+ Kind kind() const {
+ if (RecordData.size() < sizeof(RecordPrefix))
+ return Kind(0);
+ return static_cast<Kind>(static_cast<uint16_t>(
+ reinterpret_cast<const RecordPrefix *>(RecordData.data())->RecordKind));
+ }
+
ArrayRef<uint8_t> data() const { return RecordData; }
+
StringRef str_data() const {
return StringRef(reinterpret_cast<const char *>(RecordData.data()),
RecordData.size());
@@ -44,7 +58,6 @@
return RecordData.drop_front(sizeof(RecordPrefix));
}
- Kind Type;
ArrayRef<uint8_t> RecordData;
};
@@ -71,8 +84,7 @@
ArrayRef<uint8_t> Data = StreamBuffer.take_front(RealLen);
StreamBuffer = StreamBuffer.drop_front(RealLen);
- Record R(static_cast<decltype(Record::Type)>((uint16_t)Prefix->RecordKind),
- Data);
+ Record R(Data);
if (auto EC = F(R))
return EC;
}
@@ -91,13 +103,12 @@
return std::move(EC);
if (Prefix->RecordLen < 2)
return make_error<CodeViewError>(cv_error_code::corrupt_record);
- Kind K = static_cast<Kind>(uint16_t(Prefix->RecordKind));
Reader.setOffset(Offset);
ArrayRef<uint8_t> RawData;
if (auto EC = Reader.readBytes(RawData, Prefix->RecordLen + sizeof(uint16_t)))
return std::move(EC);
- return codeview::CVRecord<Kind>(K, RawData);
+ return codeview::CVRecord<Kind>(RawData);
}
} // end namespace codeview
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
index 7538cb2..7d20bb0 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CVTypeVisitor.h
@@ -11,6 +11,7 @@
#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 {
@@ -30,6 +31,9 @@
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/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h
index 4fbf507..c3acb05 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeView.h
@@ -159,9 +159,10 @@
MSIL = 0x0f,
HLSL = 0x10,
- /// The DMD compiler emits 'D' for the CV source language. Microsoft doesn't
- /// have an enumerator for it yet.
+ /// The DMD & Swift compilers emit 'D' and 'S', respectively, for the CV
+ /// source language. Microsoft does not have enumerators for them yet.
D = 'D',
+ Swift = 'S',
};
/// These values correspond to the CV_call_e enumeration, and are documented
@@ -303,6 +304,9 @@
};
CV_DEFINE_ENUM_CLASS_FLAGS_OPERATORS(ModifierOptions)
+// If the subsection kind has this bit set, then the linker should ignore it.
+enum : uint32_t { SubsectionIgnoreFlag = 0x80000000 };
+
enum class DebugSubsectionKind : uint32_t {
None = 0,
Symbols = 0xf1,
@@ -508,9 +512,23 @@
// Corresponds to CV_HREG_e enum.
enum class RegisterId : uint16_t {
+#define CV_REGISTERS_ALL
#define CV_REGISTER(name, value) name = value,
#include "CodeViewRegisters.def"
#undef CV_REGISTER
+#undef CV_REGISTERS_ALL
+};
+
+// Register Ids are shared between architectures in CodeView. CPUType is needed
+// to map register Id to name.
+struct CPURegister {
+ CPURegister() = delete;
+ CPURegister(CPUType Cpu, codeview::RegisterId Reg) {
+ this->Cpu = Cpu;
+ this->Reg = Reg;
+ }
+ CPUType Cpu;
+ RegisterId Reg;
};
/// Two-bit value indicating which register is the designated frame pointer
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
index b2476f1..d3bad4c 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRecordIO.h
@@ -24,28 +24,64 @@
#include <type_traits>
namespace llvm {
+
namespace codeview {
+class CodeViewRecordStreamer {
+public:
+ virtual void EmitBytes(StringRef Data) = 0;
+ virtual void EmitIntValue(uint64_t Value, unsigned Size) = 0;
+ virtual void EmitBinaryData(StringRef Data) = 0;
+ virtual ~CodeViewRecordStreamer() = default;
+};
+
class CodeViewRecordIO {
uint32_t getCurrentOffset() const {
- return (isWriting()) ? Writer->getOffset() : Reader->getOffset();
+ if (isWriting())
+ return Writer->getOffset();
+ else if (isReading())
+ return Reader->getOffset();
+ else
+ return 0;
}
public:
+ // deserializes records to structures
explicit CodeViewRecordIO(BinaryStreamReader &Reader) : Reader(&Reader) {}
+
+ // serializes records to buffer
explicit CodeViewRecordIO(BinaryStreamWriter &Writer) : Writer(&Writer) {}
+ // writes records to assembly file using MC library interface
+ explicit CodeViewRecordIO(CodeViewRecordStreamer &Streamer)
+ : Streamer(&Streamer) {}
+
Error beginRecord(Optional<uint32_t> MaxLength);
Error endRecord();
Error mapInteger(TypeIndex &TypeInd);
- bool isReading() const { return Reader != nullptr; }
- bool isWriting() const { return !isReading(); }
+ bool isStreaming() const {
+ return (Streamer != nullptr) && (Reader == nullptr) && (Writer == nullptr);
+ }
+ bool isReading() const {
+ return (Reader != nullptr) && (Streamer == nullptr) && (Writer == nullptr);
+ }
+ bool isWriting() const {
+ return (Writer != nullptr) && (Streamer == nullptr) && (Reader == nullptr);
+ }
uint32_t maxFieldLength() const;
template <typename T> Error mapObject(T &Value) {
+ if (isStreaming()) {
+ StringRef BytesSR =
+ StringRef((reinterpret_cast<const char *>(&Value)), sizeof(Value));
+ Streamer->EmitBytes(BytesSR);
+ incrStreamedLen(sizeof(T));
+ return Error::success();
+ }
+
if (isWriting())
return Writer->writeObject(Value);
@@ -57,6 +93,12 @@
}
template <typename T> Error mapInteger(T &Value) {
+ if (isStreaming()) {
+ Streamer->EmitIntValue((int)Value, sizeof(T));
+ incrStreamedLen(sizeof(T));
+ return Error::success();
+ }
+
if (isWriting())
return Writer->writeInteger(Value);
@@ -64,18 +106,21 @@
}
template <typename T> Error mapEnum(T &Value) {
- if (sizeof(Value) > maxFieldLength())
+ if (!isStreaming() && sizeof(Value) > maxFieldLength())
return make_error<CodeViewError>(cv_error_code::insufficient_buffer);
using U = typename std::underlying_type<T>::type;
U X;
- if (isWriting())
+
+ if (isWriting() || isStreaming())
X = static_cast<U>(Value);
if (auto EC = mapInteger(X))
return EC;
+
if (isReading())
Value = static_cast<T>(X);
+
return Error::success();
}
@@ -90,7 +135,16 @@
template <typename SizeType, typename T, typename ElementMapper>
Error mapVectorN(T &Items, const ElementMapper &Mapper) {
SizeType Size;
- if (isWriting()) {
+ if (isStreaming()) {
+ Size = static_cast<SizeType>(Items.size());
+ Streamer->EmitIntValue(Size, sizeof(Size));
+ incrStreamedLen(sizeof(Size)); // add 1 for the delimiter
+
+ for (auto &X : Items) {
+ if (auto EC = Mapper(*this, X))
+ return EC;
+ }
+ } else if (isWriting()) {
Size = static_cast<SizeType>(Items.size());
if (auto EC = Writer->writeInteger(Size))
return EC;
@@ -115,7 +169,7 @@
template <typename T, typename ElementMapper>
Error mapVectorTail(T &Items, const ElementMapper &Mapper) {
- if (isWriting()) {
+ if (isStreaming() || isWriting()) {
for (auto &Item : Items) {
if (auto EC = Mapper(*this, Item))
return EC;
@@ -138,10 +192,28 @@
Error padToAlignment(uint32_t Align);
Error skipPadding();
+ uint64_t getStreamedLen() {
+ if (isStreaming())
+ return StreamedLen;
+ return 0;
+ }
+
private:
+ void emitEncodedSignedInteger(const int64_t &Value);
+ void emitEncodedUnsignedInteger(const uint64_t &Value);
Error writeEncodedSignedInteger(const int64_t &Value);
Error writeEncodedUnsignedInteger(const uint64_t &Value);
+ void incrStreamedLen(const uint64_t &Len) {
+ if (isStreaming())
+ StreamedLen += Len;
+ }
+
+ void resetStreamedLen() {
+ if (isStreaming())
+ StreamedLen = 4; // The record prefix is 4 bytes long
+ }
+
struct RecordLimit {
uint32_t BeginOffset;
Optional<uint32_t> MaxLength;
@@ -162,6 +234,8 @@
BinaryStreamReader *Reader = nullptr;
BinaryStreamWriter *Writer = nullptr;
+ CodeViewRecordStreamer *Streamer = nullptr;
+ uint64_t StreamedLen = 0;
};
} // end namespace codeview
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
index 0593bc0..9767e49 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewRegisters.def
@@ -14,8 +14,15 @@
#define CV_REGISTER(name, value)
#endif
+#if !defined(CV_REGISTERS_ALL) && !defined(CV_REGISTERS_X86) && \
+ !defined(CV_REGISTERS_ARM64)
+#error Need include at least one register set.
+#endif
+
// This currently only contains the "register subset shared by all processor
-// types" (ERR etc.) and the x86 registers.
+// types" (ERR etc.) and the x86/arm64 registers.
+
+#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_X86)
// Some system headers define macros that conflict with our enums. Every
// compiler supported by LLVM has the push_macro and pop_macro pragmas, so use
@@ -356,3 +363,197 @@
#pragma pop_macro("CR2")
#pragma pop_macro("CR3")
#pragma pop_macro("CR4")
+
+#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_X86)
+
+#if defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64)
+
+// ARM64 registers
+
+CV_REGISTER(ARM64_NOREG, 0)
+
+// General purpose 32-bit integer registers
+
+CV_REGISTER(ARM64_W0, 10)
+CV_REGISTER(ARM64_W1, 11)
+CV_REGISTER(ARM64_W2, 12)
+CV_REGISTER(ARM64_W3, 13)
+CV_REGISTER(ARM64_W4, 14)
+CV_REGISTER(ARM64_W5, 15)
+CV_REGISTER(ARM64_W6, 16)
+CV_REGISTER(ARM64_W7, 17)
+CV_REGISTER(ARM64_W8, 18)
+CV_REGISTER(ARM64_W9, 19)
+CV_REGISTER(ARM64_W10, 20)
+CV_REGISTER(ARM64_W11, 21)
+CV_REGISTER(ARM64_W12, 22)
+CV_REGISTER(ARM64_W13, 23)
+CV_REGISTER(ARM64_W14, 24)
+CV_REGISTER(ARM64_W15, 25)
+CV_REGISTER(ARM64_W16, 26)
+CV_REGISTER(ARM64_W17, 27)
+CV_REGISTER(ARM64_W18, 28)
+CV_REGISTER(ARM64_W19, 29)
+CV_REGISTER(ARM64_W20, 30)
+CV_REGISTER(ARM64_W21, 31)
+CV_REGISTER(ARM64_W22, 32)
+CV_REGISTER(ARM64_W23, 33)
+CV_REGISTER(ARM64_W24, 34)
+CV_REGISTER(ARM64_W25, 35)
+CV_REGISTER(ARM64_W26, 36)
+CV_REGISTER(ARM64_W27, 37)
+CV_REGISTER(ARM64_W28, 38)
+CV_REGISTER(ARM64_W29, 39)
+CV_REGISTER(ARM64_W30, 40)
+CV_REGISTER(ARM64_WZR, 41)
+
+// General purpose 64-bit integer registers
+
+CV_REGISTER(ARM64_X0, 50)
+CV_REGISTER(ARM64_X1, 51)
+CV_REGISTER(ARM64_X2, 52)
+CV_REGISTER(ARM64_X3, 53)
+CV_REGISTER(ARM64_X4, 54)
+CV_REGISTER(ARM64_X5, 55)
+CV_REGISTER(ARM64_X6, 56)
+CV_REGISTER(ARM64_X7, 57)
+CV_REGISTER(ARM64_X8, 58)
+CV_REGISTER(ARM64_X9, 59)
+CV_REGISTER(ARM64_X10, 60)
+CV_REGISTER(ARM64_X11, 61)
+CV_REGISTER(ARM64_X12, 62)
+CV_REGISTER(ARM64_X13, 63)
+CV_REGISTER(ARM64_X14, 64)
+CV_REGISTER(ARM64_X15, 65)
+CV_REGISTER(ARM64_X16, 66)
+CV_REGISTER(ARM64_X17, 67)
+CV_REGISTER(ARM64_X18, 68)
+CV_REGISTER(ARM64_X19, 69)
+CV_REGISTER(ARM64_X20, 70)
+CV_REGISTER(ARM64_X21, 71)
+CV_REGISTER(ARM64_X22, 72)
+CV_REGISTER(ARM64_X23, 73)
+CV_REGISTER(ARM64_X24, 74)
+CV_REGISTER(ARM64_X25, 75)
+CV_REGISTER(ARM64_X26, 76)
+CV_REGISTER(ARM64_X27, 77)
+CV_REGISTER(ARM64_X28, 78)
+CV_REGISTER(ARM64_FP, 79)
+CV_REGISTER(ARM64_LR, 80)
+CV_REGISTER(ARM64_SP, 81)
+CV_REGISTER(ARM64_ZR, 82)
+
+// status register
+
+CV_REGISTER(ARM64_NZCV, 90)
+
+// 32-bit floating point registers
+
+CV_REGISTER(ARM64_S0, 100)
+CV_REGISTER(ARM64_S1, 101)
+CV_REGISTER(ARM64_S2, 102)
+CV_REGISTER(ARM64_S3, 103)
+CV_REGISTER(ARM64_S4, 104)
+CV_REGISTER(ARM64_S5, 105)
+CV_REGISTER(ARM64_S6, 106)
+CV_REGISTER(ARM64_S7, 107)
+CV_REGISTER(ARM64_S8, 108)
+CV_REGISTER(ARM64_S9, 109)
+CV_REGISTER(ARM64_S10, 110)
+CV_REGISTER(ARM64_S11, 111)
+CV_REGISTER(ARM64_S12, 112)
+CV_REGISTER(ARM64_S13, 113)
+CV_REGISTER(ARM64_S14, 114)
+CV_REGISTER(ARM64_S15, 115)
+CV_REGISTER(ARM64_S16, 116)
+CV_REGISTER(ARM64_S17, 117)
+CV_REGISTER(ARM64_S18, 118)
+CV_REGISTER(ARM64_S19, 119)
+CV_REGISTER(ARM64_S20, 120)
+CV_REGISTER(ARM64_S21, 121)
+CV_REGISTER(ARM64_S22, 122)
+CV_REGISTER(ARM64_S23, 123)
+CV_REGISTER(ARM64_S24, 124)
+CV_REGISTER(ARM64_S25, 125)
+CV_REGISTER(ARM64_S26, 126)
+CV_REGISTER(ARM64_S27, 127)
+CV_REGISTER(ARM64_S28, 128)
+CV_REGISTER(ARM64_S29, 129)
+CV_REGISTER(ARM64_S30, 130)
+CV_REGISTER(ARM64_S31, 131)
+
+// 64-bit floating point registers
+
+CV_REGISTER(ARM64_D0, 140)
+CV_REGISTER(ARM64_D1, 141)
+CV_REGISTER(ARM64_D2, 142)
+CV_REGISTER(ARM64_D3, 143)
+CV_REGISTER(ARM64_D4, 144)
+CV_REGISTER(ARM64_D5, 145)
+CV_REGISTER(ARM64_D6, 146)
+CV_REGISTER(ARM64_D7, 147)
+CV_REGISTER(ARM64_D8, 148)
+CV_REGISTER(ARM64_D9, 149)
+CV_REGISTER(ARM64_D10, 150)
+CV_REGISTER(ARM64_D11, 151)
+CV_REGISTER(ARM64_D12, 152)
+CV_REGISTER(ARM64_D13, 153)
+CV_REGISTER(ARM64_D14, 154)
+CV_REGISTER(ARM64_D15, 155)
+CV_REGISTER(ARM64_D16, 156)
+CV_REGISTER(ARM64_D17, 157)
+CV_REGISTER(ARM64_D18, 158)
+CV_REGISTER(ARM64_D19, 159)
+CV_REGISTER(ARM64_D20, 160)
+CV_REGISTER(ARM64_D21, 161)
+CV_REGISTER(ARM64_D22, 162)
+CV_REGISTER(ARM64_D23, 163)
+CV_REGISTER(ARM64_D24, 164)
+CV_REGISTER(ARM64_D25, 165)
+CV_REGISTER(ARM64_D26, 166)
+CV_REGISTER(ARM64_D27, 167)
+CV_REGISTER(ARM64_D28, 168)
+CV_REGISTER(ARM64_D29, 169)
+CV_REGISTER(ARM64_D30, 170)
+CV_REGISTER(ARM64_D31, 171)
+
+// 128-bit SIMD registers
+
+CV_REGISTER(ARM64_Q0, 180)
+CV_REGISTER(ARM64_Q1, 181)
+CV_REGISTER(ARM64_Q2, 182)
+CV_REGISTER(ARM64_Q3, 183)
+CV_REGISTER(ARM64_Q4, 184)
+CV_REGISTER(ARM64_Q5, 185)
+CV_REGISTER(ARM64_Q6, 186)
+CV_REGISTER(ARM64_Q7, 187)
+CV_REGISTER(ARM64_Q8, 188)
+CV_REGISTER(ARM64_Q9, 189)
+CV_REGISTER(ARM64_Q10, 190)
+CV_REGISTER(ARM64_Q11, 191)
+CV_REGISTER(ARM64_Q12, 192)
+CV_REGISTER(ARM64_Q13, 193)
+CV_REGISTER(ARM64_Q14, 194)
+CV_REGISTER(ARM64_Q15, 195)
+CV_REGISTER(ARM64_Q16, 196)
+CV_REGISTER(ARM64_Q17, 197)
+CV_REGISTER(ARM64_Q18, 198)
+CV_REGISTER(ARM64_Q19, 199)
+CV_REGISTER(ARM64_Q20, 200)
+CV_REGISTER(ARM64_Q21, 201)
+CV_REGISTER(ARM64_Q22, 202)
+CV_REGISTER(ARM64_Q23, 203)
+CV_REGISTER(ARM64_Q24, 204)
+CV_REGISTER(ARM64_Q25, 205)
+CV_REGISTER(ARM64_Q26, 206)
+CV_REGISTER(ARM64_Q27, 207)
+CV_REGISTER(ARM64_Q28, 208)
+CV_REGISTER(ARM64_Q29, 209)
+CV_REGISTER(ARM64_Q30, 210)
+CV_REGISTER(ARM64_Q31, 211)
+
+// Floating point status register
+
+CV_REGISTER(ARM64_FPSR, 220)
+
+#endif // defined(CV_REGISTERS_ALL) || defined(CV_REGISTERS_ARM64)
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
index e36d804..4f8ccfd 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/CodeViewSymbols.def
@@ -102,7 +102,6 @@
CV_SYMBOL(S_GPROCIA64_ST , 0x1016)
CV_SYMBOL(S_LOCALSLOT_ST , 0x1017)
CV_SYMBOL(S_PARAMSLOT_ST , 0x1018)
-CV_SYMBOL(S_ANNOTATION , 0x1019)
CV_SYMBOL(S_GMANPROC_ST , 0x101a)
CV_SYMBOL(S_LMANPROC_ST , 0x101b)
CV_SYMBOL(S_RESERVED1 , 0x101c)
@@ -254,6 +253,7 @@
SYMBOL_RECORD_ALIAS(S_GTHREAD32 , 0x1113, GlobalTLS, ThreadLocalDataSym)
SYMBOL_RECORD(S_UNAMESPACE , 0x1124, UsingNamespaceSym)
+SYMBOL_RECORD(S_ANNOTATION , 0x1019, AnnotationSym)
#undef CV_SYMBOL
#undef SYMBOL_RECORD
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
index 1ca2bd0..9fd88a6 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h
@@ -70,6 +70,11 @@
}
Error initialize(BinaryStreamReader Reader);
+ Error initialize(BinaryStreamRef Section) {
+ return initialize(BinaryStreamReader(Section));
+ }
+
+ bool valid() const { return Lines.valid(); }
bool hasExtraFiles() const;
Iterator begin() const { return Lines.begin(); }
@@ -77,7 +82,7 @@
private:
InlineeLinesSignature Signature;
- VarStreamArray<InlineeSourceLine> Lines;
+ LinesArray Lines;
};
class DebugInlineeLinesSubsection final : public DebugSubsection {
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/EnumTables.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/EnumTables.h
index 74f8c71..ed126ed 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/EnumTables.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/EnumTables.h
@@ -20,7 +20,7 @@
ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames();
ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames();
-ArrayRef<EnumEntry<uint16_t>> getRegisterNames();
+ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu);
ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames();
ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames();
ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames();
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/RecordSerialization.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/RecordSerialization.h
index 618146c..36c0f2f 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/RecordSerialization.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/RecordSerialization.h
@@ -31,6 +31,9 @@
enum : unsigned { MaxRecordLength = 0xFF00 };
struct RecordPrefix {
+ RecordPrefix() = default;
+ explicit RecordPrefix(uint16_t Kind) : RecordLen(2), RecordKind(Kind) {}
+
ulittle16_t RecordLen; // Record length, starting from &RecordKind.
ulittle16_t RecordKind; // Record kind enum (SymRecordKind or TypeRecordKind)
};
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h
index ac7b106..5e9a743 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolRecord.h
@@ -13,6 +13,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/DebugInfo/CodeView/CVRecord.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
@@ -155,15 +156,19 @@
uint32_t RecordOffset;
};
-struct BinaryAnnotationIterator {
- struct AnnotationData {
- BinaryAnnotationsOpCode OpCode;
- StringRef Name;
- uint32_t U1;
- uint32_t U2;
- int32_t S1;
- };
+struct DecodedAnnotation {
+ StringRef Name;
+ ArrayRef<uint8_t> Bytes;
+ BinaryAnnotationsOpCode OpCode;
+ uint32_t U1 = 0;
+ uint32_t U2 = 0;
+ int32_t S1 = 0;
+};
+struct BinaryAnnotationIterator
+ : public iterator_facade_base<BinaryAnnotationIterator,
+ std::forward_iterator_tag,
+ DecodedAnnotation> {
BinaryAnnotationIterator() = default;
BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
@@ -173,10 +178,6 @@
return Data == Other.Data;
}
- bool operator!=(const BinaryAnnotationIterator &Other) const {
- return !(*this == Other);
- }
-
BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
Data = Other.Data;
return *this;
@@ -193,13 +194,7 @@
return *this;
}
- BinaryAnnotationIterator operator++(int) {
- BinaryAnnotationIterator Orig(*this);
- ++(*this);
- return Orig;
- }
-
- const AnnotationData &operator*() {
+ const DecodedAnnotation &operator*() {
ParseCurrentAnnotation();
return Current.getValue();
}
@@ -241,17 +236,17 @@
(ThirdByte << 8) | FourthByte;
return -1;
- };
+ }
static int32_t DecodeSignedOperand(uint32_t Operand) {
if (Operand & 1)
return -(Operand >> 1);
return Operand >> 1;
- };
+ }
static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
- };
+ }
bool ParseCurrentAnnotation() {
if (Current.hasValue())
@@ -259,7 +254,7 @@
Next = Data;
uint32_t Op = GetCompressedAnnotation(Next);
- AnnotationData Result;
+ DecodedAnnotation Result;
Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
switch (Result.OpCode) {
case BinaryAnnotationsOpCode::Invalid:
@@ -324,11 +319,12 @@
break;
}
}
+ Result.Bytes = Data.take_front(Data.size() - Next.size());
Current = Result;
return true;
}
- Optional<AnnotationData> Current;
+ Optional<DecodedAnnotation> Current;
ArrayRef<uint8_t> Data;
ArrayRef<uint8_t> Next;
};
@@ -973,7 +969,7 @@
public:
explicit UsingNamespaceSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
explicit UsingNamespaceSym(uint32_t RecordOffset)
- : SymbolRecord(SymbolRecordKind::RegRelativeSym),
+ : SymbolRecord(SymbolRecordKind::UsingNamespaceSym),
RecordOffset(RecordOffset) {}
StringRef Name;
@@ -982,6 +978,19 @@
};
// S_ANNOTATION
+class AnnotationSym : public SymbolRecord {
+public:
+ explicit AnnotationSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
+ explicit AnnotationSym(uint32_t RecordOffset)
+ : SymbolRecord(SymbolRecordKind::AnnotationSym),
+ RecordOffset(RecordOffset) {}
+
+ uint32_t CodeOffset = 0;
+ uint16_t Segment = 0;
+ std::vector<StringRef> Strings;
+
+ uint32_t RecordOffset;
+};
using CVSymbol = CVRecord<SymbolKind>;
using CVSymbolArray = VarStreamArray<CVSymbol>;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolSerializer.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
index 08271c1..b805b65 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/SymbolSerializer.h
@@ -51,8 +51,8 @@
template <typename SymType>
static CVSymbol writeOneSymbol(SymType &Sym, BumpPtrAllocator &Storage,
CodeViewContainer Container) {
- CVSymbol Result;
- Result.Type = static_cast<SymbolKind>(Sym.Kind);
+ RecordPrefix Prefix{uint16_t(Sym.Kind)};
+ CVSymbol Result(&Prefix, sizeof(Prefix));
SymbolSerializer Serializer(Storage, Container);
consumeError(Serializer.visitSymbolBegin(Result));
consumeError(Serializer.visitKnownRecord(Result, Sym));
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeDeserializer.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
index d2ee347..081de32 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeDeserializer.h
@@ -58,7 +58,7 @@
TypeRecordKind K =
static_cast<TypeRecordKind>(uint16_t(Prefix->RecordKind));
T Record(K);
- CVType CVT(static_cast<TypeLeafKind>(K), Data);
+ CVType CVT(Data);
if (auto EC = deserializeAs<T>(CVT, Record))
return std::move(EC);
return Record;
@@ -111,14 +111,14 @@
public:
explicit FieldListDeserializer(BinaryStreamReader &Reader) : Mapping(Reader) {
- CVType FieldList;
- FieldList.Type = TypeLeafKind::LF_FIELDLIST;
+ RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
+ CVType FieldList(&Pre, sizeof(Pre));
consumeError(Mapping.Mapping.visitTypeBegin(FieldList));
}
~FieldListDeserializer() override {
- CVType FieldList;
- FieldList.Type = TypeLeafKind::LF_FIELDLIST;
+ RecordPrefix Pre(static_cast<uint16_t>(TypeLeafKind::LF_FIELDLIST));
+ CVType FieldList(&Pre, sizeof(Pre));
consumeError(Mapping.Mapping.visitTypeEnd(FieldList));
}
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h
index c2fbff6..b0a16cc 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeHashing.h
@@ -84,7 +84,7 @@
}
std::array<uint8_t, 8> Hash;
- bool empty() const { return *(const uint64_t*)Hash.data() == 0; }
+ bool empty() const { return *(const uint64_t*)Hash.data() == 0; }
/// Given a sequence of bytes representing a record, compute a global hash for
/// this record. Due to the nature of global hashes incorporating the hashes
@@ -109,8 +109,8 @@
template <typename Range>
static std::vector<GloballyHashedType> hashTypes(Range &&Records) {
std::vector<GloballyHashedType> Hashes;
- bool UnresolvedRecords = false;
- for (const auto &R : Records) {
+ bool UnresolvedRecords = false;
+ for (const auto &R : Records) {
GloballyHashedType H = hashType(R, Hashes, Hashes);
if (H.empty())
UnresolvedRecords = true;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
index b885d54..4c309c1 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeRecordMapping.h
@@ -23,9 +23,11 @@
public:
explicit TypeRecordMapping(BinaryStreamReader &Reader) : IO(Reader) {}
explicit TypeRecordMapping(BinaryStreamWriter &Writer) : IO(Writer) {}
+ explicit TypeRecordMapping(CodeViewRecordStreamer &Streamer) : IO(Streamer) {}
using TypeVisitorCallbacks::visitTypeBegin;
Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
Error visitTypeEnd(CVType &Record) override;
Error visitMemberBegin(CVMemberRecord &Record) override;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
index fb0b579..169715b 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h
@@ -82,6 +82,11 @@
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/linux-x64/clang/include/llvm/DebugInfo/DIContext.h b/linux-x64/clang/include/llvm/DebugInfo/DIContext.h
index a41ab21..d2a5318 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DIContext.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DIContext.h
@@ -97,11 +97,10 @@
void addFrame(const DILineInfo &Frame) {
Frames.push_back(Frame);
}
-
+
void resize(unsigned i) {
Frames.resize(i);
}
-
};
/// Container for description of a global variable.
@@ -113,6 +112,16 @@
DIGlobal() : Name("<invalid>") {}
};
+struct DILocal {
+ std::string FunctionName;
+ std::string Name;
+ std::string DeclFile;
+ uint64_t DeclLine = 0;
+ Optional<int64_t> FrameOffset;
+ Optional<uint64_t> Size;
+ Optional<uint64_t> TagOffset;
+};
+
/// A DINameKind is passed to name search methods to specify a
/// preference regarding the type of name resolution the caller wants.
enum class DINameKind { None, ShortName, LinkageName };
@@ -157,7 +166,8 @@
/// dumped.
struct DIDumpOptions {
unsigned DumpType = DIDT_All;
- unsigned RecurseDepth = -1U;
+ unsigned ChildRecurseDepth = -1U;
+ unsigned ParentRecurseDepth = -1U;
uint16_t Version = 0; // DWARF version to assume when extracting.
uint8_t AddrSize = 4; // Address byte size to assume when extracting.
bool ShowAddresses = true;
@@ -171,15 +181,18 @@
/// Return default option set for printing a single DIE without children.
static DIDumpOptions getForSingleDIE() {
DIDumpOptions Opts;
- Opts.RecurseDepth = 0;
+ Opts.ChildRecurseDepth = 0;
+ Opts.ParentRecurseDepth = 0;
return Opts;
}
/// Return the options with RecurseDepth set to 0 unless explicitly required.
DIDumpOptions noImplicitRecursion() const {
DIDumpOptions Opts = *this;
- if (RecurseDepth == -1U && !ShowChildren)
- Opts.RecurseDepth = 0;
+ if (ChildRecurseDepth == -1U && !ShowChildren)
+ Opts.ChildRecurseDepth = 0;
+ if (ParentRecurseDepth == -1U && !ShowParents)
+ Opts.ParentRecurseDepth = 0;
return Opts;
}
};
@@ -203,12 +216,18 @@
return true;
}
- virtual DILineInfo getLineInfoForAddress(uint64_t Address,
+ virtual DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
- virtual DILineInfoTable getLineInfoForAddressRange(uint64_t Address,
- uint64_t Size, DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
- virtual DIInliningInfo getInliningInfoForAddress(uint64_t Address,
+ virtual DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+ virtual DIInliningInfo getInliningInfoForAddress(
+ object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier = DILineInfoSpecifier()) = 0;
+
+ virtual std::vector<DILocal>
+ getLocalsForAddress(object::SectionedAddress Address) = 0;
private:
const DIContextKind Kind;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
index 0f09a59..3033757 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h
@@ -71,7 +71,7 @@
: AccelSection(AccelSection), StringSection(StringSection) {}
virtual ~DWARFAcceleratorTable();
- virtual llvm::Error extract() = 0;
+ virtual Error extract() = 0;
virtual void dump(raw_ostream &OS) const = 0;
DWARFAcceleratorTable(const DWARFAcceleratorTable &) = delete;
@@ -174,7 +174,7 @@
DataExtractor StringSection)
: DWARFAcceleratorTable(AccelSection, StringSection) {}
- llvm::Error extract() override;
+ Error extract() override;
uint32_t getNumBuckets();
uint32_t getNumHashes();
uint32_t getSizeHdr();
@@ -222,7 +222,7 @@
/// referenced by the name table and interpreted with the help of the
/// abbreviation table.
class DWARFDebugNames : public DWARFAcceleratorTable {
- /// The fixed-size part of a Dwarf 5 Name Index header
+ /// The fixed-size part of a DWARF v5 Name Index header
struct HeaderPOD {
uint32_t UnitLength;
uint16_t Version;
@@ -241,7 +241,7 @@
class NameIterator;
class ValueIterator;
- /// Dwarf 5 Name Index header.
+ /// DWARF v5 Name Index header.
struct Header : public HeaderPOD {
SmallString<8> AugmentationString;
@@ -348,7 +348,7 @@
};
public:
- /// A single entry in the Name Table (Dwarf 5 sect. 6.1.1.4.6) of the Name
+ /// A single entry in the Name Table (DWARF v5 sect. 6.1.1.4.6) of the Name
/// Index.
class NameTableEntry {
DataExtractor StrData;
@@ -380,7 +380,7 @@
uint32_t getEntryOffset() const { return EntryOffset; }
};
- /// Represents a single accelerator table within the Dwarf 5 .debug_names
+ /// Represents a single accelerator table within the DWARF v5 .debug_names
/// section.
class NameIndex {
DenseSet<Abbrev, AbbrevMapInfo> Abbrevs;
@@ -459,7 +459,7 @@
NameIterator begin() const { return NameIterator(this, 1); }
NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
- llvm::Error extract();
+ Error extract();
uint32_t getUnitOffset() const { return Base; }
uint32_t getNextUnitOffset() const { return Base + 4 + Hdr.UnitLength; }
void dump(ScopedPrinter &W) const;
@@ -579,7 +579,7 @@
DataExtractor StringSection)
: DWARFAcceleratorTable(AccelSection, StringSection) {}
- llvm::Error extract() override;
+ Error extract() override;
void dump(raw_ostream &OS) const override;
/// Look up all entries in the accelerator table matching \c Key.
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
index 56d46c6..2d5f9f3 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAddressRange.h
@@ -42,12 +42,6 @@
return LowPC < RHS.HighPC && RHS.LowPC < HighPC;
}
- /// Returns true if [LowPC, HighPC) fully contains [RHS.LowPC, RHS.HighPC).
- bool contains(const DWARFAddressRange &RHS) const {
- assert(valid() && RHS.valid());
- return LowPC <= RHS.LowPC && RHS.HighPC <= HighPC;
- }
-
void dump(raw_ostream &OS, uint32_t AddressSize,
DIDumpOptions DumpOpts = {}) const;
};
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAttribute.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
index fc6f0a4..96e622c 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFAttribute.h
@@ -42,6 +42,10 @@
return isValid();
}
+ /// Identifies DWARF attributes that may contain a reference to a
+ /// DWARF expression.
+ static bool mayHaveLocationDescription(dwarf::Attribute Attr);
+
void clear() {
Offset = 0;
ByteSize = 0;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h
index e415927..23cf21c 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFContext.h
@@ -317,15 +317,23 @@
/// Get the compilation unit, the function DIE and lexical block DIE for the
/// given address where applicable.
+ /// TODO: change input parameter from "uint64_t Address"
+ /// into "SectionedAddress Address"
DIEsForAddress getDIEsForAddress(uint64_t Address);
- DILineInfo getLineInfoForAddress(uint64_t Address,
+ DILineInfo getLineInfoForAddress(
+ object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
- DILineInfoTable getLineInfoForAddressRange(uint64_t Address, uint64_t Size,
+ DILineInfoTable getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
- DIInliningInfo getInliningInfoForAddress(uint64_t Address,
+ DIInliningInfo getInliningInfoForAddress(
+ object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ std::vector<DILocal>
+ getLocalsForAddress(object::SectionedAddress Address) override;
+
bool isLittleEndian() const { return DObj->isLittleEndian(); }
static bool isSupportedVersion(unsigned version) {
return version == 2 || version == 3 || version == 4 || version == 5;
@@ -366,7 +374,11 @@
private:
/// Return the compile unit which contains instruction with provided
/// address.
+ /// TODO: change input parameter from "uint64_t Address"
+ /// into "SectionedAddress Address"
DWARFCompileUnit *getCompileUnitForAddress(uint64_t Address);
+ void addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, DWARFDie Die,
+ std::vector<DILocal> &Result);
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
index 6d3af24..03223fb 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugAranges.h
@@ -49,10 +49,6 @@
return -1ULL;
}
- bool containsAddress(uint64_t Address) const {
- return LowPC <= Address && Address < HighPC();
- }
-
bool operator<(const Range &other) const {
return LowPC < other.LowPC;
}
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
index 9e40c84..9a3ad2b 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
@@ -139,12 +139,16 @@
static void dumpTableHeader(raw_ostream &OS);
static bool orderByAddress(const Row &LHS, const Row &RHS) {
- return LHS.Address < RHS.Address;
+ return std::tie(LHS.Address.SectionIndex, LHS.Address.Address) <
+ std::tie(RHS.Address.SectionIndex, RHS.Address.Address);
}
/// The program-counter value corresponding to a machine instruction
- /// generated by the compiler.
- uint64_t Address;
+ /// generated by the compiler and section index pointing to the section
+ /// containg this PC. If relocation information is present then section
+ /// index is the index of the section which contains above address.
+ /// Otherwise this is object::SectionedAddress::Undef value.
+ object::SectionedAddress Address;
/// An unsigned integer indicating a source line number. Lines are numbered
/// beginning at 1. The compiler may emit the value 0 in cases where an
/// instruction cannot be attributed to any source line.
@@ -192,21 +196,29 @@
/// and is described by line table rows [FirstRowIndex, LastRowIndex).
uint64_t LowPC;
uint64_t HighPC;
+ /// If relocation information is present then this is the index of the
+ /// section which contains above addresses. Otherwise this is
+ /// object::SectionedAddress::Undef value.
+ uint64_t SectionIndex;
unsigned FirstRowIndex;
unsigned LastRowIndex;
bool Empty;
void reset();
- static bool orderByLowPC(const Sequence &LHS, const Sequence &RHS) {
- return LHS.LowPC < RHS.LowPC;
+ static bool orderByHighPC(const Sequence &LHS, const Sequence &RHS) {
+ return std::tie(LHS.SectionIndex, LHS.HighPC) <
+ std::tie(RHS.SectionIndex, RHS.HighPC);
}
bool isValid() const {
return !Empty && (LowPC < HighPC) && (FirstRowIndex < LastRowIndex);
}
- bool containsPC(uint64_t PC) const { return (LowPC <= PC && PC < HighPC); }
+ bool containsPC(object::SectionedAddress PC) const {
+ return SectionIndex == PC.SectionIndex &&
+ (LowPC <= PC.Address && PC.Address < HighPC);
+ }
};
struct LineTable {
@@ -223,14 +235,17 @@
/// Returns the index of the row with file/line info for a given address,
/// or UnknownRowIndex if there is no such row.
- uint32_t lookupAddress(uint64_t Address) const;
+ uint32_t lookupAddress(object::SectionedAddress Address) const;
- bool lookupAddressRange(uint64_t Address, uint64_t Size,
+ bool lookupAddressRange(object::SectionedAddress Address, uint64_t Size,
std::vector<uint32_t> &Result) const;
bool hasFileAtIndex(uint64_t FileIndex) const;
/// Extracts filename by its index in filename table in prologue.
+ /// In Dwarf 4, the files are 1-indexed and the current compilation file
+ /// name is not represented in the list. In DWARF v5, the files are
+ /// 0-indexed and the primary source file has the index 0.
/// Returns true on success.
bool getFileNameByIndex(uint64_t FileIndex, const char *CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
@@ -238,7 +253,8 @@
/// Fills the Result argument with the file and line information
/// corresponding to Address. Returns true on success.
- bool getFileLineInfoForAddress(uint64_t Address, const char *CompDir,
+ bool getFileLineInfoForAddress(object::SectionedAddress Address,
+ const char *CompDir,
DILineInfoSpecifier::FileLineInfoKind Kind,
DILineInfo &Result) const;
@@ -252,6 +268,11 @@
std::function<void(Error)> RecoverableErrorCallback,
raw_ostream *OS = nullptr);
+ /// Get DWARF-version aware access to the file name entry at the provided
+ /// index.
+ const llvm::DWARFDebugLine::FileNameEntry &
+ getFileNameEntry(uint64_t Index) const;
+
using RowVector = std::vector<Row>;
using RowIter = RowVector::const_iterator;
using SequenceVector = std::vector<Sequence>;
@@ -263,10 +284,15 @@
private:
uint32_t findRowInSeq(const DWARFDebugLine::Sequence &Seq,
- uint64_t Address) const;
+ object::SectionedAddress Address) const;
Optional<StringRef>
getSourceByIndex(uint64_t FileIndex,
DILineInfoSpecifier::FileLineInfoKind Kind) const;
+
+ uint32_t lookupAddressImpl(object::SectionedAddress Address) const;
+
+ bool lookupAddressRangeImpl(object::SectionedAddress Address, uint64_t Size,
+ std::vector<uint32_t> &Result) const;
};
const LineTable *getLineTable(uint32_t Offset) const;
@@ -333,13 +359,10 @@
ParsingState(struct LineTable *LT);
void resetRowAndSequence();
- void appendRowToMatrix(uint32_t Offset);
+ void appendRowToMatrix();
/// Line table we're currently parsing.
struct LineTable *LineTable;
- /// The row number that starts at zero for the prologue, and increases for
- /// each row added to the matrix.
- unsigned RowNumber = 0;
struct Row Row;
struct Sequence Sequence;
};
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
index dbed959..cced604 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugLoc.h
@@ -41,7 +41,7 @@
SmallVector<Entry, 2> Entries;
/// Dump this list on OS.
void dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize,
- const MCRegisterInfo *MRI, uint64_t BaseAddress,
+ const MCRegisterInfo *MRI, DWARFUnit *U, uint64_t BaseAddress,
unsigned Indent) const;
};
@@ -86,7 +86,7 @@
SmallVector<Entry, 2> Entries;
void dump(raw_ostream &OS, uint64_t BaseAddr, bool IsLittleEndian,
unsigned AddressSize, const MCRegisterInfo *RegInfo,
- unsigned Indent) const;
+ DWARFUnit *U, unsigned Indent) const;
};
private:
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
index c1c0f42..a66f602 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRangeList.h
@@ -76,7 +76,7 @@
/// list. Has to be passed base address of the compile unit referencing this
/// range list.
DWARFAddressRangesVector
- getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr) const;
+ getAbsoluteRanges(llvm::Optional<object::SectionedAddress> BaseAddr) const;
};
} // end namespace llvm
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
index c6661a8..167ddde 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFDebugRnglists.h
@@ -37,7 +37,7 @@
Error extract(DWARFDataExtractor Data, uint32_t End, uint32_t *OffsetPtr);
void dump(raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
uint64_t &CurrentBase, DIDumpOptions DumpOpts,
- llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress) const;
bool isSentinel() const { return EntryKind == dwarf::DW_RLE_end_of_list; }
};
@@ -47,7 +47,7 @@
public:
/// Build a DWARFAddressRangesVector from a rangelist.
DWARFAddressRangesVector
- getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr,
+ getAbsoluteRanges(llvm::Optional<object::SectionedAddress> BaseAddr,
DWARFUnit &U) const;
};
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFExpression.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFExpression.h
index 8049094..f066dd5 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFExpression.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFExpression.h
@@ -41,7 +41,8 @@
SizeAddr = 5,
SizeRefAddr = 6,
SizeBlock = 7, ///< Preceding operand contains block size
- SignBit = 0x8,
+ BaseTypeRef = 8,
+ SignBit = 0x80,
SignedSize1 = SignBit | Size1,
SignedSize2 = SignBit | Size2,
SignedSize4 = SignBit | Size4,
@@ -54,7 +55,8 @@
DwarfNA, ///< Serves as a marker for unused entries
Dwarf2 = 2,
Dwarf3,
- Dwarf4
+ Dwarf4,
+ Dwarf5
};
/// Description of the encoding of one expression Op.
@@ -77,17 +79,20 @@
bool Error;
uint32_t EndOffset;
uint64_t Operands[2];
+ uint32_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; }
bool extract(DataExtractor Data, uint16_t Version, uint8_t AddressSize,
uint32_t Offset);
bool isError() { return Error; }
- bool print(raw_ostream &OS, const DWARFExpression *U,
- const MCRegisterInfo *RegInfo, bool isEH);
+ bool print(raw_ostream &OS, const DWARFExpression *Expr,
+ const MCRegisterInfo *RegInfo, DWARFUnit *U, bool isEH);
+ bool verify(DWARFUnit *U);
};
/// An iterator to go through the expression operations.
@@ -124,15 +129,17 @@
DWARFExpression(DataExtractor Data, uint16_t Version, uint8_t AddressSize)
: Data(Data), Version(Version), AddressSize(AddressSize) {
- assert(AddressSize == 8 || AddressSize == 4);
+ assert(AddressSize == 8 || AddressSize == 4 || AddressSize == 2);
}
iterator begin() const { return iterator(this, 0); }
iterator end() const { return iterator(this, Data.getData().size()); }
- void print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
+ void print(raw_ostream &OS, const MCRegisterInfo *RegInfo, DWARFUnit *U,
bool IsEH = false) const;
+ bool verify(DWARFUnit *U);
+
private:
DataExtractor Data;
uint16_t Version;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
index e092d96..731e71e 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFFormValue.h
@@ -41,6 +41,9 @@
private:
struct ValueType {
ValueType() { uval = 0; }
+ ValueType(int64_t V) : sval(V) {}
+ ValueType(uint64_t V) : uval(V) {}
+ ValueType(const char *V) : cstr(V) {}
union {
uint64_t uval;
@@ -55,26 +58,28 @@
ValueType Value; /// Contains all data for the form.
const DWARFUnit *U = nullptr; /// Remember the DWARFUnit at extract time.
const DWARFContext *C = nullptr; /// Context for extract time.
+
+ DWARFFormValue(dwarf::Form F, ValueType V) : Form(F), Value(V) {}
+
public:
DWARFFormValue(dwarf::Form F = dwarf::Form(0)) : Form(F) {}
+ static DWARFFormValue createFromSValue(dwarf::Form F, int64_t V);
+ static DWARFFormValue createFromUValue(dwarf::Form F, uint64_t V);
+ static DWARFFormValue createFromPValue(dwarf::Form F, const char *V);
+ static DWARFFormValue createFromBlockValue(dwarf::Form F,
+ ArrayRef<uint8_t> D);
+ static DWARFFormValue createFromUnit(dwarf::Form F, const DWARFUnit *Unit,
+ uint32_t *OffsetPtr);
+
dwarf::Form getForm() const { return Form; }
uint64_t getRawUValue() const { return Value.uval; }
- void setForm(dwarf::Form F) { Form = F; }
- void setUValue(uint64_t V) { Value.uval = V; }
- void setSValue(int64_t V) { Value.sval = V; }
- void setPValue(const char *V) { Value.cstr = V; }
-
- void setBlockValue(const ArrayRef<uint8_t> &Data) {
- Value.data = Data.data();
- setUValue(Data.size());
- }
bool isFormClass(FormClass FC) const;
const DWARFUnit *getUnit() const { return U; }
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const;
void dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts,
- SectionedAddress SA) const;
+ object::SectionedAddress SA) const;
static void dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
DIDumpOptions DumpOpts, uint64_t SectionIndex);
@@ -99,11 +104,16 @@
/// getAsFoo functions below return the extracted value as Foo if only
/// DWARFFormValue has form class is suitable for representing Foo.
Optional<uint64_t> getAsReference() const;
+ struct UnitOffset {
+ DWARFUnit *Unit;
+ uint64_t Offset;
+ };
+ Optional<UnitOffset> getAsRelativeReference() const;
Optional<uint64_t> getAsUnsignedConstant() const;
Optional<int64_t> getAsSignedConstant() const;
Optional<const char *> getAsCString() const;
Optional<uint64_t> getAsAddress() const;
- Optional<SectionedAddress> getAsSectionedAddress() const;
+ Optional<object::SectionedAddress> getAsSectionedAddress() const;
Optional<uint64_t> getAsSectionOffset() const;
Optional<ArrayRef<uint8_t>> getAsBlock() const;
Optional<uint64_t> getAsCStringOffset() const;
@@ -154,6 +164,19 @@
return None;
}
+/// Take an optional DWARFFormValue and try to extract a string value from it.
+///
+/// \param V and optional DWARFFormValue to attempt to extract the value from.
+/// \returns an optional value that contains a value if the form value
+/// was valid and was a string.
+inline StringRef toStringRef(const Optional<DWARFFormValue> &V,
+ StringRef Default = {}) {
+ if (V)
+ if (auto S = V->getAsCString())
+ return *S;
+ return Default;
+}
+
/// Take an optional DWARFFormValue and extract a string value from it.
///
/// \param V and optional DWARFFormValue to attempt to extract the value from.
@@ -241,7 +264,7 @@
return None;
}
-inline Optional<SectionedAddress>
+inline Optional<object::SectionedAddress>
toSectionedAddress(const Optional<DWARFFormValue> &V) {
if (V)
return V->getAsSectionedAddress();
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFListTable.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFListTable.h
index 6c13db3..a1ea69b 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFListTable.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFListTable.h
@@ -157,7 +157,7 @@
uint8_t getAddrSize() const { return Header.getAddrSize(); }
void dump(raw_ostream &OS,
- llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress,
DIDumpOptions DumpOpts = {}) const;
@@ -234,7 +234,7 @@
template <typename DWARFListType>
void DWARFListTableBase<DWARFListType>::dump(
raw_ostream &OS,
- llvm::function_ref<Optional<SectionedAddress>(uint32_t)>
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress,
DIDumpOptions DumpOpts) const {
Header.dump(OS, DumpOpts);
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
index a8f5b28..cd022e7 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFRelocMap.h
@@ -10,6 +10,7 @@
#define LLVM_DEBUGINFO_DWARF_DWARFRELOCMAP_H
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Object/RelocationResolver.h"
#include <cstdint>
namespace llvm {
@@ -18,7 +19,9 @@
/// Section index is -1LL if relocation points to absolute symbol.
struct RelocAddrEntry {
uint64_t SectionIndex;
- uint64_t Value;
+ object::RelocationRef Reloc;
+ object::RelocationResolver Resolver;
+ uint64_t SymbolValue;
};
/// In place of applying the relocations to the data we've read from disk we use
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFSection.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFSection.h
index bb00046..054524d 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFSection.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFSection.h
@@ -22,11 +22,6 @@
bool IsNameUnique;
};
-struct SectionedAddress {
- uint64_t Address;
- uint64_t SectionIndex;
-};
-
} // end namespace llvm
#endif // LLVM_DEBUGINFO_DWARF_DWARFSECTION_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
index e82ce8e..f9f90db 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/DWARF/DWARFUnit.h
@@ -48,7 +48,7 @@
uint32_t Offset = 0;
// Version, address size, and DWARF format.
dwarf::FormParams FormParams;
- uint32_t Length = 0;
+ uint64_t Length = 0;
uint64_t AbbrOffset = 0;
// For DWO units only.
@@ -82,7 +82,7 @@
uint8_t getDwarfOffsetByteSize() const {
return FormParams.getDwarfOffsetByteSize();
}
- uint32_t getLength() const { return Length; }
+ uint64_t getLength() const { return Length; }
uint64_t getAbbrOffset() const { return AbbrOffset; }
Optional<uint64_t> getDWOId() const { return DWOId; }
void setDWOId(uint64_t Id) {
@@ -97,8 +97,11 @@
return UnitType == dwarf::DW_UT_type || UnitType == dwarf::DW_UT_split_type;
}
uint8_t getSize() const { return Size; }
- // FIXME: Support DWARF64.
- uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
+ uint32_t getNextUnitOffset() const {
+ return Offset + Length +
+ (FormParams.Format == llvm::dwarf::DwarfFormat::DWARF64 ? 4 : 0) +
+ FormParams.getDwarfOffsetByteSize();
+ }
};
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
@@ -172,6 +175,7 @@
StrOffsetsContributionDescriptor(uint64_t Base, uint64_t Size,
uint8_t Version, dwarf::DwarfFormat Format)
: Base(Base), Size(Size), FormParams({Version, 0, Format}) {}
+ StrOffsetsContributionDescriptor() = default;
uint8_t getVersion() const { return FormParams.Version; }
dwarf::DwarfFormat getFormat() const { return FormParams.Format; }
@@ -181,7 +185,7 @@
/// Determine whether a contribution to the string offsets table is
/// consistent with the relevant section size and that its length is
/// a multiple of the size of one of its entries.
- Optional<StrOffsetsContributionDescriptor>
+ Expected<StrOffsetsContributionDescriptor>
validateContributionSize(DWARFDataExtractor &DA);
};
@@ -217,7 +221,7 @@
Optional<DWARFDebugRnglistTable> RngListTable;
mutable const DWARFAbbreviationDeclarationSet *Abbrevs;
- llvm::Optional<SectionedAddress> BaseAddr;
+ llvm::Optional<object::SectionedAddress> BaseAddr;
/// The compile unit debug information entry items.
std::vector<DWARFDebugInfoEntry> DieArray;
@@ -246,14 +250,14 @@
/// Find the unit's contribution to the string offsets table and determine its
/// length and form. The given offset is expected to be derived from the unit
/// DIE's DW_AT_str_offsets_base attribute.
- Optional<StrOffsetsContributionDescriptor>
+ Expected<Optional<StrOffsetsContributionDescriptor>>
determineStringOffsetsTableContribution(DWARFDataExtractor &DA);
/// Find the unit's contribution to the string offsets table and determine its
/// length and form. The given offset is expected to be 0 in a dwo file or,
/// in a dwp file, the start of the unit's contribution to the string offsets
/// table section (as determined by the index table).
- Optional<StrOffsetsContributionDescriptor>
+ Expected<Optional<StrOffsetsContributionDescriptor>>
determineStringOffsetsTableContributionDWO(DWARFDataExtractor &DA);
public:
@@ -304,7 +308,8 @@
RangeSectionBase = Base;
}
- Optional<SectionedAddress> getAddrOffsetSectionItem(uint32_t Index) const;
+ Optional<object::SectionedAddress>
+ getAddrOffsetSectionItem(uint32_t Index) const;
Optional<uint64_t> getStringOffsetSectionItem(uint32_t Index) const;
DWARFDataExtractor getDebugInfoExtractor() const;
@@ -375,7 +380,7 @@
llvm_unreachable("Invalid UnitType.");
}
- llvm::Optional<SectionedAddress> getBaseAddress();
+ llvm::Optional<object::SectionedAddress> getBaseAddress();
DWARFDie getUnitDIE(bool ExtractUnitDIEOnly = true) {
extractDIEsIfNeeded(ExtractUnitDIEOnly);
@@ -384,6 +389,13 @@
return DWARFDie(this, &DieArray[0]);
}
+ DWARFDie getNonSkeletonUnitDIE(bool ExtractUnitDIEOnly = true) {
+ parseDWO();
+ if (DWO)
+ return DWO->getUnitDIE(ExtractUnitDIEOnly);
+ return getUnitDIE(ExtractUnitDIEOnly);
+ }
+
const char *getCompilationDir();
Optional<uint64_t> getDWOId() {
extractDIEsIfNeeded(/*CUDieOnly*/ true);
@@ -461,13 +473,12 @@
DWARFDie getDIEForOffset(uint32_t Offset) {
extractDIEsIfNeeded(false);
assert(!DieArray.empty());
- auto it = std::lower_bound(
- DieArray.begin(), DieArray.end(), Offset,
- [](const DWARFDebugInfoEntry &LHS, uint32_t Offset) {
- return LHS.getOffset() < Offset;
+ auto It =
+ llvm::partition_point(DieArray, [=](const DWARFDebugInfoEntry &DIE) {
+ return DIE.getOffset() < Offset;
});
- if (it != DieArray.end() && it->getOffset() == Offset)
- return DWARFDie(this, &*it);
+ if (It != DieArray.end() && It->getOffset() == Offset)
+ return DWARFDie(this, &*It);
return DWARFDie();
}
diff --git a/linux-x64/clang/include/llvm/DebugInfo/GSYM/FileEntry.h b/linux-x64/clang/include/llvm/DebugInfo/GSYM/FileEntry.h
new file mode 100644
index 0000000..228b4ef
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/GSYM/FileEntry.h
@@ -0,0 +1,68 @@
+//===- FileEntry.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_FILEENTRY_H
+#define LLVM_DEBUGINFO_GSYM_FILEENTRY_H
+
+#include "llvm/ADT/DenseMapInfo.h"
+#include "llvm/ADT/Hashing.h"
+#include <functional>
+#include <stdint.h>
+#include <utility>
+
+namespace llvm {
+namespace gsym {
+
+/// Files in GSYM are contained in FileEntry structs where we split the
+/// directory and basename into two different strings in the string
+/// table. This allows paths to shared commont directory and filename
+/// strings and saves space.
+struct FileEntry {
+
+ /// Offsets in the string table.
+ /// @{
+ uint32_t Dir = 0;
+ uint32_t Base = 0;
+ /// @}
+
+ FileEntry() = default;
+ FileEntry(uint32_t D, uint32_t B) : Dir(D), Base(B) {}
+
+ // Implement operator== so that FileEntry can be used as key in
+ // unordered containers.
+ bool operator==(const FileEntry &RHS) const {
+ return Base == RHS.Base && Dir == RHS.Dir;
+ };
+ bool operator!=(const FileEntry &RHS) const {
+ return Base != RHS.Base || Dir != RHS.Dir;
+ };
+};
+
+} // namespace gsym
+
+template <> struct DenseMapInfo<gsym::FileEntry> {
+ static inline gsym::FileEntry getEmptyKey() {
+ uint32_t key = DenseMapInfo<uint32_t>::getEmptyKey();
+ return gsym::FileEntry(key, key);
+ }
+ static inline gsym::FileEntry getTombstoneKey() {
+ uint32_t key = DenseMapInfo<uint32_t>::getTombstoneKey();
+ return gsym::FileEntry(key, key);
+ }
+ static unsigned getHashValue(const gsym::FileEntry &Val) {
+ return llvm::hash_combine(DenseMapInfo<uint32_t>::getHashValue(Val.Dir),
+ DenseMapInfo<uint32_t>::getHashValue(Val.Base));
+ }
+ static bool isEqual(const gsym::FileEntry &LHS, const gsym::FileEntry &RHS) {
+ return LHS == RHS;
+ }
+};
+
+} // namespace llvm
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_FILEENTRY_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/GSYM/FunctionInfo.h b/linux-x64/clang/include/llvm/DebugInfo/GSYM/FunctionInfo.h
new file mode 100644
index 0000000..eedb1e6
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/GSYM/FunctionInfo.h
@@ -0,0 +1,107 @@
+//===- FunctionInfo.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_FUNCTIONINFO_H
+#define LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
+
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/DebugInfo/GSYM/LineEntry.h"
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/DebugInfo/GSYM/StringTable.h"
+#include <tuple>
+#include <vector>
+
+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.
+struct FunctionInfo {
+ AddressRange Range;
+ uint32_t Name; ///< String table offset in the string table.
+ std::vector<gsym::LineEntry> Lines;
+ InlineInfo Inline;
+
+ FunctionInfo(uint64_t Addr = 0, uint64_t Size = 0, uint32_t N = 0)
+ : Range(Addr, Addr + Size), Name(N) {}
+
+ 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();
+ }
+
+ 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;
+ }
+
+ uint64_t startAddress() const { return Range.Start; }
+ uint64_t endAddress() const { return Range.End; }
+ uint64_t size() const { return Range.size(); }
+ void setStartAddress(uint64_t Addr) { Range.Start = Addr; }
+ void setEndAddress(uint64_t Addr) { Range.End = Addr; }
+ void setSize(uint64_t Size) { Range.End = Range.Start + Size; }
+
+ void clear() {
+ Range = {0, 0};
+ Name = 0;
+ Lines.clear();
+ Inline.clear();
+ }
+};
+
+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;
+}
+inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) {
+ return !(LHS == RHS);
+}
+/// This sorting will order things consistently by address range first, but then
+/// followed by inlining being valid and line tables. We might end up with a
+/// FunctionInfo from debug info that will have the same range as one from the
+/// symbol table, but we want to quickly be able to sort and use the best version
+/// when creating the final GSYM file.
+inline bool operator<(const FunctionInfo &LHS, const FunctionInfo &RHS) {
+ // First sort by address range
+ if (LHS.Range != RHS.Range)
+ 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();
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const FunctionInfo &R);
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_FUNCTIONINFO_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/GSYM/InlineInfo.h b/linux-x64/clang/include/llvm/DebugInfo/GSYM/InlineInfo.h
new file mode 100644
index 0000000..2224306
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/GSYM/InlineInfo.h
@@ -0,0 +1,78 @@
+//===- InlineInfo.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_INLINEINFO_H
+#define LLVM_DEBUGINFO_GSYM_INLINEINFO_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include <stdint.h>
+#include <vector>
+
+
+namespace llvm {
+class raw_ostream;
+
+namespace gsym {
+
+/// Inline information stores the name of the inline function along with
+/// an array of address ranges. It also stores the call file and call line
+/// that called this inline function. This allows us to unwind inline call
+/// stacks back to the inline or concrete function that called this
+/// function. Inlined functions contained in this function are stored in the
+/// "Children" variable. All address ranges must be sorted and all address
+/// ranges of all children must be contained in the ranges of this function.
+/// 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.
+struct InlineInfo {
+
+ uint32_t Name; ///< String table offset in the string table.
+ uint32_t CallFile; ///< 1 based file index in the file table.
+ uint32_t CallLine; ///< Source line number.
+ AddressRanges Ranges;
+ std::vector<InlineInfo> Children;
+ InlineInfo() : Name(0), CallFile(0), CallLine(0) {}
+ void clear() {
+ Name = 0;
+ CallFile = 0;
+ CallLine = 0;
+ Ranges.clear();
+ Children.clear();
+ }
+ bool isValid() const { return !Ranges.empty(); }
+
+ using InlineArray = std::vector<const InlineInfo *>;
+
+ /// Lookup an address in the InlineInfo object
+ ///
+ /// This function is used to symbolicate an inline call stack and can
+ /// turn one address in the program into one or more inline call stacks
+ /// and have the stack trace show the original call site from
+ /// non-inlined code.
+ ///
+ /// \param Addr the address to lookup
+ ///
+ /// \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;
+};
+
+inline bool operator==(const InlineInfo &LHS, const InlineInfo &RHS) {
+ return LHS.Name == RHS.Name && LHS.CallFile == RHS.CallFile &&
+ LHS.CallLine == RHS.CallLine && LHS.Ranges == RHS.Ranges &&
+ LHS.Children == RHS.Children;
+}
+
+raw_ostream &operator<<(raw_ostream &OS, const InlineInfo &FI);
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_INLINEINFO_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/GSYM/LineEntry.h b/linux-x64/clang/include/llvm/DebugInfo/GSYM/LineEntry.h
new file mode 100644
index 0000000..6b93809
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/GSYM/LineEntry.h
@@ -0,0 +1,48 @@
+//===- LineEntry.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_LINEENTRY_H
+#define LLVM_DEBUGINFO_GSYM_LINEENTRY_H
+
+#include "llvm/DebugInfo/GSYM/Range.h"
+
+namespace llvm {
+namespace gsym {
+
+/// Line entries are used to encode the line tables in FunctionInfo objects.
+/// They are stored as a sorted vector of these objects and store the
+/// address, file and line of the line table row for a given address. The
+/// size of a line table entry is calculated by looking at the next entry
+/// in the FunctionInfo's vector of entries.
+struct LineEntry {
+ uint64_t Addr; ///< Start address of this line entry.
+ uint32_t File; ///< 1 based index of file in FileTable
+ uint32_t Line; ///< Source line number.
+ LineEntry(uint64_t A = 0, uint32_t F = 0, uint32_t L = 0)
+ : Addr(A), File(F), Line(L) {}
+ bool isValid() { return File != 0; }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const LineEntry &LE) {
+ return OS << "addr=" << HEX64(LE.Addr) << ", file=" << format("%3u", LE.File)
+ << ", line=" << format("%3u", LE.Line);
+}
+
+inline bool operator==(const LineEntry &LHS, const LineEntry &RHS) {
+ return LHS.Addr == RHS.Addr && LHS.File == RHS.File && LHS.Line == RHS.Line;
+}
+inline bool operator!=(const LineEntry &LHS, const LineEntry &RHS) {
+ return !(LHS == RHS);
+}
+inline bool operator<(const LineEntry &LHS, const LineEntry &RHS) {
+ return LHS.Addr < RHS.Addr;
+}
+} // namespace gsym
+} // namespace llvm
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_LINEENTRY_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/GSYM/Range.h b/linux-x64/clang/include/llvm/DebugInfo/GSYM/Range.h
new file mode 100644
index 0000000..772ff24
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/GSYM/Range.h
@@ -0,0 +1,87 @@
+//===- AddressRange.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_RANGE_H
+#define LLVM_DEBUGINFO_GSYM_RANGE_H
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <stdint.h>
+#include <vector>
+
+#define HEX8(v) llvm::format_hex(v, 4)
+#define HEX16(v) llvm::format_hex(v, 6)
+#define HEX32(v) llvm::format_hex(v, 10)
+#define HEX64(v) llvm::format_hex(v, 18)
+
+namespace llvm {
+class raw_ostream;
+
+namespace gsym {
+
+/// A class that represents an address range. The range is specified using
+/// a start and an end address.
+struct AddressRange {
+ uint64_t Start;
+ uint64_t End;
+ AddressRange() : Start(0), End(0) {}
+ AddressRange(uint64_t S, uint64_t E) : Start(S), End(E) {}
+ uint64_t size() const { return End - Start; }
+ bool contains(uint64_t Addr) const { return Start <= Addr && Addr < End; }
+ bool intersects(const AddressRange &R) const {
+ return Start < R.End && R.Start < End;
+ }
+
+ bool operator==(const AddressRange &R) const {
+ return Start == R.Start && End == R.End;
+ }
+ bool operator!=(const AddressRange &R) const {
+ return !(*this == R);
+ }
+ bool operator<(const AddressRange &R) const {
+ return std::make_pair(Start, End) < std::make_pair(R.Start, R.End);
+ }
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const AddressRange &R);
+
+/// The AddressRanges class helps normalize address range collections.
+/// This class keeps a sorted vector of AddressRange objects and can perform
+/// insertions and searches efficiently. The address ranges are always sorted
+/// and never contain any invalid or empty address ranges. This allows us to
+/// emit address ranges into the GSYM file efficiently. Intersecting address
+/// ranges are combined during insertion so that we can emit the most compact
+/// representation for address ranges when writing to disk.
+class AddressRanges {
+protected:
+ using Collection = std::vector<AddressRange>;
+ Collection Ranges;
+public:
+ void clear() { Ranges.clear(); }
+ bool empty() const { return Ranges.empty(); }
+ bool contains(uint64_t Addr) const;
+ void insert(AddressRange Range);
+ size_t size() const { return Ranges.size(); }
+ bool operator==(const AddressRanges &RHS) const {
+ return Ranges == RHS.Ranges;
+ }
+ const AddressRange &operator[](size_t i) const {
+ assert(i < Ranges.size());
+ return Ranges[i];
+ }
+ Collection::const_iterator begin() const { return Ranges.begin(); }
+ Collection::const_iterator end() const { return Ranges.end(); }
+};
+
+raw_ostream &operator<<(raw_ostream &OS, const AddressRanges &AR);
+
+} // namespace gsym
+} // namespace llvm
+
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_RANGE_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/GSYM/StringTable.h b/linux-x64/clang/include/llvm/DebugInfo/GSYM/StringTable.h
new file mode 100644
index 0000000..0001b8b
--- /dev/null
+++ b/linux-x64/clang/include/llvm/DebugInfo/GSYM/StringTable.h
@@ -0,0 +1,54 @@
+//===- StringTable.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_STRINGTABLE_H
+#define LLVM_DEBUGINFO_GSYM_STRINGTABLE_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/GSYM/Range.h"
+#include <stdint.h>
+#include <string>
+
+
+namespace llvm {
+namespace gsym {
+
+/// String tables in GSYM files are required to start with an empty
+/// string at offset zero. Strings must be UTF8 NULL terminated strings.
+struct StringTable {
+ StringRef Data;
+ StringTable() : Data() {}
+ StringTable(StringRef D) : Data(D) {}
+ StringRef operator[](size_t Offset) const { return getString(Offset); }
+ StringRef getString(uint32_t Offset) const {
+ if (Offset < Data.size()) {
+ auto End = Data.find('\0', Offset);
+ return Data.substr(Offset, End - Offset);
+ }
+ return StringRef();
+ }
+ void clear() { Data = StringRef(); }
+};
+
+inline raw_ostream &operator<<(raw_ostream &OS, const StringTable &S) {
+ OS << "String table:\n";
+ uint32_t Offset = 0;
+ const size_t Size = S.Data.size();
+ while (Offset < Size) {
+ StringRef Str = S.getString(Offset);
+ OS << HEX32(Offset) << ": \"" << Str << "\"\n";
+ Offset += Str.size() + 1;
+ }
+ return OS;
+}
+
+} // namespace gsym
+} // namespace llvm
+#endif // #ifndef LLVM_DEBUGINFO_GSYM_STRINGTABLE_H
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/HashTable.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/HashTable.h
index e8f08c6..86c43a4 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/HashTable.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/HashTable.h
@@ -143,7 +143,7 @@
return EC;
if (Present.intersects(Deleted))
return make_error<RawError>(raw_error_code::corrupt_file,
- "Present bit vector interesects deleted!");
+ "Present bit vector intersects deleted!");
for (uint32_t P : Present) {
if (auto EC = Stream.readInteger(Buckets[P].first))
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
index 161aa32..cb1ffc7 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/ModuleDebugStream.h
@@ -68,6 +68,8 @@
findChecksumsSubsection() const;
private:
+ Error reloadSerialize(BinaryStreamReader &Reader);
+
DbiModuleDescriptor Mod;
uint32_t Signature;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h
index 84b0cb3..6119e6e 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/Native/RawTypes.h
@@ -176,7 +176,7 @@
};
static_assert(sizeof(DbiStreamHeader) == 64, "Invalid DbiStreamHeader size!");
-/// The header preceeding the File Info Substream of the DBI stream.
+/// The header preceding the File Info Substream of the DBI stream.
struct FileInfoSubstreamHeader {
/// Total # of modules, should match number of records in the ModuleInfo
/// substream.
@@ -207,7 +207,7 @@
static const uint16_t TypeServerIndexShift = 8;
};
-/// The header preceeding each entry in the Module Info substream of the DBI
+/// The header preceding each entry in the Module Info substream of the DBI
/// stream. Corresponds to the type MODI in the reference implementation.
struct ModuleInfoHeader {
/// Currently opened module. This field is a pointer in the reference
@@ -272,7 +272,7 @@
support::ulittle32_t NumSections;
};
-// The header preceeding the global TPI stream.
+// The header preceding the global TPI stream.
// This corresponds to `HDR` in PDB/dbi/tpi.h.
struct TpiStreamHeader {
struct EmbeddedBuf {
@@ -300,7 +300,7 @@
const uint32_t MinTpiHashBuckets = 0x1000;
const uint32_t MaxTpiHashBuckets = 0x40000;
-/// The header preceeding the global PDB Stream (Stream 1)
+/// The header preceding the global PDB Stream (Stream 1)
struct InfoStreamHeader {
support::ulittle32_t Version;
support::ulittle32_t Signature;
@@ -308,7 +308,7 @@
codeview::GUID Guid;
};
-/// The header preceeding the /names stream.
+/// The header preceding the /names stream.
struct PDBStringTableHeader {
support::ulittle32_t Signature; // PDBStringTableSignature
support::ulittle32_t HashVersion; // 1 or 2
@@ -341,7 +341,6 @@
short Padding; // Pad to 4 bytes.
char Reserved[8];
};
-
static_assert(sizeof(SrcHeaderBlockEntry) == 40, "Incorrect struct size!");
} // namespace pdb
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBContext.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBContext.h
index e404e07..7b6793f 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBContext.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBContext.h
@@ -43,15 +43,18 @@
void dump(raw_ostream &OS, DIDumpOptions DIDumpOpts) override;
DILineInfo getLineInfoForAddress(
- uint64_t Address,
+ object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
DILineInfoTable getLineInfoForAddressRange(
- uint64_t Address, uint64_t Size,
+ object::SectionedAddress Address, uint64_t Size,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
DIInliningInfo getInliningInfoForAddress(
- uint64_t Address,
+ object::SectionedAddress Address,
DILineInfoSpecifier Specifier = DILineInfoSpecifier()) override;
+ std::vector<DILocal>
+ getLocalsForAddress(object::SectionedAddress Address) override;
+
private:
std::string getFunctionName(uint64_t Address, DINameKind NameKind) const;
std::unique_ptr<IPDBSession> Session;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBExtras.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBExtras.h
index b9a8d8f..f5c3a5f 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBExtras.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBExtras.h
@@ -27,7 +27,8 @@
raw_ostream &operator<<(raw_ostream &OS, const PDB_CallingConv &Conv);
raw_ostream &operator<<(raw_ostream &OS, const PDB_BuiltinType &Type);
raw_ostream &operator<<(raw_ostream &OS, const PDB_DataKind &Data);
-raw_ostream &operator<<(raw_ostream &OS, const codeview::RegisterId &Reg);
+raw_ostream &operator<<(raw_ostream &OS,
+ const llvm::codeview::CPURegister &CpuReg);
raw_ostream &operator<<(raw_ostream &OS, const PDB_LocType &Loc);
raw_ostream &operator<<(raw_ostream &OS, const codeview::ThunkOrdinal &Thunk);
raw_ostream &operator<<(raw_ostream &OS, const PDB_Checksum &Checksum);
diff --git a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h
index 6d26b64..742cb85 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/PDB/PDBTypes.h
@@ -126,6 +126,7 @@
Am33 = 0x13,
Amd64 = 0x8664,
Arm = 0x1C0,
+ Arm64 = 0xaa64,
ArmNT = 0x1C4,
Ebc = 0xEBC,
x86 = 0x14C,
diff --git a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/DIPrinter.h b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/DIPrinter.h
index 71663f3..db7a61a 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/DIPrinter.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/DIPrinter.h
@@ -20,16 +20,22 @@
struct DILineInfo;
class DIInliningInfo;
struct DIGlobal;
+struct DILocal;
namespace symbolize {
class DIPrinter {
+public:
+ enum class OutputStyle { LLVM, GNU };
+
+private:
raw_ostream &OS;
bool PrintFunctionNames;
bool PrintPretty;
int PrintSourceContext;
bool Verbose;
bool Basenames;
+ OutputStyle Style;
void print(const DILineInfo &Info, bool Inlined);
void printContext(const std::string &FileName, int64_t Line);
@@ -37,14 +43,16 @@
public:
DIPrinter(raw_ostream &OS, bool PrintFunctionNames = true,
bool PrintPretty = false, int PrintSourceContext = 0,
- bool Verbose = false, bool Basenames = false)
+ bool Verbose = false, bool Basenames = false,
+ OutputStyle Style = OutputStyle::LLVM)
: OS(OS), PrintFunctionNames(PrintFunctionNames),
PrintPretty(PrintPretty), PrintSourceContext(PrintSourceContext),
- Verbose(Verbose), Basenames(Basenames) {}
+ Verbose(Verbose), Basenames(Basenames), Style(Style) {}
DIPrinter &operator<<(const DILineInfo &Info);
DIPrinter &operator<<(const DIInliningInfo &Info);
DIPrinter &operator<<(const DIGlobal &Global);
+ DIPrinter &operator<<(const DILocal &Local);
};
}
}
diff --git a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
index f0862d0..506ecc4 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/SymbolizableModule.h
@@ -24,13 +24,16 @@
public:
virtual ~SymbolizableModule() = default;
- virtual DILineInfo symbolizeCode(uint64_t ModuleOffset,
+ virtual DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
FunctionNameKind FNKind,
bool UseSymbolTable) const = 0;
- virtual DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset,
- FunctionNameKind FNKind,
- bool UseSymbolTable) const = 0;
- virtual DIGlobal symbolizeData(uint64_t ModuleOffset) const = 0;
+ virtual DIInliningInfo
+ symbolizeInlinedCode(object::SectionedAddress ModuleOffset,
+ FunctionNameKind FNKind, bool UseSymbolTable) const = 0;
+ virtual DIGlobal
+ symbolizeData(object::SectionedAddress ModuleOffset) const = 0;
+ virtual std::vector<DILocal>
+ symbolizeFrame(object::SectionedAddress ModuleOffset) const = 0;
// Return true if this is a 32-bit x86 PE COFF module.
virtual bool isWin32Module() const = 0;
diff --git a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h
index 4e57fe4..d3da28c 100644
--- a/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h
+++ b/linux-x64/clang/include/llvm/DebugInfo/Symbolize/Symbolize.h
@@ -35,38 +35,35 @@
class LLVMSymbolizer {
public:
struct Options {
- FunctionNameKind PrintFunctions;
- bool UseSymbolTable : 1;
- bool Demangle : 1;
- bool RelativeAddresses : 1;
+ FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName;
+ bool UseSymbolTable = true;
+ bool Demangle = true;
+ bool RelativeAddresses = false;
std::string DefaultArch;
std::vector<std::string> DsymHints;
std::string FallbackDebugPath;
-
- Options(FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
- bool UseSymbolTable = true, bool Demangle = true,
- bool RelativeAddresses = false, std::string DefaultArch = "",
- std::string FallbackDebugPath = "")
- : PrintFunctions(PrintFunctions), UseSymbolTable(UseSymbolTable),
- Demangle(Demangle), RelativeAddresses(RelativeAddresses),
- DefaultArch(std::move(DefaultArch)),
- FallbackDebugPath(std::move(FallbackDebugPath)) {}
+ std::string DWPName;
};
- LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
+ LLVMSymbolizer() = default;
+ LLVMSymbolizer(const Options &Opts) : Opts(Opts) {}
~LLVMSymbolizer() {
flush();
}
+ Expected<DILineInfo> symbolizeCode(const ObjectFile &Obj,
+ object::SectionedAddress ModuleOffset);
Expected<DILineInfo> symbolizeCode(const std::string &ModuleName,
- uint64_t ModuleOffset,
- StringRef DWPName = "");
- Expected<DIInliningInfo> symbolizeInlinedCode(const std::string &ModuleName,
- uint64_t ModuleOffset,
- StringRef DWPName = "");
+ object::SectionedAddress ModuleOffset);
+ Expected<DIInliningInfo>
+ symbolizeInlinedCode(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset);
Expected<DIGlobal> symbolizeData(const std::string &ModuleName,
- uint64_t ModuleOffset);
+ object::SectionedAddress ModuleOffset);
+ Expected<std::vector<DILocal>>
+ symbolizeFrame(const std::string &ModuleName,
+ object::SectionedAddress ModuleOffset);
void flush();
static std::string
@@ -76,14 +73,23 @@
private:
// Bundles together object file with code/data and object file with
// corresponding debug info. These objects can be the same.
- using ObjectPair = std::pair<ObjectFile *, ObjectFile *>;
+ using ObjectPair = std::pair<const ObjectFile *, const ObjectFile *>;
+
+ Expected<DILineInfo>
+ symbolizeCodeCommon(SymbolizableModule *Info,
+ object::SectionedAddress ModuleOffset);
/// Returns a SymbolizableModule or an error if loading debug info failed.
/// Only one attempt is made to load a module, and errors during loading are
/// only reported once. Subsequent calls to get module info for a module that
/// failed to load will return nullptr.
Expected<SymbolizableModule *>
- getOrCreateModuleInfo(const std::string &ModuleName, StringRef DWPName = "");
+ getOrCreateModuleInfo(const std::string &ModuleName);
+
+ Expected<SymbolizableModule *>
+ createModuleInfo(const ObjectFile *Obj,
+ std::unique_ptr<DIContext> Context,
+ StringRef ModuleName);
ObjectFile *lookUpDsymFile(const std::string &Path,
const MachOObjectFile *ExeObj,