aboutsummaryrefslogtreecommitdiff
path: root/lib/DebugInfo
diff options
context:
space:
mode:
Diffstat (limited to 'lib/DebugInfo')
-rw-r--r--lib/DebugInfo/CodeView/CVTypeVisitor.cpp15
-rw-r--r--lib/DebugInfo/CodeView/CodeViewRecordIO.cpp8
-rw-r--r--lib/DebugInfo/CodeView/EnumTables.cpp166
-rw-r--r--lib/DebugInfo/CodeView/SymbolDumper.cpp2
-rw-r--r--lib/DebugInfo/CodeView/SymbolRecordMapping.cpp2
-rw-r--r--lib/DebugInfo/CodeView/TypeRecordMapping.cpp238
-rw-r--r--lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp8
-rw-r--r--lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp105
-rw-r--r--lib/DebugInfo/DWARF/DWARFCompileUnit.cpp10
-rw-r--r--lib/DebugInfo/DWARF/DWARFContext.cpp335
-rw-r--r--lib/DebugInfo/DWARF/DWARFDataExtractor.cpp13
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp10
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugAddr.cpp28
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp4
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugAranges.cpp12
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugFrame.cpp74
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp8
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLine.cpp159
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugLoc.cpp257
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugMacro.cpp2
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp6
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp18
-rw-r--r--lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp30
-rw-r--r--lib/DebugInfo/DWARF/DWARFDie.cpp54
-rw-r--r--lib/DebugInfo/DWARF/DWARFExpression.cpp13
-rw-r--r--lib/DebugInfo/DWARF/DWARFFormValue.cpp9
-rw-r--r--lib/DebugInfo/DWARF/DWARFGdbIndex.cpp2
-rw-r--r--lib/DebugInfo/DWARF/DWARFListTable.cpp70
-rw-r--r--lib/DebugInfo/DWARF/DWARFTypeUnit.cpp14
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnit.cpp231
-rw-r--r--lib/DebugInfo/DWARF/DWARFUnitIndex.cpp12
-rw-r--r--lib/DebugInfo/DWARF/DWARFVerifier.cpp120
-rw-r--r--lib/DebugInfo/GSYM/FileWriter.cpp78
-rw-r--r--lib/DebugInfo/GSYM/FunctionInfo.cpp143
-rw-r--r--lib/DebugInfo/GSYM/GsymCreator.cpp275
-rw-r--r--lib/DebugInfo/GSYM/GsymReader.cpp265
-rw-r--r--lib/DebugInfo/GSYM/Header.cpp109
-rw-r--r--lib/DebugInfo/GSYM/InlineInfo.cpp100
-rw-r--r--lib/DebugInfo/GSYM/LineTable.cpp287
-rw-r--r--lib/DebugInfo/GSYM/Range.cpp47
-rw-r--r--lib/DebugInfo/MSF/MappedBlockStream.cpp6
-rw-r--r--lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp28
-rw-r--r--lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp2
-rw-r--r--lib/DebugInfo/PDB/DIA/DIASession.cpp46
-rw-r--r--lib/DebugInfo/PDB/GenericError.cpp4
-rw-r--r--lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp4
-rw-r--r--lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp2
-rw-r--r--lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp4
-rw-r--r--lib/DebugInfo/PDB/Native/Hash.cpp5
-rw-r--r--lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp29
-rw-r--r--lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp24
-rw-r--r--lib/DebugInfo/PDB/Native/NativeSession.cpp10
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp4
-rw-r--r--lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp6
-rw-r--r--lib/DebugInfo/PDB/Native/PDBFile.cpp18
-rw-r--r--lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp17
-rw-r--r--lib/DebugInfo/PDB/Native/TpiHashing.cpp6
-rw-r--r--lib/DebugInfo/PDB/Native/TpiStream.cpp2
-rw-r--r--lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp2
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolFunc.cpp2
-rw-r--r--lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp2
-rw-r--r--lib/DebugInfo/PDB/UDTLayout.cpp14
-rw-r--r--lib/DebugInfo/Symbolize/DIPrinter.cpp17
-rw-r--r--lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp32
-rw-r--r--lib/DebugInfo/Symbolize/SymbolizableObjectFile.h7
-rw-r--r--lib/DebugInfo/Symbolize/Symbolize.cpp52
66 files changed, 2724 insertions, 960 deletions
diff --git a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index ec4773d571c8..dd6f75f97a4a 100644
--- a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -209,14 +209,6 @@ struct VisitHelper {
}
}
- VisitHelper(TypeVisitorCallbackPipeline &Callbacks, VisitorDataSource Source)
- : Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
- if (Source == VDS_BytesPresent) {
- Pipeline = Callbacks;
- Pipeline.addCallbackToPipelineFront(Deserializer);
- }
- }
-
TypeDeserializer Deserializer;
TypeVisitorCallbackPipeline Pipeline;
CVTypeVisitor Visitor;
@@ -230,13 +222,6 @@ Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index,
return V.Visitor.visitTypeRecord(Record, Index);
}
-Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index,
- TypeVisitorCallbackPipeline &Callbacks,
- VisitorDataSource Source) {
- VisitHelper V(Callbacks, Source);
- return V.Visitor.visitTypeRecord(Record, Index);
-}
-
Error llvm::codeview::visitTypeRecord(CVType &Record,
TypeVisitorCallbacks &Callbacks,
VisitorDataSource Source) {
diff --git a/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
index 2f49474115a1..36a384baa13d 100644
--- a/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -20,7 +20,6 @@ Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
Limit.MaxLength = MaxLength;
Limit.BeginOffset = getCurrentOffset();
Limits.push_back(Limit);
- resetStreamedLen();
return Error::success();
}
@@ -50,6 +49,7 @@ Error CodeViewRecordIO::endRecord() {
Streamer->EmitBytes(BytesSR);
--PaddingBytes;
}
+ resetStreamedLen();
}
return Error::success();
}
@@ -126,7 +126,11 @@ Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes,
Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) {
if (isStreaming()) {
- emitComment(Comment);
+ std::string TypeNameStr = Streamer->getTypeName(TypeInd);
+ if (!TypeNameStr.empty())
+ emitComment(Comment + ": " + TypeNameStr);
+ else
+ emitComment(Comment);
Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
incrStreamedLen(sizeof(TypeInd.getIndex()));
} else if (isWriting()) {
diff --git a/lib/DebugInfo/CodeView/EnumTables.cpp b/lib/DebugInfo/CodeView/EnumTables.cpp
index 54e68ae4ea9f..82f6713a88f5 100644
--- a/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -300,6 +300,128 @@ static const EnumEntry<COFF::SectionCharacteristics>
CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ),
CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE)};
+static const EnumEntry<uint16_t> ClassOptionNames[] = {
+ CV_ENUM_CLASS_ENT(ClassOptions, Packed),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator),
+ CV_ENUM_CLASS_ENT(ClassOptions, Nested),
+ CV_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator),
+ CV_ENUM_CLASS_ENT(ClassOptions, ForwardReference),
+ CV_ENUM_CLASS_ENT(ClassOptions, Scoped),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasUniqueName),
+ CV_ENUM_CLASS_ENT(ClassOptions, Sealed),
+ CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
+};
+
+static const EnumEntry<uint8_t> MemberAccessNames[] = {
+ CV_ENUM_CLASS_ENT(MemberAccess, None),
+ CV_ENUM_CLASS_ENT(MemberAccess, Private),
+ CV_ENUM_CLASS_ENT(MemberAccess, Protected),
+ CV_ENUM_CLASS_ENT(MemberAccess, Public),
+};
+
+static const EnumEntry<uint16_t> MethodOptionNames[] = {
+ CV_ENUM_CLASS_ENT(MethodOptions, Pseudo),
+ CV_ENUM_CLASS_ENT(MethodOptions, NoInherit),
+ CV_ENUM_CLASS_ENT(MethodOptions, NoConstruct),
+ CV_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated),
+ CV_ENUM_CLASS_ENT(MethodOptions, Sealed),
+};
+
+static const EnumEntry<uint16_t> MemberKindNames[] = {
+ CV_ENUM_CLASS_ENT(MethodKind, Vanilla),
+ CV_ENUM_CLASS_ENT(MethodKind, Virtual),
+ CV_ENUM_CLASS_ENT(MethodKind, Static),
+ CV_ENUM_CLASS_ENT(MethodKind, Friend),
+ CV_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual),
+ CV_ENUM_CLASS_ENT(MethodKind, PureVirtual),
+ CV_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual),
+};
+
+static const EnumEntry<uint8_t> PtrKindNames[] = {
+ CV_ENUM_CLASS_ENT(PointerKind, Near16),
+ CV_ENUM_CLASS_ENT(PointerKind, Far16),
+ CV_ENUM_CLASS_ENT(PointerKind, Huge16),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegment),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnValue),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnAddress),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnType),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSelf),
+ CV_ENUM_CLASS_ENT(PointerKind, Near32),
+ CV_ENUM_CLASS_ENT(PointerKind, Far32),
+ CV_ENUM_CLASS_ENT(PointerKind, Near64),
+};
+
+static const EnumEntry<uint8_t> PtrModeNames[] = {
+ CV_ENUM_CLASS_ENT(PointerMode, Pointer),
+ CV_ENUM_CLASS_ENT(PointerMode, LValueReference),
+ CV_ENUM_CLASS_ENT(PointerMode, PointerToDataMember),
+ CV_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction),
+ CV_ENUM_CLASS_ENT(PointerMode, RValueReference),
+};
+
+static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, MultipleInheritanceData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, VirtualInheritanceData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceFunction),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ MultipleInheritanceFunction),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ VirtualInheritanceFunction),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction),
+};
+
+static const EnumEntry<uint16_t> TypeModifierNames[] = {
+ CV_ENUM_CLASS_ENT(ModifierOptions, Const),
+ CV_ENUM_CLASS_ENT(ModifierOptions, Volatile),
+ CV_ENUM_CLASS_ENT(ModifierOptions, Unaligned),
+};
+
+static const EnumEntry<uint8_t> CallingConventions[] = {
+ CV_ENUM_CLASS_ENT(CallingConvention, NearC),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarC),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearPascal),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarPascal),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearFast),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarFast),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearStdCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarStdCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearSysCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarSysCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, ThisCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, MipsCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, Generic),
+ CV_ENUM_CLASS_ENT(CallingConvention, AlphaCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, PpcCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, SHCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, ArmCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, AM33Call),
+ CV_ENUM_CLASS_ENT(CallingConvention, TriCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, SH5Call),
+ CV_ENUM_CLASS_ENT(CallingConvention, M32RCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, ClrCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, Inline),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearVector),
+};
+
+static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
+ CV_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt),
+ CV_ENUM_CLASS_ENT(FunctionOptions, Constructor),
+ CV_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases),
+};
+
+static const EnumEntry<uint16_t> LabelTypeEnum[] = {
+ CV_ENUM_CLASS_ENT(LabelType, Near),
+ CV_ENUM_CLASS_ENT(LabelType, Far),
+};
+
namespace llvm {
namespace codeview {
@@ -379,5 +501,49 @@ getImageSectionCharacteristicNames() {
return makeArrayRef(ImageSectionCharacteristicNames);
}
+ArrayRef<EnumEntry<uint16_t>> getClassOptionNames() {
+ return makeArrayRef(ClassOptionNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames() {
+ return makeArrayRef(MemberAccessNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames() {
+ return makeArrayRef(MethodOptionNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getMemberKindNames() {
+ return makeArrayRef(MemberKindNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getPtrKindNames() {
+ return makeArrayRef(PtrKindNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getPtrModeNames() {
+ return makeArrayRef(PtrModeNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames() {
+ return makeArrayRef(PtrMemberRepNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames() {
+ return makeArrayRef(TypeModifierNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getCallingConventions() {
+ return makeArrayRef(CallingConventions);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum() {
+ return makeArrayRef(FunctionOptionEnum);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum() {
+ return makeArrayRef(LabelTypeEnum);
+}
+
} // end namespace codeview
} // end namespace llvm
diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp
index 27cb7e35234b..45b63983beb4 100644
--- a/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -315,7 +315,7 @@ Error CVSymbolDumperImpl::visitKnownRecord(
Error CVSymbolDumperImpl::visitKnownRecord(
CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
- W.printNumber("Offset", DefRangeFramePointerRel.Offset);
+ W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
DefRangeFramePointerRel.getRelocationOffset());
printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
diff --git a/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index 70889839ef48..3b627930e271 100644
--- a/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
@@ -229,7 +229,7 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
Error SymbolRecordMapping::visitKnownRecord(
CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
- error(IO.mapInteger(DefRangeFramePointerRel.Offset));
+ error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset));
error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range));
error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap()));
diff --git a/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index 47928c2eef64..1aded589e565 100644
--- a/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -7,24 +7,125 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
using namespace llvm;
using namespace llvm::codeview;
+namespace {
+
#define error(X) \
if (auto EC = X) \
return EC;
-namespace {
+static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
+#define CV_TYPE(enum, val) {#enum, enum},
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+};
+
+static StringRef getLeafTypeName(TypeLeafKind LT) {
+ switch (LT) {
+#define TYPE_RECORD(ename, value, name) \
+ case ename: \
+ return #name;
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ default:
+ break;
+ }
+ return "UnknownLeaf";
+}
+
+template <typename T>
+static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
+ return lhs.Name < rhs.Name;
+}
+
+template <typename T, typename TFlag>
+static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
+ ArrayRef<EnumEntry<TFlag>> Flags) {
+ if (!IO.isStreaming())
+ return std::string("");
+ typedef EnumEntry<TFlag> FlagEntry;
+ typedef SmallVector<FlagEntry, 10> FlagVector;
+ FlagVector SetFlags;
+ for (const auto &Flag : Flags) {
+ if (Flag.Value == 0)
+ continue;
+ if ((Value & Flag.Value) == Flag.Value) {
+ SetFlags.push_back(Flag);
+ }
+ }
+
+ llvm::sort(SetFlags, &compEnumNames<TFlag>);
+
+ std::string FlagLabel;
+ bool FirstOcc = true;
+ for (const auto &Flag : SetFlags) {
+ if (FirstOcc)
+ FirstOcc = false;
+ else
+ FlagLabel += (" | ");
+
+ FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
+ }
+
+ if (!FlagLabel.empty()) {
+ std::string LabelWithBraces(" ( ");
+ LabelWithBraces += FlagLabel + " )";
+ return LabelWithBraces;
+ } else
+ return FlagLabel;
+}
+
+template <typename T, typename TEnum>
+static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
+ ArrayRef<EnumEntry<TEnum>> EnumValues) {
+ if (!IO.isStreaming())
+ return "";
+ StringRef Name;
+ for (const auto &EnumItem : EnumValues) {
+ if (EnumItem.Value == Value) {
+ Name = EnumItem.Name;
+ break;
+ }
+ }
+
+ return Name;
+}
+
+static std::string getMemberAttributes(CodeViewRecordIO &IO,
+ MemberAccess Access, MethodKind Kind,
+ MethodOptions Options) {
+ if (!IO.isStreaming())
+ return "";
+ std::string AccessSpecifier =
+ getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames()));
+ std::string MemberAttrs(AccessSpecifier);
+ if (Kind != MethodKind::Vanilla) {
+ std::string MethodKind =
+ getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames()));
+ MemberAttrs += ", " + MethodKind;
+ }
+ if (Options != MethodOptions::None) {
+ std::string MethodOptions = getFlagNames(
+ IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
+ MemberAttrs += ", " + MethodOptions;
+ }
+ return MemberAttrs;
+}
+
struct MapOneMethodRecord {
explicit MapOneMethodRecord(bool IsFromOverloadList)
: IsFromOverloadList(IsFromOverloadList) {}
Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
- error(IO.mapInteger(Method.Attrs.Attrs, "AccessSpecifier"));
+ std::string Attrs = getMemberAttributes(
+ IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
+ error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
if (IsFromOverloadList) {
uint16_t Padding = 0;
- error(IO.mapInteger(Padding, "Padding"));
+ error(IO.mapInteger(Padding));
}
error(IO.mapInteger(Method.Type, "Type"));
if (Method.isIntroducingVirtual()) {
@@ -41,7 +142,7 @@ struct MapOneMethodRecord {
private:
bool IsFromOverloadList;
};
-}
+} // namespace
static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name,
StringRef &UniqueName, bool HasUniqueName) {
@@ -96,10 +197,22 @@ Error TypeRecordMapping::visitTypeBegin(CVType &CVR) {
MaxLen = MaxRecordLength - sizeof(RecordPrefix);
error(IO.beginRecord(MaxLen));
TypeKind = CVR.kind();
+
+ if (IO.isStreaming()) {
+ auto RecordKind = CVR.kind();
+ uint16_t RecordLen = CVR.length() - 2;
+ std::string RecordKindName =
+ getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames));
+ error(IO.mapInteger(RecordLen, "Record length"));
+ error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
+ }
return Error::success();
}
Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) {
+ if (IO.isStreaming())
+ IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
+ utohexstr(Index.getIndex()) + ")");
return visitTypeBegin(CVR);
}
@@ -121,11 +234,21 @@ Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
// followed by the subrecord, followed by a continuation, and that entire
// sequence spaws `MaxRecordLength` bytes. So the record's length is
// calculated as follows.
+
constexpr uint32_t ContinuationLength = 8;
error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix) -
ContinuationLength));
MemberKind = Record.Kind;
+ if (IO.isStreaming()) {
+ std::string MemberKindName = getLeafTypeName(Record.Kind);
+ MemberKindName +=
+ " ( " +
+ (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
+ .str() +
+ " )";
+ error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
+ }
return Error::success();
}
@@ -144,16 +267,24 @@ Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) {
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) {
+ std::string ModifierNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
+ makeArrayRef(getTypeModifierNames()));
error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
- error(IO.mapEnum(Record.Modifiers, "Modifiers"));
+ error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
return Error::success();
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
ProcedureRecord &Record) {
+ std::string CallingConvName = getEnumName(
+ IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()));
+ std::string FuncOptionNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getFunctionOptionEnum()));
error(IO.mapInteger(Record.ReturnType, "ReturnType"));
- error(IO.mapEnum(Record.CallConv, "CallingConvention"));
- error(IO.mapEnum(Record.Options, "FunctionOptions"));
+ error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
+ error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
@@ -162,11 +293,16 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
MemberFunctionRecord &Record) {
+ std::string CallingConvName = getEnumName(
+ IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions()));
+ std::string FuncOptionNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getFunctionOptionEnum()));
error(IO.mapInteger(Record.ReturnType, "ReturnType"));
error(IO.mapInteger(Record.ClassType, "ClassType"));
error(IO.mapInteger(Record.ThisType, "ThisType"));
- error(IO.mapEnum(Record.CallConv, "CallingConvention"));
- error(IO.mapEnum(Record.Options, "FunctionOptions"));
+ error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
+ error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));
@@ -197,8 +333,40 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) {
+
+ SmallString<128> Attr("Attrs: ");
+
+ if (IO.isStreaming()) {
+ std::string PtrType = getEnumName(IO, unsigned(Record.getPointerKind()),
+ makeArrayRef(getPtrKindNames()));
+ Attr += "[ Type: " + PtrType;
+
+ std::string PtrMode = getEnumName(IO, unsigned(Record.getMode()),
+ makeArrayRef(getPtrModeNames()));
+ Attr += ", Mode: " + PtrMode;
+
+ auto PtrSizeOf = Record.getSize();
+ Attr += ", SizeOf: " + itostr(PtrSizeOf);
+
+ if (Record.isFlat())
+ Attr += ", isFlat";
+ if (Record.isConst())
+ Attr += ", isConst";
+ if (Record.isVolatile())
+ Attr += ", isVolatile";
+ if (Record.isUnaligned())
+ Attr += ", isUnaligned";
+ if (Record.isRestrict())
+ Attr += ", isRestricted";
+ if (Record.isLValueReferenceThisPtr())
+ Attr += ", isThisPtr&";
+ if (Record.isRValueReferenceThisPtr())
+ Attr += ", isThisPtr&&";
+ Attr += " ]";
+ }
+
error(IO.mapInteger(Record.ReferentType, "PointeeType"));
- error(IO.mapInteger(Record.Attrs, "Attributes"));
+ error(IO.mapInteger(Record.Attrs, Attr));
if (Record.isPointerToMember()) {
if (IO.isReading())
@@ -206,7 +374,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) {
MemberPointerInfo &M = *Record.MemberInfo;
error(IO.mapInteger(M.ContainingType, "ClassType"));
- error(IO.mapEnum(M.Representation, "Representation"));
+ std::string PtrMemberGetRepresentation = getEnumName(
+ IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames()));
+ error(IO.mapEnum(M.Representation,
+ "Representation: " + PtrMemberGetRepresentation));
}
return Error::success();
@@ -226,8 +397,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) {
(CVR.kind() == TypeLeafKind::LF_CLASS) ||
(CVR.kind() == TypeLeafKind::LF_INTERFACE));
+ std::string PropertiesNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getClassOptionNames()));
error(IO.mapInteger(Record.MemberCount, "MemberCount"));
- error(IO.mapEnum(Record.Options, "Properties"));
+ error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
error(IO.mapInteger(Record.FieldList, "FieldList"));
error(IO.mapInteger(Record.DerivationList, "DerivedFrom"));
error(IO.mapInteger(Record.VTableShape, "VShape"));
@@ -239,8 +413,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) {
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
+ std::string PropertiesNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getClassOptionNames()));
error(IO.mapInteger(Record.MemberCount, "MemberCount"));
- error(IO.mapEnum(Record.Options, "Properties"));
+ error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
error(IO.mapInteger(Record.FieldList, "FieldList"));
error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
@@ -250,8 +427,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) {
+ std::string PropertiesNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getClassOptionNames()));
error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
- error(IO.mapEnum(Record.Options, "Properties"));
+ error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
error(IO.mapInteger(Record.FieldList, "FieldListType"));
error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
@@ -383,7 +563,11 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
FieldListRecord &Record) {
- error(IO.mapByteVectorTail(Record.Data));
+ if (IO.isStreaming()) {
+ if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
+ return EC;
+ } else
+ error(IO.mapByteVectorTail(Record.Data));
return Error::success();
}
@@ -397,13 +581,17 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
}
Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) {
- error(IO.mapEnum(Record.Mode, "Mode"));
+ std::string ModeName =
+ getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum()));
+ error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
return Error::success();
}
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
BaseClassRecord &Record) {
- error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
error(IO.mapInteger(Record.Type, "BaseType"));
error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));
@@ -412,7 +600,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
EnumeratorRecord &Record) {
- error(IO.mapInteger(Record.Attrs.Attrs));
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
// FIXME: Handle full APInt such as __int128.
error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
@@ -423,7 +613,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
DataMemberRecord &Record) {
- error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
error(IO.mapInteger(Record.Type, "Type"));
error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
error(IO.mapStringZ(Record.Name, "Name"));
@@ -460,7 +652,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
StaticDataMemberRecord &Record) {
- error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
error(IO.mapInteger(Record.Type, "Type"));
error(IO.mapStringZ(Record.Name, "Name"));
@@ -470,7 +664,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
VirtualBaseClassRecord &Record) {
- error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier"));
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
error(IO.mapInteger(Record.BaseType, "BaseType"));
error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
diff --git a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
index f4dd79937608..abbea3a868c8 100644
--- a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -38,9 +38,9 @@ DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
bool
DWARFAbbreviationDeclaration::extract(DataExtractor Data,
- uint32_t* OffsetPtr) {
+ uint64_t* OffsetPtr) {
clear();
- const uint32_t Offset = *OffsetPtr;
+ const uint64_t Offset = *OffsetPtr;
Code = Data.getULEB128(OffsetPtr);
if (Code == 0) {
return false;
@@ -148,7 +148,7 @@ DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
}
Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
- const uint32_t DIEOffset, const dwarf::Attribute Attr,
+ const uint64_t DIEOffset, const dwarf::Attribute Attr,
const DWARFUnit &U) const {
Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
if (!MatchAttrIndex)
@@ -158,7 +158,7 @@ Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
// Add the byte size of ULEB that for the abbrev Code so we can start
// skipping the attribute data.
- uint32_t Offset = DIEOffset + CodeByteSize;
+ uint64_t Offset = DIEOffset + CodeByteSize;
uint32_t AttrIndex = 0;
for (const auto &Spec : AttributeSpecs) {
if (*MatchAttrIndex == AttrIndex) {
diff --git a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 0721efb40f6a..875f5e9989a0 100644
--- a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -42,7 +42,7 @@ static Atom formatAtom(unsigned Atom) { return {Atom}; }
DWARFAcceleratorTable::~DWARFAcceleratorTable() = default;
Error AppleAcceleratorTable::extract() {
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
// Check that we can at least read the header.
if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength) + 4))
@@ -111,15 +111,15 @@ bool AppleAcceleratorTable::validateForms() {
return true;
}
-std::pair<uint32_t, dwarf::Tag>
-AppleAcceleratorTable::readAtoms(uint32_t &HashDataOffset) {
- uint32_t DieOffset = dwarf::DW_INVALID_OFFSET;
+std::pair<uint64_t, dwarf::Tag>
+AppleAcceleratorTable::readAtoms(uint64_t *HashDataOffset) {
+ uint64_t DieOffset = dwarf::DW_INVALID_OFFSET;
dwarf::Tag DieTag = dwarf::DW_TAG_null;
dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
for (auto Atom : getAtomsDesc()) {
DWARFFormValue FormValue(Atom.second);
- FormValue.extractValue(AccelSection, &HashDataOffset, FormParams);
+ FormValue.extractValue(AccelSection, HashDataOffset, FormParams);
switch (Atom.first) {
case dwarf::DW_ATOM_die_offset:
DieOffset = *FormValue.getAsUnsignedConstant();
@@ -163,19 +163,19 @@ Optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset(
bool AppleAcceleratorTable::dumpName(ScopedPrinter &W,
SmallVectorImpl<DWARFFormValue> &AtomForms,
- uint32_t *DataOffset) const {
+ uint64_t *DataOffset) const {
dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
- uint32_t NameOffset = *DataOffset;
+ uint64_t NameOffset = *DataOffset;
if (!AccelSection.isValidOffsetForDataOfSize(*DataOffset, 4)) {
W.printString("Incorrectly terminated list.");
return false;
}
- unsigned StringOffset = AccelSection.getRelocatedValue(4, DataOffset);
+ uint64_t StringOffset = AccelSection.getRelocatedValue(4, DataOffset);
if (!StringOffset)
return false; // End of list
DictScope NameScope(W, ("Name@0x" + Twine::utohexstr(NameOffset)).str());
- W.startLine() << format("String: 0x%08x", StringOffset);
+ W.startLine() << format("String: 0x%08" PRIx64, StringOffset);
W.getOStream() << " \"" << StringSection.getCStr(&StringOffset) << "\"\n";
unsigned NumData = AccelSection.getU32(DataOffset);
@@ -223,9 +223,9 @@ LLVM_DUMP_METHOD void AppleAcceleratorTable::dump(raw_ostream &OS) const {
}
// Now go through the actual tables and dump them.
- uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
- unsigned HashesBase = Offset + Hdr.BucketCount * 4;
- unsigned OffsetsBase = HashesBase + Hdr.HashCount * 4;
+ uint64_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
+ uint64_t HashesBase = Offset + Hdr.BucketCount * 4;
+ uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
for (unsigned Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket) {
unsigned Index = AccelSection.getU32(&Offset);
@@ -237,14 +237,14 @@ LLVM_DUMP_METHOD void AppleAcceleratorTable::dump(raw_ostream &OS) const {
}
for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
- unsigned HashOffset = HashesBase + HashIdx*4;
- unsigned OffsetsOffset = OffsetsBase + HashIdx*4;
+ uint64_t HashOffset = HashesBase + HashIdx*4;
+ uint64_t OffsetsOffset = OffsetsBase + HashIdx*4;
uint32_t Hash = AccelSection.getU32(&HashOffset);
if (Hash % Hdr.BucketCount != Bucket)
break;
- unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
+ uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
ListScope HashScope(W, ("Hash 0x" + Twine::utohexstr(Hash)).str());
if (!AccelSection.isValidOffset(DataOffset)) {
W.printString("Invalid section offset");
@@ -265,7 +265,7 @@ AppleAcceleratorTable::Entry::Entry(
}
void AppleAcceleratorTable::Entry::extract(
- const AppleAcceleratorTable &AccelTable, uint32_t *Offset) {
+ const AppleAcceleratorTable &AccelTable, uint64_t *Offset) {
dwarf::FormParams FormParams = {AccelTable.Hdr.Version, 0,
dwarf::DwarfFormat::DWARF32};
@@ -302,7 +302,7 @@ Optional<dwarf::Tag> AppleAcceleratorTable::Entry::getTag() const {
}
AppleAcceleratorTable::ValueIterator::ValueIterator(
- const AppleAcceleratorTable &AccelTable, unsigned Offset)
+ const AppleAcceleratorTable &AccelTable, uint64_t Offset)
: AccelTable(&AccelTable), Current(AccelTable.HdrData), DataOffset(Offset) {
if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
return;
@@ -333,25 +333,25 @@ AppleAcceleratorTable::equal_range(StringRef Key) const {
// Find the bucket.
unsigned HashValue = djbHash(Key);
unsigned Bucket = HashValue % Hdr.BucketCount;
- unsigned BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
- unsigned HashesBase = BucketBase + Hdr.BucketCount * 4;
- unsigned OffsetsBase = HashesBase + Hdr.HashCount * 4;
+ uint64_t BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
+ uint64_t HashesBase = BucketBase + Hdr.BucketCount * 4;
+ uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
- unsigned BucketOffset = BucketBase + Bucket * 4;
+ uint64_t BucketOffset = BucketBase + Bucket * 4;
unsigned Index = AccelSection.getU32(&BucketOffset);
// Search through all hashes in the bucket.
for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
- unsigned HashOffset = HashesBase + HashIdx * 4;
- unsigned OffsetsOffset = OffsetsBase + HashIdx * 4;
+ uint64_t HashOffset = HashesBase + HashIdx * 4;
+ uint64_t OffsetsOffset = OffsetsBase + HashIdx * 4;
uint32_t Hash = AccelSection.getU32(&HashOffset);
if (Hash % Hdr.BucketCount != Bucket)
// We are already in the next bucket.
break;
- unsigned DataOffset = AccelSection.getU32(&OffsetsOffset);
- unsigned StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
+ uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
+ uint64_t StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
if (!StringOffset)
break;
@@ -377,7 +377,7 @@ void DWARFDebugNames::Header::dump(ScopedPrinter &W) const {
}
Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
- uint32_t *Offset) {
+ uint64_t *Offset) {
// Check that we can read the fixed-size part.
if (!AS.isValidOffset(*Offset + sizeof(HeaderPOD) - 1))
return createStringError(errc::illegal_byte_sequence,
@@ -437,7 +437,7 @@ DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getTombstoneKey() {
}
Expected<DWARFDebugNames::AttributeEncoding>
-DWARFDebugNames::NameIndex::extractAttributeEncoding(uint32_t *Offset) {
+DWARFDebugNames::NameIndex::extractAttributeEncoding(uint64_t *Offset) {
if (*Offset >= EntriesBase) {
return createStringError(errc::illegal_byte_sequence,
"Incorrectly terminated abbreviation table.");
@@ -449,7 +449,7 @@ DWARFDebugNames::NameIndex::extractAttributeEncoding(uint32_t *Offset) {
}
Expected<std::vector<DWARFDebugNames::AttributeEncoding>>
-DWARFDebugNames::NameIndex::extractAttributeEncodings(uint32_t *Offset) {
+DWARFDebugNames::NameIndex::extractAttributeEncodings(uint64_t *Offset) {
std::vector<AttributeEncoding> Result;
for (;;) {
auto AttrEncOr = extractAttributeEncoding(Offset);
@@ -463,7 +463,7 @@ DWARFDebugNames::NameIndex::extractAttributeEncodings(uint32_t *Offset) {
}
Expected<DWARFDebugNames::Abbrev>
-DWARFDebugNames::NameIndex::extractAbbrev(uint32_t *Offset) {
+DWARFDebugNames::NameIndex::extractAbbrev(uint64_t *Offset) {
if (*Offset >= EntriesBase) {
return createStringError(errc::illegal_byte_sequence,
"Incorrectly terminated abbreviation table.");
@@ -482,7 +482,7 @@ DWARFDebugNames::NameIndex::extractAbbrev(uint32_t *Offset) {
Error DWARFDebugNames::NameIndex::extract() {
const DWARFDataExtractor &AS = Section.AccelSection;
- uint32_t Offset = Base;
+ uint64_t Offset = Base;
if (Error E = Hdr.extract(AS, &Offset))
return E;
@@ -577,27 +577,27 @@ std::error_code DWARFDebugNames::SentinelError::convertToErrorCode() const {
return inconvertibleErrorCode();
}
-uint32_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const {
+uint64_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const {
assert(CU < Hdr.CompUnitCount);
- uint32_t Offset = CUsBase + 4 * CU;
+ uint64_t Offset = CUsBase + 4 * CU;
return Section.AccelSection.getRelocatedValue(4, &Offset);
}
-uint32_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const {
+uint64_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const {
assert(TU < Hdr.LocalTypeUnitCount);
- uint32_t Offset = CUsBase + 4 * (Hdr.CompUnitCount + TU);
+ uint64_t Offset = CUsBase + 4 * (Hdr.CompUnitCount + TU);
return Section.AccelSection.getRelocatedValue(4, &Offset);
}
uint64_t DWARFDebugNames::NameIndex::getForeignTUSignature(uint32_t TU) const {
assert(TU < Hdr.ForeignTypeUnitCount);
- uint32_t Offset =
+ uint64_t Offset =
CUsBase + 4 * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU;
return Section.AccelSection.getU64(&Offset);
}
Expected<DWARFDebugNames::Entry>
-DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const {
+DWARFDebugNames::NameIndex::getEntry(uint64_t *Offset) const {
const DWARFDataExtractor &AS = Section.AccelSection;
if (!AS.isValidOffset(*Offset))
return createStringError(errc::illegal_byte_sequence,
@@ -625,12 +625,12 @@ DWARFDebugNames::NameIndex::getEntry(uint32_t *Offset) const {
DWARFDebugNames::NameTableEntry
DWARFDebugNames::NameIndex::getNameTableEntry(uint32_t Index) const {
assert(0 < Index && Index <= Hdr.NameCount);
- uint32_t StringOffsetOffset = StringOffsetsBase + 4 * (Index - 1);
- uint32_t EntryOffsetOffset = EntryOffsetsBase + 4 * (Index - 1);
+ uint64_t StringOffsetOffset = StringOffsetsBase + 4 * (Index - 1);
+ uint64_t EntryOffsetOffset = EntryOffsetsBase + 4 * (Index - 1);
const DWARFDataExtractor &AS = Section.AccelSection;
- uint32_t StringOffset = AS.getRelocatedValue(4, &StringOffsetOffset);
- uint32_t EntryOffset = AS.getU32(&EntryOffsetOffset);
+ uint64_t StringOffset = AS.getRelocatedValue(4, &StringOffsetOffset);
+ uint64_t EntryOffset = AS.getU32(&EntryOffsetOffset);
EntryOffset += EntriesBase;
return {Section.StringSection, Index, StringOffset, EntryOffset};
}
@@ -638,13 +638,13 @@ DWARFDebugNames::NameIndex::getNameTableEntry(uint32_t Index) const {
uint32_t
DWARFDebugNames::NameIndex::getBucketArrayEntry(uint32_t Bucket) const {
assert(Bucket < Hdr.BucketCount);
- uint32_t BucketOffset = BucketsBase + 4 * Bucket;
+ uint64_t BucketOffset = BucketsBase + 4 * Bucket;
return Section.AccelSection.getU32(&BucketOffset);
}
uint32_t DWARFDebugNames::NameIndex::getHashArrayEntry(uint32_t Index) const {
assert(0 < Index && Index <= Hdr.NameCount);
- uint32_t HashOffset = HashesBase + 4 * (Index - 1);
+ uint64_t HashOffset = HashesBase + 4 * (Index - 1);
return Section.AccelSection.getU32(&HashOffset);
}
@@ -653,8 +653,8 @@ uint32_t DWARFDebugNames::NameIndex::getHashArrayEntry(uint32_t Index) const {
// it's not possible to recover this entry list (but the other lists may still
// parse OK).
bool DWARFDebugNames::NameIndex::dumpEntry(ScopedPrinter &W,
- uint32_t *Offset) const {
- uint32_t EntryId = *Offset;
+ uint64_t *Offset) const {
+ uint64_t EntryId = *Offset;
auto EntryOr = getEntry(Offset);
if (!EntryOr) {
handleAllErrors(EntryOr.takeError(), [](const SentinelError &) {},
@@ -674,10 +674,10 @@ void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W,
if (Hash)
W.printHex("Hash", *Hash);
- W.startLine() << format("String: 0x%08x", NTE.getStringOffset());
+ W.startLine() << format("String: 0x%08" PRIx64, NTE.getStringOffset());
W.getOStream() << " \"" << NTE.getString() << "\"\n";
- uint32_t EntryOffset = NTE.getEntryOffset();
+ uint64_t EntryOffset = NTE.getEntryOffset();
while (dumpEntry(W, &EntryOffset))
/*empty*/;
}
@@ -685,7 +685,7 @@ void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W,
void DWARFDebugNames::NameIndex::dumpCUs(ScopedPrinter &W) const {
ListScope CUScope(W, "Compilation Unit offsets");
for (uint32_t CU = 0; CU < Hdr.CompUnitCount; ++CU)
- W.startLine() << format("CU[%u]: 0x%08x\n", CU, getCUOffset(CU));
+ W.startLine() << format("CU[%u]: 0x%08" PRIx64 "\n", CU, getCUOffset(CU));
}
void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const {
@@ -694,7 +694,8 @@ void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const {
ListScope TUScope(W, "Local Type Unit offsets");
for (uint32_t TU = 0; TU < Hdr.LocalTypeUnitCount; ++TU)
- W.startLine() << format("LocalTU[%u]: 0x%08x\n", TU, getLocalTUOffset(TU));
+ W.startLine() << format("LocalTU[%u]: 0x%08" PRIx64 "\n", TU,
+ getLocalTUOffset(TU));
}
void DWARFDebugNames::NameIndex::dumpForeignTUs(ScopedPrinter &W) const {
@@ -756,7 +757,7 @@ LLVM_DUMP_METHOD void DWARFDebugNames::NameIndex::dump(ScopedPrinter &W) const {
}
Error DWARFDebugNames::extract() {
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
while (AccelSection.isValidOffset(Offset)) {
NameIndex Next(*this, Offset);
if (Error E = Next.extract())
@@ -778,7 +779,7 @@ LLVM_DUMP_METHOD void DWARFDebugNames::dump(raw_ostream &OS) const {
NI.dump(W);
}
-Optional<uint32_t>
+Optional<uint64_t>
DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() {
const Header &Hdr = CurrentIndex->Hdr;
if (Hdr.BucketCount == 0) {
@@ -822,7 +823,7 @@ bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() {
}
bool DWARFDebugNames::ValueIterator::findInCurrentIndex() {
- Optional<uint32_t> Offset = findEntryOffsetInCurrentIndex();
+ Optional<uint64_t> Offset = findEntryOffsetInCurrentIndex();
if (!Offset)
return false;
DataOffset = *Offset;
@@ -877,7 +878,7 @@ DWARFDebugNames::equal_range(StringRef Key) const {
}
const DWARFDebugNames::NameIndex *
-DWARFDebugNames::getCUNameIndex(uint32_t CUOffset) {
+DWARFDebugNames::getCUNameIndex(uint64_t CUOffset) {
if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) {
for (const auto &NI : *this) {
for (uint32_t CU = 0; CU < NI.getCUCount(); ++CU)
diff --git a/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 74cce42466dd..f59e49268288 100644
--- a/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -15,16 +15,18 @@
using namespace llvm;
void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
- OS << format("0x%08x", getOffset()) << ": Compile Unit:"
- << " length = " << format("0x%08x", getLength())
+ OS << format("0x%08" PRIx64, getOffset()) << ": Compile Unit:"
+ << " length = " << format("0x%08" PRIx64, getLength())
<< " version = " << format("0x%04x", getVersion());
if (getVersion() >= 5)
OS << " unit_type = " << dwarf::UnitTypeString(getUnitType());
- OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
+ OS << " abbr_offset = "
+ << format("0x%04" PRIx64, getAbbreviations()->getOffset())
<< " addr_size = " << format("0x%02x", getAddressByteSize());
if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
OS << " DWO_id = " << format("0x%016" PRIx64, *getDWOId());
- OS << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
+ OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
+ << ")\n";
if (DWARFDie CUDie = getUnitDIE(false))
CUDie.dump(OS, 0, DumpOpts);
diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp
index 5ede9bf59619..c06d85d50609 100644
--- a/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -138,7 +138,7 @@ static void dumpDWARFv5StringOffsetsSection(
DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
DataExtractor StrData(StringSection, LittleEndian, 0);
uint64_t SectionSize = StringOffsetsSection.Data.size();
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
for (auto &Contribution : Contributions) {
// Report an ill-formed contribution.
if (!Contribution) {
@@ -166,10 +166,10 @@ static void dumpDWARFv5StringOffsetsSection(
}
// Report a gap in the table.
if (Offset < ContributionHeader) {
- OS << format("0x%8.8x: Gap, length = ", Offset);
+ OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
OS << (ContributionHeader - Offset) << "\n";
}
- OS << format("0x%8.8x: ", (uint32_t)ContributionHeader);
+ OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
// In DWARF v5 the contribution size in the descriptor does not equal
// the originally encoded length (it does not contain the length of the
// version field and the padding, a total of 4 bytes). Add them back in
@@ -181,26 +181,19 @@ static void dumpDWARFv5StringOffsetsSection(
Offset = Contribution->Base;
unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
while (Offset - Contribution->Base < Contribution->Size) {
- OS << format("0x%8.8x: ", Offset);
- // FIXME: We can only extract strings if the offset fits in 32 bits.
+ OS << format("0x%8.8" PRIx64 ": ", Offset);
uint64_t StringOffset =
StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
- // Extract the string if we can and display it. Otherwise just report
- // the offset.
- if (StringOffset <= std::numeric_limits<uint32_t>::max()) {
- uint32_t StringOffset32 = (uint32_t)StringOffset;
- OS << format("%8.8x ", StringOffset32);
- const char *S = StrData.getCStr(&StringOffset32);
- if (S)
- OS << format("\"%s\"", S);
- } else
- OS << format("%16.16" PRIx64 " ", StringOffset);
+ OS << format("%8.8" PRIx64 " ", StringOffset);
+ const char *S = StrData.getCStr(&StringOffset);
+ if (S)
+ OS << format("\"%s\"", S);
OS << "\n";
}
}
// Report a gap at the end of the table.
if (Offset < SectionSize) {
- OS << format("0x%8.8x: Gap, length = ", Offset);
+ OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
OS << (SectionSize - Offset) << "\n";
}
}
@@ -225,7 +218,7 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
StringSection, Units, LittleEndian);
else {
DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
- uint32_t offset = 0;
+ uint64_t offset = 0;
uint64_t size = StringOffsetsSection.Data.size();
// Ensure that size is a multiple of the size of an entry.
if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
@@ -235,9 +228,9 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
}
DataExtractor StrData(StringSection, LittleEndian, 0);
while (offset < size) {
- OS << format("0x%8.8x: ", offset);
- uint32_t StringOffset = strOffsetExt.getU32(&offset);
- OS << format("%8.8x ", StringOffset);
+ OS << format("0x%8.8" PRIx64 ": ", offset);
+ uint64_t StringOffset = strOffsetExt.getU32(&offset);
+ OS << format("%8.8" PRIx64 " ", StringOffset);
const char *S = StrData.getCStr(&StringOffset);
if (S)
OS << format("\"%s\"", S);
@@ -250,10 +243,10 @@ static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
DIDumpOptions DumpOpts, uint16_t Version,
uint8_t AddrSize) {
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
while (AddrData.isValidOffset(Offset)) {
DWARFDebugAddrTable AddrTable;
- uint32_t TableOffset = Offset;
+ uint64_t TableOffset = Offset;
if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
DWARFContext::dumpWarning)) {
WithColor::error() << toString(std::move(Err)) << '\n';
@@ -261,8 +254,7 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
// could be read. If it couldn't, stop reading the section.
if (!AddrTable.hasValidLength())
break;
- uint64_t Length = AddrTable.getLength();
- Offset = TableOffset + Length;
+ Offset = TableOffset + AddrTable.getLength();
} else {
AddrTable.dump(OS, DumpOpts);
}
@@ -275,10 +267,10 @@ static void dumpRnglistsSection(
llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
LookupPooledAddress,
DIDumpOptions DumpOpts) {
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
while (rnglistData.isValidOffset(Offset)) {
llvm::DWARFDebugRnglistTable Rnglists;
- uint32_t TableOffset = Offset;
+ uint64_t TableOffset = Offset;
if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
WithColor::error() << toString(std::move(Err)) << '\n';
uint64_t Length = Rnglists.length();
@@ -297,21 +289,25 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
DWARFDataExtractor Data,
const MCRegisterInfo *MRI,
Optional<uint64_t> DumpOffset) {
- uint32_t Offset = 0;
- DWARFDebugLoclists Loclists;
+ uint64_t Offset = 0;
- DWARFListTableHeader Header(".debug_loclists", "locations");
- if (Error E = Header.extract(Data, &Offset)) {
- WithColor::error() << toString(std::move(E)) << '\n';
- return;
- }
+ while (Data.isValidOffset(Offset)) {
+ DWARFListTableHeader Header(".debug_loclists", "locations");
+ if (Error E = Header.extract(Data, &Offset)) {
+ WithColor::error() << toString(std::move(E)) << '\n';
+ return;
+ }
- Header.dump(OS, DumpOpts);
- DataExtractor LocData(Data.getData().drop_front(Offset),
- Data.isLittleEndian(), Header.getAddrSize());
+ Header.dump(OS, DumpOpts);
+ DataExtractor LocData(Data.getData(),
+ Data.isLittleEndian(), Header.getAddrSize());
- Loclists.parse(LocData, Header.getVersion());
- Loclists.dump(OS, 0, MRI, DumpOffset);
+ DWARFDebugLoclists Loclists;
+ uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
+ Loclists.parse(LocData, Offset, EndOffset, Header.getVersion());
+ Loclists.dump(OS, 0, MRI, DumpOpts, DumpOffset);
+ Offset = EndOffset;
+ }
}
void DWARFContext::dump(
@@ -386,7 +382,7 @@ void DWARFContext::dump(
if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
DObj->getLocSection().Data)) {
- getDebugLoc()->dump(OS, getRegisterInfo(), *Off);
+ getDebugLoc()->dump(OS, getRegisterInfo(), DumpOpts, *Off);
}
if (const auto *Off =
shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
@@ -398,15 +394,15 @@ void DWARFContext::dump(
if (const auto *Off =
shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
DObj->getLocDWOSection().Data)) {
- getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), *Off);
+ getDebugLocDWO()->dump(OS, 0, getRegisterInfo(), DumpOpts, *Off);
}
if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
- DObj->getDebugFrameSection()))
+ DObj->getFrameSection().Data))
getDebugFrame()->dump(OS, getRegisterInfo(), *Off);
if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
- DObj->getEHFrameSection()))
+ DObj->getEHFrameSection().Data))
getEHFrame()->dump(OS, getRegisterInfo(), *Off);
if (DumpType & DIDT_DebugMacro) {
@@ -417,9 +413,9 @@ void DWARFContext::dump(
}
if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
- DObj->getARangeSection())) {
- uint32_t offset = 0;
- DataExtractor arangesData(DObj->getARangeSection(), isLittleEndian(), 0);
+ DObj->getArangesSection())) {
+ uint64_t offset = 0;
+ DataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(), 0);
DWARFDebugArangeSet set;
while (set.extract(arangesData, &offset))
set.dump(OS);
@@ -433,7 +429,8 @@ void DWARFContext::dump(
Parser.skip(dumpWarning);
continue;
}
- OS << "debug_line[" << format("0x%8.8x", Parser.getOffset()) << "]\n";
+ OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
+ << "]\n";
if (DumpOpts.Verbose) {
Parser.parseNext(dumpWarning, dumpWarning, &OS);
} else {
@@ -474,32 +471,32 @@ void DWARFContext::dump(
}
if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
- DObj->getStringSection())) {
- DataExtractor strData(DObj->getStringSection(), isLittleEndian(), 0);
- uint32_t offset = 0;
- uint32_t strOffset = 0;
+ DObj->getStrSection())) {
+ DataExtractor strData(DObj->getStrSection(), isLittleEndian(), 0);
+ uint64_t offset = 0;
+ uint64_t strOffset = 0;
while (const char *s = strData.getCStr(&offset)) {
- OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
+ OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strOffset, s);
strOffset = offset;
}
}
if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
- DObj->getStringDWOSection())) {
- DataExtractor strDWOData(DObj->getStringDWOSection(), isLittleEndian(), 0);
- uint32_t offset = 0;
- uint32_t strDWOOffset = 0;
+ DObj->getStrDWOSection())) {
+ DataExtractor strDWOData(DObj->getStrDWOSection(), isLittleEndian(), 0);
+ uint64_t offset = 0;
+ uint64_t strDWOOffset = 0;
while (const char *s = strDWOData.getCStr(&offset)) {
- OS << format("0x%8.8x: \"%s\"\n", strDWOOffset, s);
+ OS << format("0x%8.8" PRIx64 ": \"%s\"\n", strDWOOffset, s);
strDWOOffset = offset;
}
}
if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
- DObj->getLineStringSection())) {
- DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0);
- uint32_t offset = 0;
- uint32_t strOffset = 0;
+ DObj->getLineStrSection())) {
+ DataExtractor strData(DObj->getLineStrSection(), isLittleEndian(), 0);
+ uint64_t offset = 0;
+ uint64_t strOffset = 0;
while (const char *s = strData.getCStr(&offset)) {
- OS << format("0x%8.8x: \"", strOffset);
+ OS << format("0x%8.8" PRIx64 ": \"", strOffset);
OS.write_escaped(s);
OS << "\"\n";
strOffset = offset;
@@ -514,11 +511,11 @@ void DWARFContext::dump(
}
if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
- DObj->getRangeSection().Data)) {
+ DObj->getRangesSection().Data)) {
uint8_t savedAddressByteSize = getCUAddrSize();
- DWARFDataExtractor rangesData(*DObj, DObj->getRangeSection(),
+ DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
isLittleEndian(), savedAddressByteSize);
- uint32_t offset = 0;
+ uint64_t offset = 0;
DWARFDebugRangeList rangeList;
while (rangesData.isValidOffset(offset)) {
if (Error E = rangeList.extract(rangesData, &offset)) {
@@ -552,38 +549,38 @@ void DWARFContext::dump(
}
if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
- DObj->getPubNamesSection().Data))
- DWARFDebugPubTable(*DObj, DObj->getPubNamesSection(), isLittleEndian(), false)
+ DObj->getPubnamesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getPubnamesSection(), isLittleEndian(), false)
.dump(OS);
if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
- DObj->getPubTypesSection().Data))
- DWARFDebugPubTable(*DObj, DObj->getPubTypesSection(), isLittleEndian(), false)
+ DObj->getPubtypesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getPubtypesSection(), isLittleEndian(), false)
.dump(OS);
if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
- DObj->getGnuPubNamesSection().Data))
- DWARFDebugPubTable(*DObj, DObj->getGnuPubNamesSection(), isLittleEndian(),
+ DObj->getGnuPubnamesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getGnuPubnamesSection(), isLittleEndian(),
true /* GnuStyle */)
.dump(OS);
if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
- DObj->getGnuPubTypesSection().Data))
- DWARFDebugPubTable(*DObj, DObj->getGnuPubTypesSection(), isLittleEndian(),
+ DObj->getGnuPubtypesSection().Data))
+ DWARFDebugPubTable(*DObj, DObj->getGnuPubtypesSection(), isLittleEndian(),
true /* GnuStyle */)
.dump(OS);
if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
- DObj->getStringOffsetSection().Data))
+ DObj->getStrOffsetsSection().Data))
dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj,
- DObj->getStringOffsetSection(),
- DObj->getStringSection(), normal_units(),
+ DObj->getStrOffsetsSection(),
+ DObj->getStrSection(), normal_units(),
isLittleEndian(), getMaxVersion());
if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
- DObj->getStringOffsetDWOSection().Data))
+ DObj->getStrOffsetsDWOSection().Data))
dumpStringOffsetsSection(OS, "debug_str_offsets.dwo", *DObj,
- DObj->getStringOffsetDWOSection(),
- DObj->getStringDWOSection(), dwo_units(),
+ DObj->getStrOffsetsDWOSection(),
+ DObj->getStrDWOSection(), dwo_units(),
isLittleEndian(), getMaxDWOVersion());
if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
@@ -607,7 +604,7 @@ void DWARFContext::dump(
DObj->getAppleObjCSection().Data))
getAppleObjC().dump(OS);
if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
- DObj->getDebugNamesSection().Data))
+ DObj->getNamesSection().Data))
getDebugNames().dump(OS);
}
@@ -641,7 +638,7 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
return nullptr;
}
-DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
+DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) {
parseNormalUnits();
if (auto *CU = NormalUnits.getUnitForOffset(Offset))
return CU->getDIEForOffset(Offset);
@@ -667,7 +664,7 @@ const DWARFUnitIndex &DWARFContext::getCUIndex() {
DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
- CUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
+ CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
CUIndex->parse(CUIndexData);
return *CUIndex;
}
@@ -678,7 +675,7 @@ const DWARFUnitIndex &DWARFContext::getTUIndex() {
DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
- TUIndex = llvm::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
+ TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_TYPES);
TUIndex->parse(TUIndexData);
return *TUIndex;
}
@@ -688,7 +685,7 @@ DWARFGdbIndex &DWARFContext::getGdbIndex() {
return *GdbIndex;
DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
- GdbIndex = llvm::make_unique<DWARFGdbIndex>();
+ GdbIndex = std::make_unique<DWARFGdbIndex>();
GdbIndex->parse(GdbIndexData);
return *GdbIndex;
}
@@ -740,7 +737,7 @@ const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() {
// Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
// that means we are parsing the new style .debug_loc (pre-standatized version
// of the .debug_loclists).
- LocDWO->parse(LocData, 4 /* Version */);
+ LocDWO->parse(LocData, 0, LocData.getData().size(), 4 /* Version */);
return LocDWO.get();
}
@@ -766,7 +763,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
// provides this information). This problem is fixed in DWARFv4
// See this dwarf-discuss discussion for more details:
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
- DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
+ DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(),
isLittleEndian(), DObj->getAddressSize());
DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
DebugFrame->parse(debugFrameData);
@@ -777,8 +774,8 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
if (EHFrame)
return EHFrame.get();
- DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
- DObj->getAddressSize());
+ DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
+ isLittleEndian(), DObj->getAddressSize());
DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
DebugFrame->parse(debugFrameData);
return DebugFrame.get();
@@ -809,29 +806,29 @@ static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
}
const DWARFDebugNames &DWARFContext::getDebugNames() {
- return getAccelTable(Names, *DObj, DObj->getDebugNamesSection(),
- DObj->getStringSection(), isLittleEndian());
+ return getAccelTable(Names, *DObj, DObj->getNamesSection(),
+ DObj->getStrSection(), isLittleEndian());
}
const AppleAcceleratorTable &DWARFContext::getAppleNames() {
return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
- DObj->getStringSection(), isLittleEndian());
+ DObj->getStrSection(), isLittleEndian());
}
const AppleAcceleratorTable &DWARFContext::getAppleTypes() {
return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
- DObj->getStringSection(), isLittleEndian());
+ DObj->getStrSection(), isLittleEndian());
}
const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() {
return getAccelTable(AppleNamespaces, *DObj,
DObj->getAppleNamespacesSection(),
- DObj->getStringSection(), isLittleEndian());
+ DObj->getStrSection(), isLittleEndian());
}
const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
- DObj->getStringSection(), isLittleEndian());
+ DObj->getStrSection(), isLittleEndian());
}
const DWARFDebugLine::LineTable *
@@ -858,7 +855,7 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
if (!Offset)
return nullptr; // No line table for this compile unit.
- uint32_t stmtOffset = *Offset + U->getLineTableOffset();
+ uint64_t stmtOffset = *Offset + U->getLineTableOffset();
// See if the line table is cached.
if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
return lt;
@@ -898,7 +895,7 @@ void DWARFContext::parseDWOUnits(bool Lazy) {
});
}
-DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
+DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
parseNormalUnits();
return dyn_cast_or_null<DWARFCompileUnit>(
NormalUnits.getUnitForOffset(Offset));
@@ -906,7 +903,7 @@ DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
// First, get the offset of the compile unit.
- uint32_t CUOffset = getDebugAranges()->findAddress(Address);
+ uint64_t CUOffset = getDebugAranges()->findAddress(Address);
// Retrieve the compile unit.
return getCompileUnitForOffset(CUOffset);
}
@@ -1118,8 +1115,8 @@ DILineInfoTable DWARFContext::getLineInfoForAddressRange(
if (!CU)
return Lines;
- std::string FunctionName = "<invalid>";
uint32_t StartLine = 0;
+ std::string FunctionName(DILineInfo::BadString);
getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind,
FunctionName, StartLine);
@@ -1379,46 +1376,50 @@ class DWARFObjInMemory final : public DWARFObject {
InfoSectionMap TypesDWOSections;
DWARFSectionMap LocSection;
- DWARFSectionMap LocListsSection;
+ DWARFSectionMap LoclistsSection;
DWARFSectionMap LineSection;
- DWARFSectionMap RangeSection;
+ DWARFSectionMap RangesSection;
DWARFSectionMap RnglistsSection;
- DWARFSectionMap StringOffsetSection;
+ DWARFSectionMap StrOffsetsSection;
DWARFSectionMap LineDWOSection;
+ DWARFSectionMap FrameSection;
+ DWARFSectionMap EHFrameSection;
DWARFSectionMap LocDWOSection;
- DWARFSectionMap StringOffsetDWOSection;
- DWARFSectionMap RangeDWOSection;
+ DWARFSectionMap StrOffsetsDWOSection;
+ DWARFSectionMap RangesDWOSection;
DWARFSectionMap RnglistsDWOSection;
DWARFSectionMap AddrSection;
DWARFSectionMap AppleNamesSection;
DWARFSectionMap AppleTypesSection;
DWARFSectionMap AppleNamespacesSection;
DWARFSectionMap AppleObjCSection;
- DWARFSectionMap DebugNamesSection;
- DWARFSectionMap PubNamesSection;
- DWARFSectionMap PubTypesSection;
- DWARFSectionMap GnuPubNamesSection;
- DWARFSectionMap GnuPubTypesSection;
+ DWARFSectionMap NamesSection;
+ DWARFSectionMap PubnamesSection;
+ DWARFSectionMap PubtypesSection;
+ DWARFSectionMap GnuPubnamesSection;
+ DWARFSectionMap GnuPubtypesSection;
DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
return StringSwitch<DWARFSectionMap *>(Name)
.Case("debug_loc", &LocSection)
- .Case("debug_loclists", &LocListsSection)
+ .Case("debug_loclists", &LoclistsSection)
.Case("debug_line", &LineSection)
- .Case("debug_str_offsets", &StringOffsetSection)
- .Case("debug_ranges", &RangeSection)
+ .Case("debug_frame", &FrameSection)
+ .Case("eh_frame", &EHFrameSection)
+ .Case("debug_str_offsets", &StrOffsetsSection)
+ .Case("debug_ranges", &RangesSection)
.Case("debug_rnglists", &RnglistsSection)
.Case("debug_loc.dwo", &LocDWOSection)
.Case("debug_line.dwo", &LineDWOSection)
- .Case("debug_names", &DebugNamesSection)
+ .Case("debug_names", &NamesSection)
.Case("debug_rnglists.dwo", &RnglistsDWOSection)
- .Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
+ .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
.Case("debug_addr", &AddrSection)
.Case("apple_names", &AppleNamesSection)
- .Case("debug_pubnames", &PubNamesSection)
- .Case("debug_pubtypes", &PubTypesSection)
- .Case("debug_gnu_pubnames", &GnuPubNamesSection)
- .Case("debug_gnu_pubtypes", &GnuPubTypesSection)
+ .Case("debug_pubnames", &PubnamesSection)
+ .Case("debug_pubtypes", &PubtypesSection)
+ .Case("debug_gnu_pubnames", &GnuPubnamesSection)
+ .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
.Case("apple_types", &AppleTypesSection)
.Case("apple_namespaces", &AppleNamespacesSection)
.Case("apple_namespac", &AppleNamespacesSection)
@@ -1427,17 +1428,15 @@ class DWARFObjInMemory final : public DWARFObject {
}
StringRef AbbrevSection;
- StringRef ARangeSection;
- StringRef DebugFrameSection;
- StringRef EHFrameSection;
- StringRef StringSection;
+ StringRef ArangesSection;
+ StringRef StrSection;
StringRef MacinfoSection;
StringRef AbbrevDWOSection;
- StringRef StringDWOSection;
+ StringRef StrDWOSection;
StringRef CUIndexSection;
StringRef GdbIndexSection;
StringRef TUIndexSection;
- StringRef LineStringSection;
+ StringRef LineStrSection;
// A deque holding section data whose iterators are not invalidated when
// new decompressed sections are inserted at the end.
@@ -1448,17 +1447,15 @@ class DWARFObjInMemory final : public DWARFObject {
return &Sec->Data;
return StringSwitch<StringRef *>(Name)
.Case("debug_abbrev", &AbbrevSection)
- .Case("debug_aranges", &ARangeSection)
- .Case("debug_frame", &DebugFrameSection)
- .Case("eh_frame", &EHFrameSection)
- .Case("debug_str", &StringSection)
+ .Case("debug_aranges", &ArangesSection)
+ .Case("debug_str", &StrSection)
.Case("debug_macinfo", &MacinfoSection)
.Case("debug_abbrev.dwo", &AbbrevDWOSection)
- .Case("debug_str.dwo", &StringDWOSection)
+ .Case("debug_str.dwo", &StrDWOSection)
.Case("debug_cu_index", &CUIndexSection)
.Case("debug_tu_index", &TUIndexSection)
.Case("gdb_index", &GdbIndexSection)
- .Case("debug_line_str", &LineStringSection)
+ .Case("debug_line_str", &LineStrSection)
// Any more debug info sections go here.
.Default(nullptr);
}
@@ -1513,7 +1510,11 @@ public:
StringMap<unsigned> SectionAmountMap;
for (const SectionRef &Section : Obj.sections()) {
StringRef Name;
- Section.getName(Name);
+ if (auto NameOrErr = Section.getName())
+ Name = *NameOrErr;
+ else
+ consumeError(NameOrErr.takeError());
+
++SectionAmountMap[Name];
SectionNames.push_back({ Name, true });
@@ -1526,10 +1527,19 @@ public:
continue;
StringRef Data;
- section_iterator RelocatedSection = Section.getRelocatedSection();
+ Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
+ if (!SecOrErr) {
+ ErrorPolicy EP = HandleError(createError(
+ "failed to get relocated section: ", SecOrErr.takeError()));
+ if (EP == ErrorPolicy::Halt)
+ return;
+ continue;
+ }
+
// Try to obtain an already relocated version of this section.
// Else use the unrelocated section from the object file. We'll have to
// apply relocations ourselves later.
+ section_iterator RelocatedSection = *SecOrErr;
if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
Expected<StringRef> E = Section.getContents();
if (E)
@@ -1560,7 +1570,7 @@ public:
*SectionData = Data;
if (Name == "debug_ranges") {
// FIXME: Use the other dwo range section when we emit it.
- RangeDWOSection.Data = Data;
+ RangesDWOSection.Data = Data;
}
} else if (Name == "debug_info") {
// Find debug_info and debug_types data by section rather than name as
@@ -1578,12 +1588,15 @@ public:
continue;
StringRef RelSecName;
- StringRef RelSecData;
- RelocatedSection->getName(RelSecName);
+ if (auto NameOrErr = RelocatedSection->getName())
+ RelSecName = *NameOrErr;
+ else
+ consumeError(NameOrErr.takeError());
// If the section we're relocating was relocated already by the JIT,
// then we used the relocated version above, so we do not need to process
// relocations for it now.
+ StringRef RelSecData;
if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
continue;
@@ -1710,12 +1723,12 @@ public:
const DWARFSection &getLocDWOSection() const override {
return LocDWOSection;
}
- StringRef getStringDWOSection() const override { return StringDWOSection; }
- const DWARFSection &getStringOffsetDWOSection() const override {
- return StringOffsetDWOSection;
+ StringRef getStrDWOSection() const override { return StrDWOSection; }
+ const DWARFSection &getStrOffsetsDWOSection() const override {
+ return StrOffsetsDWOSection;
}
- const DWARFSection &getRangeDWOSection() const override {
- return RangeDWOSection;
+ const DWARFSection &getRangesDWOSection() const override {
+ return RangesDWOSection;
}
const DWARFSection &getRnglistsDWOSection() const override {
return RnglistsDWOSection;
@@ -1726,10 +1739,10 @@ public:
StringRef getTUIndexSection() const override { return TUIndexSection; }
// DWARF v5
- const DWARFSection &getStringOffsetSection() const override {
- return StringOffsetSection;
+ const DWARFSection &getStrOffsetsSection() const override {
+ return StrOffsetsSection;
}
- StringRef getLineStringSection() const override { return LineStringSection; }
+ StringRef getLineStrSection() const override { return LineStrSection; }
// Sections for DWARF5 split dwarf proposal.
void forEachInfoDWOSections(
@@ -1745,24 +1758,28 @@ public:
StringRef getAbbrevSection() const override { return AbbrevSection; }
const DWARFSection &getLocSection() const override { return LocSection; }
- const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
- StringRef getARangeSection() const override { return ARangeSection; }
- StringRef getDebugFrameSection() const override { return DebugFrameSection; }
- StringRef getEHFrameSection() const override { return EHFrameSection; }
+ const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
+ StringRef getArangesSection() const override { return ArangesSection; }
+ const DWARFSection &getFrameSection() const override {
+ return FrameSection;
+ }
+ const DWARFSection &getEHFrameSection() const override {
+ return EHFrameSection;
+ }
const DWARFSection &getLineSection() const override { return LineSection; }
- StringRef getStringSection() const override { return StringSection; }
- const DWARFSection &getRangeSection() const override { return RangeSection; }
+ StringRef getStrSection() const override { return StrSection; }
+ const DWARFSection &getRangesSection() const override { return RangesSection; }
const DWARFSection &getRnglistsSection() const override {
return RnglistsSection;
}
StringRef getMacinfoSection() const override { return MacinfoSection; }
- const DWARFSection &getPubNamesSection() const override { return PubNamesSection; }
- const DWARFSection &getPubTypesSection() const override { return PubTypesSection; }
- const DWARFSection &getGnuPubNamesSection() const override {
- return GnuPubNamesSection;
+ const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
+ const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
+ const DWARFSection &getGnuPubnamesSection() const override {
+ return GnuPubnamesSection;
}
- const DWARFSection &getGnuPubTypesSection() const override {
- return GnuPubTypesSection;
+ const DWARFSection &getGnuPubtypesSection() const override {
+ return GnuPubtypesSection;
}
const DWARFSection &getAppleNamesSection() const override {
return AppleNamesSection;
@@ -1776,8 +1793,8 @@ public:
const DWARFSection &getAppleObjCSection() const override {
return AppleObjCSection;
}
- const DWARFSection &getDebugNamesSection() const override {
- return DebugNamesSection;
+ const DWARFSection &getNamesSection() const override {
+ return NamesSection;
}
StringRef getFileName() const override { return FileName; }
@@ -1799,16 +1816,16 @@ std::unique_ptr<DWARFContext>
DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
function_ref<ErrorPolicy(Error)> HandleError,
std::string DWPName) {
- auto DObj = llvm::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
- return llvm::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
+ auto DObj = std::make_unique<DWARFObjInMemory>(Obj, L, HandleError);
+ return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName));
}
std::unique_ptr<DWARFContext>
DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
uint8_t AddrSize, bool isLittleEndian) {
auto DObj =
- llvm::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
- return llvm::make_unique<DWARFContext>(std::move(DObj), "");
+ std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
+ return std::make_unique<DWARFContext>(std::move(DObj), "");
}
Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
diff --git a/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index b9adf8cb1d99..53e676bc7031 100644
--- a/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -12,14 +12,15 @@
using namespace llvm;
-uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
- uint64_t *SecNdx) const {
+uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
+ uint64_t *SecNdx,
+ Error *Err) const {
if (SecNdx)
*SecNdx = object::SectionedAddress::UndefSection;
if (!Section)
- return getUnsigned(Off, Size);
+ return getUnsigned(Off, Size, Err);
Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
- uint64_t A = getUnsigned(Off, Size);
+ uint64_t A = getUnsigned(Off, Size, Err);
if (!E)
return A;
if (SecNdx)
@@ -31,13 +32,13 @@ uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
}
Optional<uint64_t>
-DWARFDataExtractor::getEncodedPointer(uint32_t *Offset, uint8_t Encoding,
+DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
uint64_t PCRelOffset) const {
if (Encoding == dwarf::DW_EH_PE_omit)
return None;
uint64_t Result = 0;
- uint32_t OldOffset = *Offset;
+ uint64_t OldOffset = *Offset;
// First get value
switch (Encoding & 0x0F) {
case dwarf::DW_EH_PE_absptr:
diff --git a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
index 31b324e5eb27..4afac2f99503 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
@@ -26,9 +26,9 @@ void DWARFAbbreviationDeclarationSet::clear() {
}
bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
- uint32_t *OffsetPtr) {
+ uint64_t *OffsetPtr) {
clear();
- const uint32_t BeginOffset = *OffsetPtr;
+ const uint64_t BeginOffset = *OffsetPtr;
Offset = BeginOffset;
DWARFAbbreviationDeclaration AbbrDecl;
uint32_t PrevAbbrCode = 0;
@@ -82,12 +82,12 @@ void DWARFDebugAbbrev::extract(DataExtractor Data) {
void DWARFDebugAbbrev::parse() const {
if (!Data)
return;
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
auto I = AbbrDeclSets.begin();
while (Data->isValidOffset(Offset)) {
while (I != AbbrDeclSets.end() && I->first < Offset)
++I;
- uint32_t CUAbbrOffset = Offset;
+ uint64_t CUAbbrOffset = Offset;
DWARFAbbreviationDeclarationSet AbbrDecls;
if (!AbbrDecls.extract(*Data, &Offset))
break;
@@ -124,7 +124,7 @@ DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
}
if (Data && CUAbbrOffset < Data->getData().size()) {
- uint32_t Offset = CUAbbrOffset;
+ uint64_t Offset = CUAbbrOffset;
DWARFAbbreviationDeclarationSet AbbrDecls;
if (!AbbrDecls.extract(*Data, &Offset))
return nullptr;
diff --git a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
index 58626539bba4..f71543799e28 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
@@ -19,7 +19,7 @@ void DWARFDebugAddrTable::clear() {
}
Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
- uint32_t *OffsetPtr,
+ uint64_t *OffsetPtr,
uint16_t Version,
uint8_t AddrSize,
std::function<void(Error)> WarnCallback) {
@@ -30,7 +30,7 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
return createStringError(errc::invalid_argument,
"section is not large enough to contain a "
".debug_addr table length at offset 0x%"
- PRIx32, *OffsetPtr);
+ PRIx64, *OffsetPtr);
uint16_t UnitVersion;
if (Version == 0) {
WarnCallback(createStringError(errc::invalid_argument,
@@ -44,28 +44,28 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
Format = dwarf::DwarfFormat::DWARF32;
if (UnitVersion >= 5) {
HeaderData.Length = Data.getU32(OffsetPtr);
- if (HeaderData.Length == 0xffffffffu) {
+ if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
invalidateLength();
return createStringError(errc::not_supported,
- "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx32,
+ "DWARF64 is not supported in .debug_addr at offset 0x%" PRIx64,
HeaderOffset);
}
if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header)) {
uint32_t TmpLength = getLength();
invalidateLength();
return createStringError(errc::invalid_argument,
- ".debug_addr table at offset 0x%" PRIx32
+ ".debug_addr table at offset 0x%" PRIx64
" has too small length (0x%" PRIx32
") to contain a complete header",
HeaderOffset, TmpLength);
}
- uint32_t End = HeaderOffset + getLength();
+ uint64_t End = HeaderOffset + getLength();
if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset)) {
uint32_t TmpLength = getLength();
invalidateLength();
return createStringError(errc::invalid_argument,
"section is not large enough to contain a .debug_addr table "
- "of length 0x%" PRIx32 " at offset 0x%" PRIx32,
+ "of length 0x%" PRIx32 " at offset 0x%" PRIx64,
TmpLength, HeaderOffset);
}
@@ -88,7 +88,7 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
// and consists only of a series of addresses.
if (HeaderData.Version > 5) {
return createStringError(errc::not_supported, "version %" PRIu16
- " of .debug_addr section at offset 0x%" PRIx32 " is not supported",
+ " of .debug_addr section at offset 0x%" PRIx64 " is not supported",
HeaderData.Version, HeaderOffset);
}
// FIXME: For now we just treat version mismatch as an error,
@@ -97,19 +97,19 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
// attribute in the info table.
if (HeaderData.Version != UnitVersion)
return createStringError(errc::invalid_argument,
- ".debug_addr table at offset 0x%" PRIx32
+ ".debug_addr table at offset 0x%" PRIx64
" has version %" PRIu16
" which is different from the version suggested"
" by the DWARF unit header: %" PRIu16,
HeaderOffset, HeaderData.Version, UnitVersion);
if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
return createStringError(errc::not_supported,
- ".debug_addr table at offset 0x%" PRIx32
+ ".debug_addr table at offset 0x%" PRIx64
" has unsupported address size %" PRIu8,
HeaderOffset, HeaderData.AddrSize);
if (HeaderData.AddrSize != AddrSize && AddrSize != 0)
return createStringError(errc::invalid_argument,
- ".debug_addr table at offset 0x%" PRIx32
+ ".debug_addr table at offset 0x%" PRIx64
" has address size %" PRIu8
" which is different from CU address size %" PRIu8,
HeaderOffset, HeaderData.AddrSize, AddrSize);
@@ -117,13 +117,13 @@ Error DWARFDebugAddrTable::extract(DWARFDataExtractor Data,
// TODO: add support for non-zero segment selector size.
if (HeaderData.SegSize != 0)
return createStringError(errc::not_supported,
- ".debug_addr table at offset 0x%" PRIx32
+ ".debug_addr table at offset 0x%" PRIx64
" has unsupported segment selector size %" PRIu8,
HeaderOffset, HeaderData.SegSize);
if (DataSize % HeaderData.AddrSize != 0) {
invalidateLength();
return createStringError(errc::invalid_argument,
- ".debug_addr table at offset 0x%" PRIx32
+ ".debug_addr table at offset 0x%" PRIx64
" contains data of size %" PRIu32
" which is not a multiple of addr size %" PRIu8,
HeaderOffset, DataSize, HeaderData.AddrSize);
@@ -162,7 +162,7 @@ Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const {
return Addrs[Index];
return createStringError(errc::invalid_argument,
"Index %" PRIu32 " is out of range of the "
- ".debug_addr table at offset 0x%" PRIx32,
+ ".debug_addr table at offset 0x%" PRIx64,
Index, HeaderOffset);
}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
index 6551b61accb8..200b2d52a02b 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
@@ -24,13 +24,13 @@ void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS,
}
void DWARFDebugArangeSet::clear() {
- Offset = -1U;
+ Offset = -1ULL;
std::memset(&HeaderData, 0, sizeof(Header));
ArangeDescriptors.clear();
}
bool
-DWARFDebugArangeSet::extract(DataExtractor data, uint32_t *offset_ptr) {
+DWARFDebugArangeSet::extract(DataExtractor data, uint64_t *offset_ptr) {
if (data.isValidOffset(*offset_ptr)) {
ArangeDescriptors.clear();
Offset = *offset_ptr;
diff --git a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index 6460c9feeab8..ca6043109cdb 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -23,11 +23,11 @@ using namespace llvm;
void DWARFDebugAranges::extract(DataExtractor DebugArangesData) {
if (!DebugArangesData.isValidOffset(0))
return;
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
DWARFDebugArangeSet Set;
while (Set.extract(DebugArangesData, &Offset)) {
- uint32_t CUOffset = Set.getCompileUnitDIEOffset();
+ uint64_t CUOffset = Set.getCompileUnitDIEOffset();
for (const auto &Desc : Set.descriptors()) {
uint64_t LowPC = Desc.Address;
uint64_t HighPC = Desc.getEndAddress();
@@ -43,7 +43,7 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
return;
// Extract aranges from .debug_aranges section.
- DataExtractor ArangesData(CTX->getDWARFObj().getARangeSection(),
+ DataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(),
CTX->isLittleEndian(), 0);
extract(ArangesData);
@@ -51,7 +51,7 @@ void DWARFDebugAranges::generate(DWARFContext *CTX) {
// it may describe only a small subset of compilation units, so we need to
// manually build aranges for the rest of them.
for (const auto &CU : CTX->compile_units()) {
- uint32_t CUOffset = CU->getOffset();
+ uint64_t CUOffset = CU->getOffset();
if (ParsedCUOffsets.insert(CUOffset).second) {
Expected<DWARFAddressRangesVector> CURanges = CU->collectAddressRanges();
if (!CURanges)
@@ -71,7 +71,7 @@ void DWARFDebugAranges::clear() {
ParsedCUOffsets.clear();
}
-void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
+void DWARFDebugAranges::appendRange(uint64_t CUOffset, uint64_t LowPC,
uint64_t HighPC) {
if (LowPC >= HighPC)
return;
@@ -80,7 +80,7 @@ void DWARFDebugAranges::appendRange(uint32_t CUOffset, uint64_t LowPC,
}
void DWARFDebugAranges::construct() {
- std::multiset<uint32_t> ValidCUs; // Maintain the set of CUs describing
+ std::multiset<uint64_t> ValidCUs; // Maintain the set of CUs describing
// a current address range.
llvm::sort(Endpoints);
uint64_t PrevAddress = -1ULL;
diff --git a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index b3f23366f2a2..81b00f65741b 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -34,10 +34,10 @@ using namespace dwarf;
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
-Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
- uint32_t EndOffset) {
+Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
+ uint64_t EndOffset) {
while (*Offset < EndOffset) {
- uint8_t Opcode = Data.getU8(Offset);
+ uint8_t Opcode = Data.getRelocatedValue(1, Offset);
// Some instructions have a primary opcode encoded in the top bits.
uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
@@ -74,19 +74,19 @@ Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
break;
case DW_CFA_set_loc:
// Operands: Address
- addInstruction(Opcode, Data.getAddress(Offset));
+ addInstruction(Opcode, Data.getRelocatedAddress(Offset));
break;
case DW_CFA_advance_loc1:
// Operands: 1-byte delta
- addInstruction(Opcode, Data.getU8(Offset));
+ addInstruction(Opcode, Data.getRelocatedValue(1, Offset));
break;
case DW_CFA_advance_loc2:
// Operands: 2-byte delta
- addInstruction(Opcode, Data.getU16(Offset));
+ addInstruction(Opcode, Data.getRelocatedValue(2, Offset));
break;
case DW_CFA_advance_loc4:
// Operands: 4-byte delta
- addInstruction(Opcode, Data.getU32(Offset));
+ addInstruction(Opcode, Data.getRelocatedValue(4, Offset));
break;
case DW_CFA_restore_extended:
case DW_CFA_undefined:
@@ -331,7 +331,7 @@ DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
DWARFDebugFrame::~DWARFDebugFrame() = default;
static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
- uint32_t Offset, int Length) {
+ uint64_t Offset, int Length) {
errs() << "DUMP: ";
for (int i = 0; i < Length; ++i) {
uint8_t c = Data.getU8(&Offset);
@@ -344,7 +344,7 @@ static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
// noreturn attribute usage in lambdas. Once the support for those
// compilers are phased out, we can remove this and return back to
// a ReportError lambda: [StartOffset](const char *ErrorMsg).
-static void LLVM_ATTRIBUTE_NORETURN ReportError(uint32_t StartOffset,
+static void LLVM_ATTRIBUTE_NORETURN ReportError(uint64_t StartOffset,
const char *ErrorMsg) {
std::string Str;
raw_string_ostream OS(Str);
@@ -354,32 +354,30 @@ static void LLVM_ATTRIBUTE_NORETURN ReportError(uint32_t StartOffset,
}
void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
- uint32_t Offset = 0;
- DenseMap<uint32_t, CIE *> CIEs;
+ uint64_t Offset = 0;
+ DenseMap<uint64_t, CIE *> CIEs;
while (Data.isValidOffset(Offset)) {
- uint32_t StartOffset = Offset;
+ uint64_t StartOffset = Offset;
bool IsDWARF64 = false;
- uint64_t Length = Data.getU32(&Offset);
+ uint64_t Length = Data.getRelocatedValue(4, &Offset);
uint64_t Id;
- if (Length == UINT32_MAX) {
+ if (Length == dwarf::DW_LENGTH_DWARF64) {
// DWARF-64 is distinguished by the first 32 bits of the initial length
// field being 0xffffffff. Then, the next 64 bits are the actual entry
// length.
IsDWARF64 = true;
- Length = Data.getU64(&Offset);
+ Length = Data.getRelocatedValue(8, &Offset);
}
// At this point, Offset points to the next field after Length.
// Length is the structure size excluding itself. Compute an offset one
// past the end of the structure (needed to know how many instructions to
// read).
- // TODO: For honest DWARF64 support, DataExtractor will have to treat
- // offset_ptr as uint64_t*
- uint32_t StartStructureOffset = Offset;
- uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
+ uint64_t StartStructureOffset = Offset;
+ uint64_t EndStructureOffset = Offset + Length;
// The Id field's size depends on the DWARF format
Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
@@ -407,22 +405,23 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
Optional<uint32_t> PersonalityEncoding;
if (IsEH) {
Optional<uint64_t> AugmentationLength;
- uint32_t StartAugmentationOffset;
- uint32_t EndAugmentationOffset;
+ uint64_t StartAugmentationOffset;
+ uint64_t EndAugmentationOffset;
// Walk the augmentation string to get all the augmentation data.
for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
switch (AugmentationString[i]) {
default:
- ReportError(StartOffset,
- "Unknown augmentation character in entry at %lx");
+ ReportError(
+ StartOffset,
+ "Unknown augmentation character in entry at %" PRIx64);
case 'L':
LSDAPointerEncoding = Data.getU8(&Offset);
break;
case 'P': {
if (Personality)
ReportError(StartOffset,
- "Duplicate personality in entry at %lx");
+ "Duplicate personality in entry at %" PRIx64);
PersonalityEncoding = Data.getU8(&Offset);
Personality = Data.getEncodedPointer(
&Offset, *PersonalityEncoding,
@@ -438,13 +437,12 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
case 'z':
if (i)
ReportError(StartOffset,
- "'z' must be the first character at %lx");
+ "'z' must be the first character at %" PRIx64);
// Parse the augmentation length first. We only parse it if
// the string contains a 'z'.
AugmentationLength = Data.getULEB128(&Offset);
StartAugmentationOffset = Offset;
- EndAugmentationOffset = Offset +
- static_cast<uint32_t>(*AugmentationLength);
+ EndAugmentationOffset = Offset + *AugmentationLength;
break;
case 'B':
// B-Key is used for signing functions associated with this
@@ -455,14 +453,15 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
if (AugmentationLength.hasValue()) {
if (Offset != EndAugmentationOffset)
- ReportError(StartOffset, "Parsing augmentation data at %lx failed");
+ ReportError(StartOffset,
+ "Parsing augmentation data at %" PRIx64 " failed");
AugmentationData = Data.getData().slice(StartAugmentationOffset,
EndAugmentationOffset);
}
}
- auto Cie = llvm::make_unique<CIE>(
+ auto Cie = std::make_unique<CIE>(
StartOffset, Length, Version, AugmentationString, AddressSize,
SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
@@ -480,8 +479,8 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
if (IsEH) {
// The address size is encoded in the CIE we reference.
if (!Cie)
- ReportError(StartOffset,
- "Parsing FDE data at %lx failed due to missing CIE");
+ ReportError(StartOffset, "Parsing FDE data at %" PRIx64
+ " failed due to missing CIE");
if (auto Val = Data.getEncodedPointer(
&Offset, Cie->getFDEPointerEncoding(),
@@ -498,8 +497,7 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
// Parse the augmentation length and data for this FDE.
uint64_t AugmentationLength = Data.getULEB128(&Offset);
- uint32_t EndAugmentationOffset =
- Offset + static_cast<uint32_t>(AugmentationLength);
+ uint64_t EndAugmentationOffset = Offset + AugmentationLength;
// Decode the LSDA if the CIE augmentation string said we should.
if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
@@ -509,11 +507,12 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
}
if (Offset != EndAugmentationOffset)
- ReportError(StartOffset, "Parsing augmentation data at %lx failed");
+ ReportError(StartOffset,
+ "Parsing augmentation data at %" PRIx64 " failed");
}
} else {
- InitialLocation = Data.getAddress(&Offset);
- AddressRange = Data.getAddress(&Offset);
+ InitialLocation = Data.getRelocatedAddress(&Offset);
+ AddressRange = Data.getRelocatedAddress(&Offset);
}
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
@@ -527,7 +526,8 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
}
if (Offset != EndStructureOffset)
- ReportError(StartOffset, "Parsing entry instructions at %lx failed");
+ ReportError(StartOffset,
+ "Parsing entry instructions at %" PRIx64 " failed");
}
}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index d8a755e90df4..87eab34d58ee 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -19,15 +19,15 @@ using namespace llvm;
using namespace dwarf;
bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
- uint32_t *OffsetPtr) {
+ uint64_t *OffsetPtr) {
DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
- const uint32_t UEndOffset = U.getNextUnitOffset();
+ const uint64_t UEndOffset = U.getNextUnitOffset();
return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0);
}
-bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint32_t *OffsetPtr,
+bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
const DWARFDataExtractor &DebugInfoData,
- uint32_t UEndOffset, uint32_t D) {
+ uint64_t UEndOffset, uint32_t D) {
Offset = *OffsetPtr;
Depth = D;
if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index a1cb1e8582ed..dbee28ff5ab1 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -16,7 +16,6 @@
#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/WithColor.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
@@ -156,7 +155,7 @@ void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
// Parse v2-v4 directory and file tables.
static void
parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
- uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
+ uint64_t *OffsetPtr, uint64_t EndPrologueOffset,
DWARFDebugLine::ContentTypeTracker &ContentTypes,
std::vector<DWARFFormValue> &IncludeDirectories,
std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
@@ -187,18 +186,24 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
}
// Parse v5 directory/file entry content descriptions.
-// Returns the descriptors, or an empty vector if we did not find a path or
-// ran off the end of the prologue.
-static ContentDescriptors
-parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t
- *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker
- *ContentTypes) {
+// Returns the descriptors, or an error if we did not find a path or ran off
+// the end of the prologue.
+static llvm::Expected<ContentDescriptors>
+parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
+ uint64_t EndPrologueOffset,
+ DWARFDebugLine::ContentTypeTracker *ContentTypes) {
ContentDescriptors Descriptors;
int FormatCount = DebugLineData.getU8(OffsetPtr);
bool HasPath = false;
for (int I = 0; I != FormatCount; ++I) {
if (*OffsetPtr >= EndPrologueOffset)
- return ContentDescriptors();
+ return createStringError(
+ errc::invalid_argument,
+ "failed to parse entry content descriptions at offset "
+ "0x%8.8" PRIx64
+ " because offset extends beyond the prologue end at offset "
+ "0x%8.8" PRIx64,
+ *OffsetPtr, EndPrologueOffset);
ContentDescriptor Descriptor;
Descriptor.Type =
dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr));
@@ -209,60 +214,82 @@ parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t
ContentTypes->trackContentType(Descriptor.Type);
Descriptors.push_back(Descriptor);
}
- return HasPath ? Descriptors : ContentDescriptors();
+
+ if (!HasPath)
+ return createStringError(errc::invalid_argument,
+ "failed to parse entry content descriptions"
+ " because no path was found");
+ return Descriptors;
}
-static bool
+static Error
parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
- uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
+ uint64_t *OffsetPtr, uint64_t EndPrologueOffset,
const dwarf::FormParams &FormParams,
const DWARFContext &Ctx, const DWARFUnit *U,
DWARFDebugLine::ContentTypeTracker &ContentTypes,
std::vector<DWARFFormValue> &IncludeDirectories,
std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
// Get the directory entry description.
- ContentDescriptors DirDescriptors =
+ llvm::Expected<ContentDescriptors> DirDescriptors =
parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, nullptr);
- if (DirDescriptors.empty())
- return false;
+ if (!DirDescriptors)
+ return DirDescriptors.takeError();
// Get the directory entries, according to the format described above.
int DirEntryCount = DebugLineData.getU8(OffsetPtr);
for (int I = 0; I != DirEntryCount; ++I) {
if (*OffsetPtr >= EndPrologueOffset)
- return false;
- for (auto Descriptor : DirDescriptors) {
+ return createStringError(
+ errc::invalid_argument,
+ "failed to parse directory entry at offset "
+ "0x%8.8" PRIx64
+ " because offset extends beyond the prologue end at offset "
+ "0x%8.8" PRIx64,
+ *OffsetPtr, EndPrologueOffset);
+ for (auto Descriptor : *DirDescriptors) {
DWARFFormValue Value(Descriptor.Form);
switch (Descriptor.Type) {
case DW_LNCT_path:
if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
- return false;
+ return createStringError(errc::invalid_argument,
+ "failed to parse directory entry because "
+ "extracting the form value failed.");
IncludeDirectories.push_back(Value);
break;
default:
if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
- return false;
+ return createStringError(errc::invalid_argument,
+ "failed to parse directory entry because "
+ "skipping the form value failed.");
}
}
}
// Get the file entry description.
- ContentDescriptors FileDescriptors =
- parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset,
- &ContentTypes);
- if (FileDescriptors.empty())
- return false;
+ llvm::Expected<ContentDescriptors> FileDescriptors = parseV5EntryFormat(
+ DebugLineData, OffsetPtr, EndPrologueOffset, &ContentTypes);
+ if (!FileDescriptors)
+ return FileDescriptors.takeError();
// Get the file entries, according to the format described above.
int FileEntryCount = DebugLineData.getU8(OffsetPtr);
for (int I = 0; I != FileEntryCount; ++I) {
if (*OffsetPtr >= EndPrologueOffset)
- return false;
+ return createStringError(
+ errc::invalid_argument,
+ "failed to parse file entry at offset "
+ "0x%8.8" PRIx64
+ " because offset extends beyond the prologue end at offset "
+ "0x%8.8" PRIx64,
+ *OffsetPtr, EndPrologueOffset);
DWARFDebugLine::FileNameEntry FileEntry;
- for (auto Descriptor : FileDescriptors) {
+ for (auto Descriptor : *FileDescriptors) {
DWARFFormValue Value(Descriptor.Form);
if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
- return false;
+ return createStringError(errc::invalid_argument,
+ "failed to parse file entry because "
+ "extracting the form value failed.");
switch (Descriptor.Type) {
case DW_LNCT_path:
FileEntry.Name = Value;
@@ -280,7 +307,10 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
FileEntry.Length = Value.getAsUnsignedConstant().getValue();
break;
case DW_LNCT_MD5:
- assert(Value.getAsBlock().getValue().size() == 16);
+ if (!Value.getAsBlock() || Value.getAsBlock().getValue().size() != 16)
+ return createStringError(
+ errc::invalid_argument,
+ "failed to parse file entry because the MD5 hash is invalid");
std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
FileEntry.Checksum.Bytes.begin());
break;
@@ -290,21 +320,21 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
}
FileNames.push_back(FileEntry);
}
- return true;
+ return Error::success();
}
Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
- uint32_t *OffsetPtr,
+ uint64_t *OffsetPtr,
const DWARFContext &Ctx,
const DWARFUnit *U) {
const uint64_t PrologueOffset = *OffsetPtr;
clear();
TotalLength = DebugLineData.getRelocatedValue(4, OffsetPtr);
- if (TotalLength == UINT32_MAX) {
+ if (TotalLength == dwarf::DW_LENGTH_DWARF64) {
FormParams.Format = dwarf::DWARF64;
TotalLength = DebugLineData.getU64(OffsetPtr);
- } else if (TotalLength >= 0xfffffff0) {
+ } else if (TotalLength >= dwarf::DW_LENGTH_lo_reserved) {
return createStringError(errc::invalid_argument,
"parsing line table prologue at offset 0x%8.8" PRIx64
" unsupported reserved unit length found of value 0x%8.8" PRIx64,
@@ -343,14 +373,17 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
}
if (getVersion() >= 5) {
- if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
- FormParams, Ctx, U, ContentTypes,
- IncludeDirectories, FileNames)) {
- return createStringError(errc::invalid_argument,
- "parsing line table prologue at 0x%8.8" PRIx64
- " found an invalid directory or file table description at"
- " 0x%8.8" PRIx64,
- PrologueOffset, (uint64_t)*OffsetPtr);
+ if (Error e = parseV5DirFileTables(
+ DebugLineData, OffsetPtr, EndPrologueOffset, FormParams, Ctx, U,
+ ContentTypes, IncludeDirectories, FileNames)) {
+ return joinErrors(
+ createStringError(
+ errc::invalid_argument,
+ "parsing line table prologue at 0x%8.8" PRIx64
+ " found an invalid directory or file table description at"
+ " 0x%8.8" PRIx64,
+ PrologueOffset, *OffsetPtr),
+ std::move(e));
}
} else
parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
@@ -361,7 +394,7 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
"parsing line table prologue at 0x%8.8" PRIx64
" should have ended at 0x%8.8" PRIx64
" but it ended at 0x%8.8" PRIx64,
- PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
+ PrologueOffset, EndPrologueOffset, *OffsetPtr);
return Error::success();
}
@@ -468,7 +501,7 @@ void DWARFDebugLine::ParsingState::appendRowToMatrix() {
}
const DWARFDebugLine::LineTable *
-DWARFDebugLine::getLineTable(uint32_t Offset) const {
+DWARFDebugLine::getLineTable(uint64_t Offset) const {
LineTableConstIter Pos = LineTableMap.find(Offset);
if (Pos != LineTableMap.end())
return &Pos->second;
@@ -476,10 +509,10 @@ DWARFDebugLine::getLineTable(uint32_t Offset) const {
}
Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
- DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFContext &Ctx,
+ DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx,
const DWARFUnit *U, std::function<void(Error)> RecoverableErrorCallback) {
if (!DebugLineData.isValidOffset(Offset))
- return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx32
+ return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx64
" is not a valid debug line section offset",
Offset);
@@ -496,10 +529,10 @@ Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
}
Error DWARFDebugLine::LineTable::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) {
- const uint32_t DebugLineOffset = *OffsetPtr;
+ const uint64_t DebugLineOffset = *OffsetPtr;
clear();
@@ -515,7 +548,7 @@ Error DWARFDebugLine::LineTable::parse(
if (PrologueErr)
return PrologueErr;
- const uint32_t EndOffset =
+ const uint64_t EndOffset =
DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength();
// See if we should tell the data extractor the address size.
@@ -529,7 +562,7 @@ Error DWARFDebugLine::LineTable::parse(
while (*OffsetPtr < EndOffset) {
if (OS)
- *OS << format("0x%08.08" PRIx32 ": ", *OffsetPtr);
+ *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr);
uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
@@ -540,7 +573,7 @@ Error DWARFDebugLine::LineTable::parse(
// Extended Opcodes always start with a zero opcode followed by
// a uleb128 length so you can skip ones you don't know about
uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
- uint32_t ExtOffset = *OffsetPtr;
+ uint64_t ExtOffset = *OffsetPtr;
// Tolerate zero-length; assume length is correct and soldier on.
if (Len == 0) {
@@ -585,7 +618,7 @@ Error DWARFDebugLine::LineTable::parse(
DebugLineData.setAddressSize(Len - 1);
else if (DebugLineData.getAddressSize() != Len - 1) {
return createStringError(errc::invalid_argument,
- "mismatching address size at offset 0x%8.8" PRIx32
+ "mismatching address size at offset 0x%8.8" PRIx64
" expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
ExtOffset, DebugLineData.getAddressSize(),
Len - 1);
@@ -652,8 +685,8 @@ Error DWARFDebugLine::LineTable::parse(
// Otherwise we have an unparseable line-number program.
if (*OffsetPtr - ExtOffset != Len)
return createStringError(errc::illegal_byte_sequence,
- "unexpected line op length at offset 0x%8.8" PRIx32
- " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32,
+ "unexpected line op length at offset 0x%8.8" PRIx64
+ " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
ExtOffset, Len, *OffsetPtr - ExtOffset);
} else if (Opcode < Prologue.OpcodeBase) {
if (OS)
@@ -1007,10 +1040,9 @@ static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
sys::path::is_absolute(Path, sys::path::Style::windows);
}
-bool DWARFDebugLine::Prologue::getFileNameByIndex(uint64_t FileIndex,
- StringRef CompDir,
- FileLineInfoKind Kind,
- std::string &Result) const {
+bool DWARFDebugLine::Prologue::getFileNameByIndex(
+ uint64_t FileIndex, StringRef CompDir, FileLineInfoKind Kind,
+ std::string &Result, sys::path::Style Style) const {
if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
return false;
const FileNameEntry &Entry = getFileNameEntry(FileIndex);
@@ -1036,11 +1068,11 @@ bool DWARFDebugLine::Prologue::getFileNameByIndex(uint64_t FileIndex,
// We know that FileName is not absolute, the only way to have an
// absolute path at this point would be if IncludeDir is absolute.
if (!CompDir.empty() && !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
- sys::path::append(FilePath, CompDir);
+ sys::path::append(FilePath, Style, CompDir);
}
// sys::path::append skips empty strings.
- sys::path::append(FilePath, IncludeDir, FileName);
+ sys::path::append(FilePath, Style, IncludeDir, FileName);
Result = FilePath.str();
return true;
}
@@ -1092,7 +1124,8 @@ DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data,
}
bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
- return TotalLength == 0xffffffff || TotalLength < 0xfffffff0;
+ return TotalLength == dwarf::DW_LENGTH_DWARF64 ||
+ TotalLength < dwarf::DW_LENGTH_lo_reserved;
}
DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
@@ -1101,7 +1134,7 @@ DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
assert(DebugLineData.isValidOffset(Offset) &&
"parsing should have terminated");
DWARFUnit *U = prepareToParse(Offset);
- uint32_t OldOffset = Offset;
+ uint64_t OldOffset = Offset;
LineTable LT;
if (Error Err = LT.parse(DebugLineData, &Offset, Context, U,
RecoverableErrorCallback, OS))
@@ -1115,14 +1148,14 @@ void DWARFDebugLine::SectionParser::skip(
assert(DebugLineData.isValidOffset(Offset) &&
"parsing should have terminated");
DWARFUnit *U = prepareToParse(Offset);
- uint32_t OldOffset = Offset;
+ uint64_t OldOffset = Offset;
LineTable LT;
if (Error Err = LT.Prologue.parse(DebugLineData, &Offset, Context, U))
ErrorCallback(std::move(Err));
moveToNextTable(OldOffset, LT.Prologue);
}
-DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint32_t Offset) {
+DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset) {
DWARFUnit *U = nullptr;
auto It = LineToUnit.find(Offset);
if (It != LineToUnit.end())
@@ -1131,7 +1164,7 @@ DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint32_t Offset) {
return U;
}
-void DWARFDebugLine::SectionParser::moveToNextTable(uint32_t OldOffset,
+void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
const Prologue &P) {
// If the length field is not valid, we don't know where the next table is, so
// cannot continue to parse. Mark the parser as done, and leave the Offset
diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index 6d8f4bee77c4..4f7b01130a47 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -28,19 +28,18 @@ using namespace llvm;
// expression that LLVM doesn't produce. Guessing the wrong version means we
// won't be able to pretty print expressions in DWARF2 binaries produced by
// non-LLVM tools.
-static void dumpExpression(raw_ostream &OS, ArrayRef<char> Data,
+static void dumpExpression(raw_ostream &OS, ArrayRef<uint8_t> Data,
bool IsLittleEndian, unsigned AddressSize,
const MCRegisterInfo *MRI, DWARFUnit *U) {
- DWARFDataExtractor Extractor(StringRef(Data.data(), Data.size()),
- IsLittleEndian, AddressSize);
+ DWARFDataExtractor Extractor(toStringRef(Data), IsLittleEndian, AddressSize);
DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U);
}
-void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian,
+void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, uint64_t BaseAddress,
+ bool IsLittleEndian,
unsigned AddressSize,
- const MCRegisterInfo *MRI,
- DWARFUnit *U,
- uint64_t BaseAddress,
+ const MCRegisterInfo *MRI, DWARFUnit *U,
+ DIDumpOptions DumpOpts,
unsigned Indent) const {
for (const Entry &E : Entries) {
OS << '\n';
@@ -64,12 +63,12 @@ DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const {
return nullptr;
}
-void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
+void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, DIDumpOptions DumpOpts,
Optional<uint64_t> Offset) const {
auto DumpLocationList = [&](const LocationList &L) {
- OS << format("0x%8.8x: ", L.Offset);
- L.dump(OS, IsLittleEndian, AddressSize, MRI, nullptr, 0, 12);
- OS << "\n\n";
+ OS << format("0x%8.8" PRIx64 ": ", L.Offset);
+ L.dump(OS, 0, IsLittleEndian, AddressSize, MRI, nullptr, DumpOpts, 12);
+ OS << "\n";
};
if (Offset) {
@@ -80,50 +79,47 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
for (const LocationList &L : Locations) {
DumpLocationList(L);
+ if (&L != &Locations.back())
+ OS << '\n';
}
}
-Optional<DWARFDebugLoc::LocationList>
-DWARFDebugLoc::parseOneLocationList(DWARFDataExtractor Data, unsigned *Offset) {
+Expected<DWARFDebugLoc::LocationList>
+DWARFDebugLoc::parseOneLocationList(const DWARFDataExtractor &Data,
+ uint64_t *Offset) {
LocationList LL;
LL.Offset = *Offset;
+ AddressSize = Data.getAddressSize();
+ DataExtractor::Cursor C(*Offset);
// 2.6.2 Location Lists
// A location list entry consists of:
while (true) {
Entry E;
- if (!Data.isValidOffsetForDataOfSize(*Offset, 2 * Data.getAddressSize())) {
- WithColor::error() << "location list overflows the debug_loc section.\n";
- return None;
- }
// 1. A beginning address offset. ...
- E.Begin = Data.getRelocatedAddress(Offset);
+ E.Begin = Data.getRelocatedAddress(C);
// 2. An ending address offset. ...
- E.End = Data.getRelocatedAddress(Offset);
+ E.End = Data.getRelocatedAddress(C);
+
+ if (Error Err = C.takeError())
+ return std::move(Err);
// The end of any given location list is marked by an end of list entry,
// which consists of a 0 for the beginning address offset and a 0 for the
// ending address offset.
- if (E.Begin == 0 && E.End == 0)
+ if (E.Begin == 0 && E.End == 0) {
+ *Offset = C.tell();
return LL;
-
- if (!Data.isValidOffsetForDataOfSize(*Offset, 2)) {
- WithColor::error() << "location list overflows the debug_loc section.\n";
- return None;
}
- unsigned Bytes = Data.getU16(Offset);
- if (!Data.isValidOffsetForDataOfSize(*Offset, Bytes)) {
- WithColor::error() << "location list overflows the debug_loc section.\n";
- return None;
+ if (E.Begin != (AddressSize == 4 ? -1U : -1ULL)) {
+ unsigned Bytes = Data.getU16(C);
+ // A single location description describing the location of the object...
+ Data.getU8(C, E.Loc, Bytes);
}
- // A single location description describing the location of the object...
- StringRef str = Data.getData().substr(*Offset, Bytes);
- *Offset += Bytes;
- E.Loc.reserve(str.size());
- llvm::copy(str, std::back_inserter(E.Loc));
+
LL.Entries.push_back(std::move(E));
}
}
@@ -132,81 +128,89 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
IsLittleEndian = data.isLittleEndian();
AddressSize = data.getAddressSize();
- uint32_t Offset = 0;
- while (data.isValidOffset(Offset + data.getAddressSize() - 1)) {
+ uint64_t Offset = 0;
+ while (Offset < data.getData().size()) {
if (auto LL = parseOneLocationList(data, &Offset))
Locations.push_back(std::move(*LL));
- else
+ else {
+ logAllUnhandledErrors(LL.takeError(), WithColor::error());
break;
+ }
}
- if (data.isValidOffset(Offset))
- WithColor::error() << "failed to consume entire .debug_loc section\n";
}
-Optional<DWARFDebugLoclists::LocationList>
-DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset,
- unsigned Version) {
+Expected<DWARFDebugLoclists::LocationList>
+DWARFDebugLoclists::parseOneLocationList(const DataExtractor &Data,
+ uint64_t *Offset, unsigned Version) {
LocationList LL;
LL.Offset = *Offset;
+ DataExtractor::Cursor C(*Offset);
// dwarf::DW_LLE_end_of_list_entry is 0 and indicates the end of the list.
- while (auto Kind =
- static_cast<dwarf::LocationListEntry>(Data.getU8(Offset))) {
-
+ while (auto Kind = Data.getU8(C)) {
Entry E;
E.Kind = Kind;
+ E.Offset = C.tell() - 1;
switch (Kind) {
+ case dwarf::DW_LLE_base_addressx:
+ E.Value0 = Data.getULEB128(C);
+ break;
case dwarf::DW_LLE_startx_length:
- E.Value0 = Data.getULEB128(Offset);
+ E.Value0 = Data.getULEB128(C);
// Pre-DWARF 5 has different interpretation of the length field. We have
// to support both pre- and standartized styles for the compatibility.
if (Version < 5)
- E.Value1 = Data.getU32(Offset);
+ E.Value1 = Data.getU32(C);
else
- E.Value1 = Data.getULEB128(Offset);
+ E.Value1 = Data.getULEB128(C);
break;
case dwarf::DW_LLE_start_length:
- E.Value0 = Data.getAddress(Offset);
- E.Value1 = Data.getULEB128(Offset);
+ E.Value0 = Data.getAddress(C);
+ E.Value1 = Data.getULEB128(C);
break;
case dwarf::DW_LLE_offset_pair:
- E.Value0 = Data.getULEB128(Offset);
- E.Value1 = Data.getULEB128(Offset);
+ E.Value0 = Data.getULEB128(C);
+ E.Value1 = Data.getULEB128(C);
break;
case dwarf::DW_LLE_base_address:
- E.Value0 = Data.getAddress(Offset);
+ E.Value0 = Data.getAddress(C);
break;
default:
- WithColor::error() << "dumping support for LLE of kind " << (int)Kind
- << " not implemented\n";
- return None;
+ cantFail(C.takeError());
+ return createStringError(errc::illegal_byte_sequence,
+ "LLE of kind %x not supported", (int)Kind);
}
- if (Kind != dwarf::DW_LLE_base_address) {
- unsigned Bytes =
- Version >= 5 ? Data.getULEB128(Offset) : Data.getU16(Offset);
+ if (Kind != dwarf::DW_LLE_base_address &&
+ Kind != dwarf::DW_LLE_base_addressx) {
+ unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
// A single location description describing the location of the object...
- StringRef str = Data.getData().substr(*Offset, Bytes);
- *Offset += Bytes;
- E.Loc.resize(str.size());
- llvm::copy(str, E.Loc.begin());
+ Data.getU8(C, E.Loc, Bytes);
}
LL.Entries.push_back(std::move(E));
}
+ if (Error Err = C.takeError())
+ return std::move(Err);
+ Entry E;
+ E.Kind = dwarf::DW_LLE_end_of_list;
+ E.Offset = C.tell() - 1;
+ LL.Entries.push_back(E);
+ *Offset = C.tell();
return LL;
}
-void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) {
+void DWARFDebugLoclists::parse(DataExtractor data, uint64_t Offset, uint64_t EndOffset, uint16_t Version) {
IsLittleEndian = data.isLittleEndian();
AddressSize = data.getAddressSize();
- uint32_t Offset = 0;
- while (data.isValidOffset(Offset)) {
+ while (Offset < EndOffset) {
if (auto LL = parseOneLocationList(data, &Offset, Version))
Locations.push_back(std::move(*LL));
- else
+ else {
+ logAllUnhandledErrors(LL.takeError(), WithColor::error());
return;
+ }
}
}
@@ -219,51 +223,106 @@ DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const {
return nullptr;
}
-void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr,
- bool IsLittleEndian,
- unsigned AddressSize,
- const MCRegisterInfo *MRI,
- DWARFUnit *U,
- unsigned Indent) const {
- for (const Entry &E : Entries) {
- switch (E.Kind) {
+void DWARFDebugLoclists::Entry::dump(raw_ostream &OS, uint64_t &BaseAddr,
+ bool IsLittleEndian, unsigned AddressSize,
+ const MCRegisterInfo *MRI, DWARFUnit *U,
+ DIDumpOptions DumpOpts, unsigned Indent,
+ size_t MaxEncodingStringLength) const {
+ if (DumpOpts.Verbose) {
+ OS << "\n";
+ OS.indent(Indent);
+ auto EncodingString = dwarf::LocListEncodingString(Kind);
+ // Unsupported encodings should have been reported during parsing.
+ assert(!EncodingString.empty() && "Unknown loclist entry encoding");
+ OS << format("%s%*c", EncodingString.data(),
+ MaxEncodingStringLength - EncodingString.size() + 1, '(');
+ switch (Kind) {
case dwarf::DW_LLE_startx_length:
- OS << '\n';
- OS.indent(Indent);
- OS << "Addr idx " << E.Value0 << " (w/ length " << E.Value1 << "): ";
- break;
case dwarf::DW_LLE_start_length:
- OS << '\n';
- OS.indent(Indent);
- OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2,
- AddressSize * 2, E.Value0, AddressSize * 2, AddressSize * 2,
- E.Value0 + E.Value1);
- break;
case dwarf::DW_LLE_offset_pair:
- OS << '\n';
- OS.indent(Indent);
- OS << format("[0x%*.*" PRIx64 ", 0x%*.*" PRIx64 "): ", AddressSize * 2,
- AddressSize * 2, BaseAddr + E.Value0, AddressSize * 2,
- AddressSize * 2, BaseAddr + E.Value1);
+ OS << format("0x%*.*" PRIx64 ", 0x%*.*" PRIx64, AddressSize * 2,
+ AddressSize * 2, Value0, AddressSize * 2, AddressSize * 2,
+ Value1);
break;
+ case dwarf::DW_LLE_base_addressx:
case dwarf::DW_LLE_base_address:
- BaseAddr = E.Value0;
+ OS << format("0x%*.*" PRIx64, AddressSize * 2, AddressSize * 2,
+ Value0);
+ break;
+ case dwarf::DW_LLE_end_of_list:
break;
- default:
- llvm_unreachable("unreachable locations list kind");
}
-
- dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U);
+ OS << ')';
}
+ auto PrintPrefix = [&] {
+ OS << "\n";
+ OS.indent(Indent);
+ if (DumpOpts.Verbose)
+ OS << format("%*s", MaxEncodingStringLength, (const char *)"=> ");
+ };
+ switch (Kind) {
+ case dwarf::DW_LLE_startx_length:
+ PrintPrefix();
+ OS << "Addr idx " << Value0 << " (w/ length " << Value1 << "): ";
+ break;
+ case dwarf::DW_LLE_start_length:
+ PrintPrefix();
+ DWARFAddressRange(Value0, Value0 + Value1)
+ .dump(OS, AddressSize, DumpOpts);
+ OS << ": ";
+ break;
+ case dwarf::DW_LLE_offset_pair:
+ PrintPrefix();
+ DWARFAddressRange(BaseAddr + Value0, BaseAddr + Value1)
+ .dump(OS, AddressSize, DumpOpts);
+ OS << ": ";
+ break;
+ case dwarf::DW_LLE_base_addressx:
+ if (!DumpOpts.Verbose)
+ return;
+ break;
+ case dwarf::DW_LLE_end_of_list:
+ if (!DumpOpts.Verbose)
+ return;
+ break;
+ case dwarf::DW_LLE_base_address:
+ BaseAddr = Value0;
+ if (!DumpOpts.Verbose)
+ return;
+ break;
+ default:
+ llvm_unreachable("unreachable locations list kind");
+ }
+
+ dumpExpression(OS, Loc, IsLittleEndian, AddressSize, MRI, U);
+}
+void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr,
+ bool IsLittleEndian,
+ unsigned AddressSize,
+ const MCRegisterInfo *MRI,
+ DWARFUnit *U,
+ DIDumpOptions DumpOpts,
+ unsigned Indent) const {
+ size_t MaxEncodingStringLength = 0;
+ if (DumpOpts.Verbose)
+ for (const auto &Entry : Entries)
+ MaxEncodingStringLength =
+ std::max(MaxEncodingStringLength,
+ dwarf::LocListEncodingString(Entry.Kind).size());
+
+ for (const Entry &E : Entries)
+ E.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, U, DumpOpts, Indent,
+ MaxEncodingStringLength);
}
void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr,
- const MCRegisterInfo *MRI,
+ const MCRegisterInfo *MRI, DIDumpOptions DumpOpts,
Optional<uint64_t> Offset) const {
auto DumpLocationList = [&](const LocationList &L) {
- OS << format("0x%8.8x: ", L.Offset);
- L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, /*Indent=*/12);
- OS << "\n\n";
+ OS << format("0x%8.8" PRIx64 ": ", L.Offset);
+ L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, DumpOpts,
+ /*Indent=*/12);
+ OS << "\n";
};
if (Offset) {
@@ -274,5 +333,7 @@ void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr,
for (const LocationList &L : Locations) {
DumpLocationList(L);
+ if (&L != &Locations.back())
+ OS << '\n';
}
}
diff --git a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index 3317a778cc70..9a0e770aed3d 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -53,7 +53,7 @@ void DWARFDebugMacro::dump(raw_ostream &OS) const {
}
void DWARFDebugMacro::parse(DataExtractor data) {
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
while (data.isValidOffset(Offset)) {
// A macro list entry consists of:
Entry E;
diff --git a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
index 963ec64f5e91..ab71b239cb67 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
@@ -23,7 +23,7 @@ DWARFDebugPubTable::DWARFDebugPubTable(const DWARFObject &Obj,
bool LittleEndian, bool GnuStyle)
: GnuStyle(GnuStyle) {
DWARFDataExtractor PubNames(Obj, Sec, LittleEndian, 0);
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
while (PubNames.isValidOffset(Offset)) {
Sets.push_back({});
Set &SetData = Sets.back();
@@ -49,13 +49,13 @@ void DWARFDebugPubTable::dump(raw_ostream &OS) const {
for (const Set &S : Sets) {
OS << "length = " << format("0x%08x", S.Length);
OS << " version = " << format("0x%04x", S.Version);
- OS << " unit_offset = " << format("0x%08x", S.Offset);
+ OS << " unit_offset = " << format("0x%08" PRIx64, S.Offset);
OS << " unit_size = " << format("0x%08x", S.Size) << '\n';
OS << (GnuStyle ? "Offset Linkage Kind Name\n"
: "Offset Name\n");
for (const Entry &E : S.Entries) {
- OS << format("0x%8.8x ", E.SecOffset);
+ OS << format("0x%8.8" PRIx64 " ", E.SecOffset);
if (GnuStyle) {
StringRef EntryLinkage =
GDBIndexEntryLinkageString(E.Descriptor.Linkage);
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index d8df81a0aa0b..1a1857d8cd79 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -17,17 +17,17 @@
using namespace llvm;
void DWARFDebugRangeList::clear() {
- Offset = -1U;
+ Offset = -1ULL;
AddressSize = 0;
Entries.clear();
}
Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
- uint32_t *offset_ptr) {
+ uint64_t *offset_ptr) {
clear();
if (!data.isValidOffset(*offset_ptr))
return createStringError(errc::invalid_argument,
- "invalid range list offset 0x%" PRIx32, *offset_ptr);
+ "invalid range list offset 0x%" PRIx64, *offset_ptr);
AddressSize = data.getAddressSize();
if (AddressSize != 4 && AddressSize != 8)
@@ -38,7 +38,7 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
RangeListEntry Entry;
Entry.SectionIndex = -1ULL;
- uint32_t prev_offset = *offset_ptr;
+ uint64_t prev_offset = *offset_ptr;
Entry.StartAddress = data.getRelocatedAddress(offset_ptr);
Entry.EndAddress =
data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex);
@@ -47,7 +47,7 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
if (*offset_ptr != prev_offset + 2 * AddressSize) {
clear();
return createStringError(errc::invalid_argument,
- "invalid range list entry at offset 0x%" PRIx32,
+ "invalid range list entry at offset 0x%" PRIx64,
prev_offset);
}
if (Entry.isEndOfListEntry())
@@ -59,12 +59,12 @@ Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
void DWARFDebugRangeList::dump(raw_ostream &OS) const {
for (const RangeListEntry &RLE : Entries) {
- const char *format_str = (AddressSize == 4
- ? "%08x %08" PRIx64 " %08" PRIx64 "\n"
- : "%08x %016" PRIx64 " %016" PRIx64 "\n");
+ const char *format_str =
+ (AddressSize == 4 ? "%08" PRIx64 " %08" PRIx64 " %08" PRIx64 "\n"
+ : "%08" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n");
OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
}
- OS << format("%08x <End of list>\n", Offset);
+ OS << format("%08" PRIx64 " <End of list>\n", Offset);
}
DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
diff --git a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index 5ac3326f6681..f6785b89e86d 100644
--- a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -16,8 +16,8 @@
using namespace llvm;
-Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
- uint32_t *OffsetPtr) {
+Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t End,
+ uint64_t *OffsetPtr) {
Offset = *OffsetPtr;
SectionIndex = -1ULL;
// The caller should guarantee that we have at least 1 byte available, so
@@ -32,41 +32,41 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
break;
// TODO: Support other encodings.
case dwarf::DW_RLE_base_addressx: {
- uint32_t PreviousOffset = *OffsetPtr - 1;
+ uint64_t PreviousOffset = *OffsetPtr - 1;
Value0 = Data.getULEB128(OffsetPtr);
if (End < *OffsetPtr)
return createStringError(
errc::invalid_argument,
"read past end of table when reading "
- "DW_RLE_base_addressx encoding at offset 0x%" PRIx32,
+ "DW_RLE_base_addressx encoding at offset 0x%" PRIx64,
PreviousOffset);
break;
}
case dwarf::DW_RLE_startx_endx:
return createStringError(errc::not_supported,
"unsupported rnglists encoding DW_RLE_startx_endx at "
- "offset 0x%" PRIx32,
+ "offset 0x%" PRIx64,
*OffsetPtr - 1);
case dwarf::DW_RLE_startx_length: {
- uint32_t PreviousOffset = *OffsetPtr - 1;
+ uint64_t PreviousOffset = *OffsetPtr - 1;
Value0 = Data.getULEB128(OffsetPtr);
Value1 = Data.getULEB128(OffsetPtr);
if (End < *OffsetPtr)
return createStringError(
errc::invalid_argument,
"read past end of table when reading "
- "DW_RLE_startx_length encoding at offset 0x%" PRIx32,
+ "DW_RLE_startx_length encoding at offset 0x%" PRIx64,
PreviousOffset);
break;
}
case dwarf::DW_RLE_offset_pair: {
- uint32_t PreviousOffset = *OffsetPtr - 1;
+ uint64_t PreviousOffset = *OffsetPtr - 1;
Value0 = Data.getULEB128(OffsetPtr);
Value1 = Data.getULEB128(OffsetPtr);
if (End < *OffsetPtr)
return createStringError(errc::invalid_argument,
"read past end of table when reading "
- "DW_RLE_offset_pair encoding at offset 0x%" PRIx32,
+ "DW_RLE_offset_pair encoding at offset 0x%" PRIx64,
PreviousOffset);
break;
}
@@ -74,7 +74,7 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
if ((End - *OffsetPtr) < Data.getAddressSize())
return createStringError(errc::invalid_argument,
"insufficient space remaining in table for "
- "DW_RLE_base_address encoding at offset 0x%" PRIx32,
+ "DW_RLE_base_address encoding at offset 0x%" PRIx64,
*OffsetPtr - 1);
Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
break;
@@ -84,27 +84,27 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End,
return createStringError(errc::invalid_argument,
"insufficient space remaining in table for "
"DW_RLE_start_end encoding "
- "at offset 0x%" PRIx32,
+ "at offset 0x%" PRIx64,
*OffsetPtr - 1);
Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
Value1 = Data.getRelocatedAddress(OffsetPtr);
break;
}
case dwarf::DW_RLE_start_length: {
- uint32_t PreviousOffset = *OffsetPtr - 1;
+ uint64_t PreviousOffset = *OffsetPtr - 1;
Value0 = Data.getRelocatedAddress(OffsetPtr, &SectionIndex);
Value1 = Data.getULEB128(OffsetPtr);
if (End < *OffsetPtr)
return createStringError(errc::invalid_argument,
"read past end of table when reading "
- "DW_RLE_start_length encoding at offset 0x%" PRIx32,
+ "DW_RLE_start_length encoding at offset 0x%" PRIx64,
PreviousOffset);
break;
}
default:
return createStringError(errc::not_supported,
"unknown rnglists encoding 0x%" PRIx32
- " at offset 0x%" PRIx32,
+ " at offset 0x%" PRIx64,
uint32_t(Encoding), *OffsetPtr - 1);
}
@@ -187,7 +187,7 @@ void RangeListEntry::dump(
if (DumpOpts.Verbose) {
// Print the section offset in verbose mode.
- OS << format("0x%8.8" PRIx32 ":", Offset);
+ OS << format("0x%8.8" PRIx64 ":", Offset);
auto EncodingString = dwarf::RangeListEncodingString(EntryKind);
// Unsupported encodings should have been reported during parsing.
assert(!EncodingString.empty() && "Unknown range entry encoding");
diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp
index d638dc4239f4..cec194e8b6b3 100644
--- a/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -21,6 +21,7 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatAdapters.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/WithColor.h"
@@ -91,21 +92,29 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
}
FormValue.dump(OS, DumpOpts);
+ const auto &DumpLL = [&](auto ExpectedLL) {
+ if (ExpectedLL) {
+ uint64_t BaseAddr = 0;
+ if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
+ BaseAddr = BA->Address;
+ auto LLDumpOpts = DumpOpts;
+ LLDumpOpts.Verbose = false;
+ ExpectedLL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(),
+ MRI, U, LLDumpOpts, Indent);
+ } else {
+ OS << '\n';
+ OS.indent(Indent);
+ OS << formatv("error extracting location list: {0}",
+ fmt_consume(ExpectedLL.takeError()));
+ }
+ };
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
- uint32_t Offset = *FormValue.getAsSectionOffset();
+ uint64_t Offset = *FormValue.getAsSectionOffset();
if (!U->isDWOUnit() && !U->getLocSection()->Data.empty()) {
DWARFDebugLoc DebugLoc;
DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
Obj.getAddressSize());
- auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
- if (LL) {
- uint64_t BaseAddr = 0;
- if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
- BaseAddr = BA->Address;
- LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U,
- BaseAddr, Indent);
- } else
- OS << "error extracting location list.";
+ DumpLL(DebugLoc.parseOneLocationList(Data, &Offset));
return;
}
@@ -121,18 +130,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
// Modern locations list (.debug_loclists) are used starting from v5.
// Ideally we should take the version from the .debug_loclists section
// header, but using CU's version for simplicity.
- auto LL = DWARFDebugLoclists::parseOneLocationList(
- Data, &Offset, UseLocLists ? U->getVersion() : 4);
-
- uint64_t BaseAddr = 0;
- if (Optional<object::SectionedAddress> BA = U->getBaseAddress())
- BaseAddr = BA->Address;
-
- if (LL)
- LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI,
- U, Indent);
- else
- OS << "error extracting location list.";
+ DumpLL(DWARFDebugLoclists::parseOneLocationList(
+ Data, &Offset, UseLocLists ? U->getVersion() : 4));
}
}
}
@@ -264,7 +263,7 @@ static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) {
}
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
- uint32_t *OffsetPtr, dwarf::Attribute Attr,
+ uint64_t *OffsetPtr, dwarf::Attribute Attr,
dwarf::Form Form, unsigned Indent,
DIDumpOptions DumpOpts) {
if (!Die.isValid())
@@ -568,8 +567,8 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
if (!isValid())
return;
DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
- const uint32_t Offset = getOffset();
- uint32_t offset = Offset;
+ const uint64_t Offset = getOffset();
+ uint64_t offset = Offset;
if (DumpOpts.ShowParents) {
DIDumpOptions ParentDumpOpts = DumpOpts;
ParentDumpOpts.ShowParents = false;
@@ -581,7 +580,7 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
uint32_t abbrCode = debug_info_data.getULEB128(&offset);
if (DumpOpts.ShowAddresses)
WithColor(OS, HighlightColor::Address).get()
- << format("\n0x%8.8x: ", Offset);
+ << format("\n0x%8.8" PRIx64 ": ", Offset);
if (abbrCode) {
auto AbbrevDecl = getAbbreviationDeclarationPtr();
@@ -685,7 +684,7 @@ void DWARFDie::attribute_iterator::updateForIndex(
AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
// Add the previous byte size of any previous attribute value.
AttrValue.Offset += AttrValue.ByteSize;
- uint32_t ParseOffset = AttrValue.Offset;
+ uint64_t ParseOffset = AttrValue.Offset;
auto U = Die.getDwarfUnit();
assert(U && "Die must have valid DWARF unit");
AttrValue.Value = DWARFFormValue::createFromUnit(
@@ -733,6 +732,7 @@ bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr) {
case DW_AT_call_data_value:
// Extensions.
case DW_AT_GNU_call_site_value:
+ case DW_AT_GNU_call_site_target:
return true;
default:
return false;
diff --git a/lib/DebugInfo/DWARF/DWARFExpression.cpp b/lib/DebugInfo/DWARF/DWARFExpression.cpp
index 470d4b5364b4..5009b1b7b412 100644
--- a/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -119,7 +119,7 @@ static uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) {
}
bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version,
- uint8_t AddressSize, uint32_t Offset) {
+ uint8_t AddressSize, uint64_t Offset) {
Opcode = Data.getU8(&Offset);
Desc = getOpDesc(Opcode);
@@ -218,9 +218,8 @@ static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode,
else
DwarfRegNum = Opcode - DW_OP_reg0;
- int LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH);
- if (LLVMRegNum >= 0) {
- if (const char *RegName = MRI->getName(LLVMRegNum)) {
+ if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) {
+ if (const char *RegName = MRI->getName(*LLVMRegNum)) {
if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
Opcode == DW_OP_bregx)
OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
@@ -263,7 +262,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
if (Size == Operation::BaseTypeRef && U) {
auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
- OS << format(" (0x%08x)", U->getOffset() + Operands[Operand]);
+ OS << format(" (0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
if (auto Name = Die.find(dwarf::DW_AT_name))
OS << " \"" << Name->getAsCString() << "\"";
} else {
@@ -271,7 +270,7 @@ bool DWARFExpression::Operation::print(raw_ostream &OS,
Operands[Operand]);
}
} else if (Size == Operation::SizeBlock) {
- uint32_t Offset = Operands[Operand];
+ uint64_t Offset = Operands[Operand];
for (unsigned i = 0; i < Operands[Operand - 1]; ++i)
OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
} else {
@@ -290,7 +289,7 @@ void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
uint32_t EntryValExprSize = 0;
for (auto &Op : *this) {
if (!Op.print(OS, this, RegInfo, U, IsEH)) {
- uint32_t FailOffset = Op.getEndOffset();
+ uint64_t FailOffset = Op.getEndOffset();
while (FailOffset < Data.getData().size())
OS << format(" %02x", Data.getU8(&FailOffset));
return;
diff --git a/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 290d35511cdb..26090638b34c 100644
--- a/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -98,7 +98,7 @@ DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F,
}
DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U,
- uint32_t *OffsetPtr) {
+ uint64_t *OffsetPtr) {
DWARFFormValue FormValue(F);
FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
U->getFormParams(), U);
@@ -106,7 +106,7 @@ DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U,
}
bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
- uint32_t *OffsetPtr,
+ uint64_t *OffsetPtr,
const dwarf::FormParams Params) {
bool Indirect = false;
do {
@@ -234,7 +234,7 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
}
bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
- uint32_t *OffsetPtr, dwarf::FormParams FP,
+ uint64_t *OffsetPtr, dwarf::FormParams FP,
const DWARFContext *Ctx,
const DWARFUnit *CU) {
if (!Ctx && CU)
@@ -590,7 +590,7 @@ Optional<const char *> DWARFFormValue::getAsCString() const {
// FIXME: Add support for DW_FORM_GNU_strp_alt
if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
return None;
- uint32_t Offset = Value.uval;
+ uint64_t Offset = Value.uval;
if (Form == DW_FORM_line_strp) {
// .debug_line_str is tracked in the Context.
if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
@@ -624,6 +624,7 @@ Optional<uint64_t> DWARFFormValue::getAsAddress() const {
return SA->Address;
return None;
}
+
Optional<object::SectionedAddress>
DWARFFormValue::getAsSectionedAddress() const {
if (!isFormClass(FC_Address))
diff --git a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index f5f975578082..252b58e5a591 100644
--- a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -112,7 +112,7 @@ void DWARFGdbIndex::dump(raw_ostream &OS) {
}
bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
// Only version 7 is supported at this moment.
Version = Data.getU32(&Offset);
diff --git a/lib/DebugInfo/DWARF/DWARFListTable.cpp b/lib/DebugInfo/DWARF/DWARFListTable.cpp
index e38e706227da..269ea9f79a6e 100644
--- a/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ b/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -16,33 +16,42 @@
using namespace llvm;
Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
- uint32_t *OffsetPtr) {
+ uint64_t *OffsetPtr) {
HeaderOffset = *OffsetPtr;
// Read and verify the length field.
if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, sizeof(uint32_t)))
return createStringError(errc::invalid_argument,
"section is not large enough to contain a "
- "%s table length at offset 0x%" PRIx32,
+ "%s table length at offset 0x%" PRIx64,
SectionName.data(), *OffsetPtr);
- // TODO: Add support for DWARF64.
- HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
- if (HeaderData.Length == 0xffffffffu)
- return createStringError(errc::not_supported,
- "DWARF64 is not supported in %s at offset 0x%" PRIx32,
- SectionName.data(), HeaderOffset);
Format = dwarf::DwarfFormat::DWARF32;
- if (HeaderData.Length + sizeof(uint32_t) < sizeof(Header))
+ uint8_t OffsetByteSize = 4;
+ HeaderData.Length = Data.getRelocatedValue(4, OffsetPtr);
+ if (HeaderData.Length == dwarf::DW_LENGTH_DWARF64) {
+ Format = dwarf::DwarfFormat::DWARF64;
+ OffsetByteSize = 8;
+ HeaderData.Length = Data.getU64(OffsetPtr);
+ } else if (HeaderData.Length >= dwarf::DW_LENGTH_lo_reserved) {
+ return createStringError(errc::invalid_argument,
+ "%s table at offset 0x%" PRIx64
+ " has unsupported reserved unit length of value 0x%8.8" PRIx64,
+ SectionName.data(), HeaderOffset, HeaderData.Length);
+ }
+ uint64_t FullLength =
+ HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
+ assert(FullLength == length());
+ if (FullLength < getHeaderSize(Format))
return createStringError(errc::invalid_argument,
- "%s table at offset 0x%" PRIx32
- " has too small length (0x%" PRIx32
+ "%s table at offset 0x%" PRIx64
+ " has too small length (0x%" PRIx64
") to contain a complete header",
- SectionName.data(), HeaderOffset, length());
- uint32_t End = HeaderOffset + length();
- if (!Data.isValidOffsetForDataOfSize(HeaderOffset, End - HeaderOffset))
+ SectionName.data(), HeaderOffset, FullLength);
+ uint64_t End = HeaderOffset + FullLength;
+ if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))
return createStringError(errc::invalid_argument,
"section is not large enough to contain a %s table "
- "of length 0x%" PRIx32 " at offset 0x%" PRIx32,
- SectionName.data(), length(), HeaderOffset);
+ "of length 0x%" PRIx64 " at offset 0x%" PRIx64,
+ SectionName.data(), FullLength, HeaderOffset);
HeaderData.Version = Data.getU16(OffsetPtr);
HeaderData.AddrSize = Data.getU8(OffsetPtr);
@@ -53,35 +62,35 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
if (HeaderData.Version != 5)
return createStringError(errc::invalid_argument,
"unrecognised %s table version %" PRIu16
- " in table at offset 0x%" PRIx32,
+ " in table at offset 0x%" PRIx64,
SectionName.data(), HeaderData.Version, HeaderOffset);
if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
return createStringError(errc::not_supported,
- "%s table at offset 0x%" PRIx32
+ "%s table at offset 0x%" PRIx64
" has unsupported address size %" PRIu8,
SectionName.data(), HeaderOffset, HeaderData.AddrSize);
if (HeaderData.SegSize != 0)
return createStringError(errc::not_supported,
- "%s table at offset 0x%" PRIx32
+ "%s table at offset 0x%" PRIx64
" has unsupported segment selector size %" PRIu8,
SectionName.data(), HeaderOffset, HeaderData.SegSize);
- if (End < HeaderOffset + sizeof(HeaderData) +
- HeaderData.OffsetEntryCount * sizeof(uint32_t))
+ if (End < HeaderOffset + getHeaderSize(Format) +
+ HeaderData.OffsetEntryCount * OffsetByteSize)
return createStringError(errc::invalid_argument,
- "%s table at offset 0x%" PRIx32 " has more offset entries (%" PRIu32
+ "%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32
") than there is space for",
SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
Data.setAddressSize(HeaderData.AddrSize);
for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I)
- Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr));
+ Offsets.push_back(Data.getRelocatedValue(OffsetByteSize, OffsetPtr));
return Error::success();
}
void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
if (DumpOpts.Verbose)
- OS << format("0x%8.8" PRIx32 ": ", HeaderOffset);
+ OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
OS << format(
- "%s list header: length = 0x%8.8" PRIx32 ", version = 0x%4.4" PRIx16 ", "
+ "%s list header: length = 0x%8.8" PRIx64 ", version = 0x%4.4" PRIx16 ", "
"addr_size = 0x%2.2" PRIx8 ", seg_size = 0x%2.2" PRIx8
", offset_entry_count = "
"0x%8.8" PRIx32 "\n",
@@ -91,18 +100,17 @@ void DWARFListTableHeader::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
if (HeaderData.OffsetEntryCount > 0) {
OS << "offsets: [";
for (const auto &Off : Offsets) {
- OS << format("\n0x%8.8" PRIx32, Off);
+ OS << format("\n0x%8.8" PRIx64, Off);
if (DumpOpts.Verbose)
- OS << format(" => 0x%8.8" PRIx32,
- Off + HeaderOffset + sizeof(HeaderData));
+ OS << format(" => 0x%8.8" PRIx64,
+ Off + HeaderOffset + getHeaderSize(Format));
}
OS << "\n]\n";
}
}
-uint32_t DWARFListTableHeader::length() const {
+uint64_t DWARFListTableHeader::length() const {
if (HeaderData.Length == 0)
return 0;
- // TODO: DWARF64 support.
- return HeaderData.Length + sizeof(uint32_t);
+ return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
}
diff --git a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index 844920ba5b11..bb81090ba25c 100644
--- a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -24,21 +24,23 @@ void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
if (DumpOpts.SummarizeTypes) {
OS << "name = '" << Name << "'"
<< " type_signature = " << format("0x%016" PRIx64, getTypeHash())
- << " length = " << format("0x%08x", getLength()) << '\n';
+ << " length = " << format("0x%08" PRIx64, getLength()) << '\n';
return;
}
- OS << format("0x%08x", getOffset()) << ": Type Unit:"
- << " length = " << format("0x%08x", getLength())
+ OS << format("0x%08" PRIx64, getOffset()) << ": Type Unit:"
+ << " length = " << format("0x%08" PRIx64, getLength())
<< " version = " << format("0x%04x", getVersion());
if (getVersion() >= 5)
OS << " unit_type = " << dwarf::UnitTypeString(getUnitType());
- OS << " abbr_offset = " << format("0x%04x", getAbbreviations()->getOffset())
+ OS << " abbr_offset = "
+ << format("0x%04" PRIx64, getAbbreviations()->getOffset())
<< " addr_size = " << format("0x%02x", getAddressByteSize())
<< " name = '" << Name << "'"
<< " type_signature = " << format("0x%016" PRIx64, getTypeHash())
- << " type_offset = " << format("0x%04x", getTypeOffset())
- << " (next unit at " << format("0x%08x", getNextUnitOffset()) << ")\n";
+ << " type_offset = " << format("0x%04" PRIx64, getTypeOffset())
+ << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
+ << ")\n";
if (DWARFDie TU = getUnitDIE(false))
TU.dump(OS, 0, DumpOpts);
diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp
index b74acf60c747..a56402a707ad 100644
--- a/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -37,9 +37,9 @@ void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
const DWARFSection &Section,
DWARFSectionKind SectionKind) {
const DWARFObject &D = C.getDWARFObj();
- addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
- &D.getLocSection(), D.getStringSection(),
- D.getStringOffsetSection(), &D.getAddrSection(),
+ addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
+ &D.getLocSection(), D.getStrSection(),
+ D.getStrOffsetsSection(), &D.getAddrSection(),
D.getLineSection(), D.isLittleEndian(), false, false,
SectionKind);
}
@@ -49,9 +49,9 @@ void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
DWARFSectionKind SectionKind,
bool Lazy) {
const DWARFObject &D = C.getDWARFObj();
- addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
- &D.getLocDWOSection(), D.getStringDWOSection(),
- D.getStringOffsetDWOSection(), &D.getAddrSection(),
+ addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
+ &D.getLocDWOSection(), D.getStrDWOSection(),
+ D.getStrOffsetsDWOSection(), &D.getAddrSection(),
D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
SectionKind);
}
@@ -66,7 +66,7 @@ void DWARFUnitVector::addUnitsImpl(
// Lazy initialization of Parser, now that we have all section info.
if (!Parser) {
Parser = [=, &Context, &Obj, &Section, &SOS,
- &LS](uint32_t Offset, DWARFSectionKind SectionKind,
+ &LS](uint64_t Offset, DWARFSectionKind SectionKind,
const DWARFSection *CurSection,
const DWARFUnitIndex::Entry *IndexEntry)
-> std::unique_ptr<DWARFUnit> {
@@ -83,11 +83,11 @@ void DWARFUnitVector::addUnitsImpl(
return nullptr;
std::unique_ptr<DWARFUnit> U;
if (Header.isTypeUnit())
- U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
+ U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
RS, LocSection, SS, SOS, AOS, LS,
LE, IsDWO, *this);
else
- U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
+ U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
DA, RS, LocSection, SS, SOS,
AOS, LS, LE, IsDWO, *this);
return U;
@@ -101,7 +101,7 @@ void DWARFUnitVector::addUnitsImpl(
// within a section, although not necessarily within the object file,
// even if we do lazy parsing.
auto I = this->begin();
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
while (Data.isValidOffset(Offset)) {
if (I != this->end() &&
(&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
@@ -126,11 +126,11 @@ DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
return this->insert(I, std::move(Unit))->get();
}
-DWARFUnit *DWARFUnitVector::getUnitForOffset(uint32_t Offset) const {
+DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const {
auto end = begin() + getNumInfoUnits();
auto *CU =
std::upper_bound(begin(), end, Offset,
- [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+ [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
return LHS < RHS->getNextUnitOffset();
});
if (CU != end && (*CU)->getOffset() <= Offset)
@@ -149,7 +149,7 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
auto *CU =
std::upper_bound(begin(), end, CUOff->Offset,
- [](uint32_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+ [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
return LHS < RHS->getNextUnitOffset();
});
if (CU != end && (*CU)->getOffset() <= Offset)
@@ -209,7 +209,7 @@ DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
if (I != R.end() && std::next(I) == R.end())
return (*I)->getAddrOffsetSectionItem(Index);
}
- uint32_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
+ uint64_t Offset = AddrOffsetSectionBase + Index * getAddressByteSize();
if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
return None;
DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
@@ -223,7 +223,7 @@ Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
if (!StringOffsetsTableContribution)
return None;
unsigned ItemSize = getDwarfStringOffsetsByteSize();
- uint32_t Offset = getStringOffsetsBase() + Index * ItemSize;
+ uint64_t Offset = getStringOffsetsBase() + Index * ItemSize;
if (StringOffsetSection.Data.size() < Offset + ItemSize)
return None;
DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
@@ -233,7 +233,7 @@ Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
bool DWARFUnitHeader::extract(DWARFContext &Context,
const DWARFDataExtractor &debug_info,
- uint32_t *offset_ptr,
+ uint64_t *offset_ptr,
DWARFSectionKind SectionKind,
const DWARFUnitIndex *Index,
const DWARFUnitIndex::Entry *Entry) {
@@ -243,11 +243,9 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
IndexEntry = Index->getFromOffset(*offset_ptr);
Length = debug_info.getRelocatedValue(4, offset_ptr);
FormParams.Format = DWARF32;
- unsigned SizeOfLength = 4;
- if (Length == 0xffffffff) {
+ if (Length == dwarf::DW_LENGTH_DWARF64) {
Length = debug_info.getU64(offset_ptr);
FormParams.Format = DWARF64;
- SizeOfLength = 8;
}
FormParams.Version = debug_info.getU16(offset_ptr);
if (FormParams.Version >= 5) {
@@ -277,7 +275,8 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
}
if (isTypeUnit()) {
TypeHash = debug_info.getU64(offset_ptr);
- TypeOffset = debug_info.getU32(offset_ptr);
+ TypeOffset =
+ debug_info.getUnsigned(offset_ptr, FormParams.getDwarfOffsetByteSize());
} else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
DWOId = debug_info.getU64(offset_ptr);
@@ -290,7 +289,8 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
bool TypeOffsetOK =
!isTypeUnit()
? true
- : TypeOffset >= Size && TypeOffset < getLength() + SizeOfLength;
+ : TypeOffset >= Size &&
+ TypeOffset < getLength() + getUnitLengthFieldByteSize();
bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
bool AddrSizeOK = getAddressByteSize() == 4 || getAddressByteSize() == 8;
@@ -306,16 +306,18 @@ bool DWARFUnitHeader::extract(DWARFContext &Context,
// Parse the rangelist table header, including the optional array of offsets
// following it (DWARF v5 and later).
static Expected<DWARFDebugRnglistTable>
-parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
- // TODO: Support DWARF64
+parseRngListTableHeader(DWARFDataExtractor &DA, uint64_t Offset,
+ DwarfFormat Format) {
// We are expected to be called with Offset 0 or pointing just past the table
- // header, which is 12 bytes long for DWARF32.
+ // header. Correct Offset in the latter case so that it points to the start
+ // of the header.
if (Offset > 0) {
- if (Offset < 12U)
+ uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Format);
+ if (Offset < HeaderSize)
return createStringError(errc::invalid_argument, "Did not detect a valid"
- " range list table with base = 0x%" PRIu32,
+ " range list table with base = 0x%" PRIx64 "\n",
Offset);
- Offset -= 12U;
+ Offset -= HeaderSize;
}
llvm::DWARFDebugRnglistTable Table;
if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))
@@ -323,13 +325,13 @@ parseRngListTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
return Table;
}
-Error DWARFUnit::extractRangeList(uint32_t RangeListOffset,
+Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
DWARFDebugRangeList &RangeList) const {
// Require that compile unit is extracted.
assert(!DieArray.empty());
DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
isLittleEndian, getAddressByteSize());
- uint32_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
+ uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
return RangeList.extract(RangesData, &ActualRangeListOffset);
}
@@ -354,8 +356,8 @@ void DWARFUnit::extractDIEsToVector(
// Set the offset to that of the first DIE and calculate the start of the
// next compilation unit header.
- uint32_t DIEOffset = getOffset() + getHeaderSize();
- uint32_t NextCUOffset = getNextUnitOffset();
+ uint64_t DIEOffset = getOffset() + getHeaderSize();
+ uint64_t NextCUOffset = getNextUnitOffset();
DWARFDebugInfoEntry DIE;
DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
uint32_t Depth = 0;
@@ -396,90 +398,98 @@ void DWARFUnit::extractDIEsToVector(
// unit header).
if (DIEOffset > NextCUOffset)
WithColor::warning() << format("DWARF compile unit extends beyond its "
- "bounds cu 0x%8.8x at 0x%8.8x\n",
+ "bounds cu 0x%8.8" PRIx64 " "
+ "at 0x%8.8" PRIx64 "\n",
getOffset(), DIEOffset);
}
-size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
+void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
+ if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
+ WithColor::error() << toString(std::move(e));
+}
+
+Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
if ((CUDieOnly && !DieArray.empty()) ||
DieArray.size() > 1)
- return 0; // Already parsed.
+ return Error::success(); // Already parsed.
bool HasCUDie = !DieArray.empty();
extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
if (DieArray.empty())
- return 0;
+ return Error::success();
// If CU DIE was just parsed, copy several attribute values from it.
- if (!HasCUDie) {
- DWARFDie UnitDie = getUnitDIE();
- if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
- Header.setDWOId(*DWOId);
- if (!IsDWO) {
- assert(AddrOffsetSectionBase == 0);
- assert(RangeSectionBase == 0);
- AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0);
- if (!AddrOffsetSectionBase)
- AddrOffsetSectionBase =
- toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
- RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
- }
-
- // In general, in DWARF v5 and beyond we derive the start of the unit's
- // contribution to the string offsets table from the unit DIE's
- // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
- // attribute, so we assume that there is a contribution to the string
- // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
- // In both cases we need to determine the format of the contribution,
- // which may differ from the unit's format.
- DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
- isLittleEndian, 0);
- if (IsDWO || getVersion() >= 5) {
- auto StringOffsetOrError =
- IsDWO ? determineStringOffsetsTableContributionDWO(DA)
- : determineStringOffsetsTableContribution(DA);
- if (!StringOffsetOrError) {
- WithColor::error() << "invalid contribution to string offsets table in section .debug_str_offsets[.dwo]: "
- << toString(StringOffsetOrError.takeError()) << '\n';
- } else {
- StringOffsetsTableContribution = *StringOffsetOrError;
- }
- }
+ if (HasCUDie)
+ return Error::success();
+
+ DWARFDie UnitDie(this, &DieArray[0]);
+ if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
+ Header.setDWOId(*DWOId);
+ if (!IsDWO) {
+ assert(AddrOffsetSectionBase == 0);
+ assert(RangeSectionBase == 0);
+ AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base), 0);
+ if (!AddrOffsetSectionBase)
+ AddrOffsetSectionBase =
+ toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
+ RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+ }
- // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
- // describe address ranges.
- if (getVersion() >= 5) {
- if (IsDWO)
- setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
- else
- setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
- toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
- if (RangeSection->Data.size()) {
- // Parse the range list table header. Individual range lists are
- // extracted lazily.
- DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
- isLittleEndian, 0);
- if (auto TableOrError =
- parseRngListTableHeader(RangesDA, RangeSectionBase))
- RngListTable = TableOrError.get();
- else
- WithColor::error() << "parsing a range list table: "
- << toString(TableOrError.takeError())
- << '\n';
-
- // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
- // Adjust RangeSectionBase to point past the table header.
- if (IsDWO && RngListTable)
- RangeSectionBase = RngListTable->getHeaderSize();
- }
- }
+ // In general, in DWARF v5 and beyond we derive the start of the unit's
+ // contribution to the string offsets table from the unit DIE's
+ // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
+ // attribute, so we assume that there is a contribution to the string
+ // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
+ // In both cases we need to determine the format of the contribution,
+ // which may differ from the unit's format.
+ DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+ isLittleEndian, 0);
+ if (IsDWO || getVersion() >= 5) {
+ auto StringOffsetOrError =
+ IsDWO ? determineStringOffsetsTableContributionDWO(DA)
+ : determineStringOffsetsTableContribution(DA);
+ if (!StringOffsetOrError)
+ return createStringError(errc::invalid_argument,
+ "invalid reference to or invalid content in "
+ ".debug_str_offsets[.dwo]: " +
+ toString(StringOffsetOrError.takeError()));
+
+ StringOffsetsTableContribution = *StringOffsetOrError;
+ }
- // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
- // skeleton CU DIE, so that DWARF users not aware of it are not broken.
+ // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
+ // describe address ranges.
+ if (getVersion() >= 5) {
+ if (IsDWO)
+ setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
+ else
+ setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
+ toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0));
+ if (RangeSection->Data.size()) {
+ // Parse the range list table header. Individual range lists are
+ // extracted lazily.
+ DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
+ isLittleEndian, 0);
+ auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase,
+ Header.getFormat());
+ if (!TableOrError)
+ return createStringError(errc::invalid_argument,
+ "parsing a range list table: " +
+ toString(TableOrError.takeError()));
+
+ RngListTable = TableOrError.get();
+
+ // In a split dwarf unit, there is no DW_AT_rnglists_base attribute.
+ // Adjust RangeSectionBase to point past the table header.
+ if (IsDWO && RngListTable)
+ RangeSectionBase = RngListTable->getHeaderSize();
}
+ }
- return DieArray.size();
+ // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
+ // skeleton CU DIE, so that DWARF users not aware of it are not broken.
+ return Error::success();
}
bool DWARFUnit::parseDWO() {
@@ -517,7 +527,8 @@ bool DWARFUnit::parseDWO() {
DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(), 0);
DWARFDataExtractor RangesDA(Context.getDWARFObj(), *RangeSection,
isLittleEndian, 0);
- if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase))
+ if (auto TableOrError = parseRngListTableHeader(RangesDA, RangeSectionBase,
+ Header.getFormat()))
DWO->RngListTable = TableOrError.get();
else
WithColor::error() << "parsing a range list table: "
@@ -541,7 +552,7 @@ void DWARFUnit::clearDIEs(bool KeepCUDie) {
}
Expected<DWARFAddressRangesVector>
-DWARFUnit::findRnglistFromOffset(uint32_t Offset) {
+DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
if (getVersion() <= 4) {
DWARFDebugRangeList RangeList;
if (Error E = extractRangeList(Offset, RangeList))
@@ -569,9 +580,9 @@ DWARFUnit::findRnglistFromIndex(uint32_t Index) {
if (RngListTable)
return createStringError(errc::invalid_argument,
"invalid range list table index %d", Index);
- else
- return createStringError(errc::invalid_argument,
- "missing or invalid range list table");
+
+ return createStringError(errc::invalid_argument,
+ "missing or invalid range list table");
}
Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
@@ -780,11 +791,11 @@ StrOffsetsContributionDescriptor::validateContributionSize(
// Look for a DWARF64-formatted contribution to the string offsets table
// starting at a given offset and record it in a descriptor.
static Expected<StrOffsetsContributionDescriptor>
-parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
+parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
if (!DA.isValidOffsetForDataOfSize(Offset, 16))
return createStringError(errc::invalid_argument, "section offset exceeds section size");
- if (DA.getU32(&Offset) != 0xffffffff)
+ if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64)
return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit");
uint64_t Size = DA.getU64(&Offset);
@@ -798,12 +809,12 @@ parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
// Look for a DWARF32-formatted contribution to the string offsets table
// starting at a given offset and record it in a descriptor.
static Expected<StrOffsetsContributionDescriptor>
-parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) {
+parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
if (!DA.isValidOffsetForDataOfSize(Offset, 8))
return createStringError(errc::invalid_argument, "section offset exceeds section size");
uint32_t ContributionSize = DA.getU32(&Offset);
- if (ContributionSize >= 0xfffffff0)
+ if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
return createStringError(errc::invalid_argument, "invalid length");
uint8_t Version = DA.getU16(&Offset);
@@ -823,7 +834,7 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
case dwarf::DwarfFormat::DWARF64: {
if (Offset < 16)
return createStringError(errc::invalid_argument, "insufficient space for 64 bit header prefix");
- auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16);
+ auto DescOrError = parseDWARF64StringOffsetsTableHeader(DA, Offset - 16);
if (!DescOrError)
return DescOrError.takeError();
Desc = *DescOrError;
@@ -832,7 +843,7 @@ parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA,
case dwarf::DwarfFormat::DWARF32: {
if (Offset < 8)
return createStringError(errc::invalid_argument, "insufficient space for 32 bit header prefix");
- auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8);
+ auto DescOrError = parseDWARF32StringOffsetsTableHeader(DA, Offset - 8);
if (!DescOrError)
return DescOrError.takeError();
Desc = *DescOrError;
diff --git a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index 047c63461ccf..f29c1e6cc5c7 100644
--- a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -18,7 +18,7 @@
using namespace llvm;
bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
- uint32_t *OffsetPtr) {
+ uint64_t *OffsetPtr) {
if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
return false;
Version = IndexData.getU32(OffsetPtr);
@@ -45,7 +45,7 @@ bool DWARFUnitIndex::parse(DataExtractor IndexData) {
}
bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
if (!Header.parse(IndexData, &Offset))
return false;
@@ -54,10 +54,10 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
(2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
return false;
- Rows = llvm::make_unique<Entry[]>(Header.NumBuckets);
+ Rows = std::make_unique<Entry[]>(Header.NumBuckets);
auto Contribs =
- llvm::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
- ColumnKinds = llvm::make_unique<DWARFSectionKind[]>(Header.NumColumns);
+ std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
+ ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns);
// Read Hash Table of Signatures
for (unsigned i = 0; i != Header.NumBuckets; ++i)
@@ -70,7 +70,7 @@ bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
continue;
Rows[i].Index = this;
Rows[i].Contributions =
- llvm::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
+ std::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
Contribs[Index - 1] = Rows[i].Contributions.get();
}
diff --git a/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index c2b3189514a8..bf499b6ee092 100644
--- a/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -34,11 +34,11 @@ DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
if (Pos != End) {
if (Pos->intersects(R))
- return Pos;
+ return std::move(Pos);
if (Pos != Begin) {
auto Iter = Pos - 1;
if (Iter->intersects(R))
- return Iter;
+ return std::move(Iter);
}
}
@@ -98,7 +98,7 @@ bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
}
bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
- uint32_t *Offset, unsigned UnitIndex,
+ uint64_t *Offset, unsigned UnitIndex,
uint8_t &UnitType, bool &isUnitDWARF64) {
uint64_t AbbrOffset, Length;
uint8_t AddrSize = 0;
@@ -111,9 +111,9 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
bool ValidType = true;
bool ValidAbbrevOffset = true;
- uint32_t OffsetStart = *Offset;
+ uint64_t OffsetStart = *Offset;
Length = DebugInfoData.getU32(Offset);
- if (Length == UINT32_MAX) {
+ if (Length == dwarf::DW_LENGTH_DWARF64) {
Length = DebugInfoData.getU64(Offset);
isUnitDWARF64 = true;
}
@@ -139,7 +139,7 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData,
if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
!ValidType) {
Success = false;
- error() << format("Units[%d] - start offset: 0x%08x \n", UnitIndex,
+ error() << format("Units[%d] - start offset: 0x%08" PRIx64 " \n", UnitIndex,
OffsetStart);
if (!ValidLength)
note() << "The length for this unit is too "
@@ -203,7 +203,7 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
}
unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
- if (Die.getTag() != DW_TAG_call_site)
+ if (Die.getTag() != DW_TAG_call_site && Die.getTag() != DW_TAG_GNU_call_site)
return 0;
DWARFDie Curr = Die.getParent();
@@ -223,7 +223,9 @@ unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
Optional<DWARFFormValue> CallAttr =
Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_calls,
- DW_AT_call_all_tail_calls});
+ DW_AT_call_all_tail_calls, DW_AT_GNU_all_call_sites,
+ DW_AT_GNU_all_source_call_sites,
+ DW_AT_GNU_all_tail_call_sites});
if (!CallAttr) {
error() << "Subprogram with call site entry has no DW_AT_call attribute:";
Curr.dump(OS);
@@ -273,7 +275,7 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
const DWARFObject &DObj = DCtx.getDWARFObj();
DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
unsigned NumDebugInfoErrors = 0;
- uint32_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
+ uint64_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
uint8_t UnitType = 0;
bool isUnitDWARF64 = false;
bool isHeaderChainValid = true;
@@ -294,10 +296,10 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
switch (UnitType) {
case dwarf::DW_UT_type:
case dwarf::DW_UT_split_type: {
- Unit = TypeUnitVector.addUnit(llvm::make_unique<DWARFTypeUnit>(
- DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
- &DObj.getLocSection(), DObj.getStringSection(),
- DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+ Unit = TypeUnitVector.addUnit(std::make_unique<DWARFTypeUnit>(
+ DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
+ &DObj.getLocSection(), DObj.getStrSection(),
+ DObj.getStrOffsetsSection(), &DObj.getAppleObjCSection(),
DObj.getLineSection(), DCtx.isLittleEndian(), false,
TypeUnitVector));
break;
@@ -308,10 +310,10 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
case dwarf::DW_UT_partial:
// UnitType = 0 means that we are verifying a compile unit in DWARF v4.
case 0: {
- Unit = CompileUnitVector.addUnit(llvm::make_unique<DWARFCompileUnit>(
- DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
- &DObj.getLocSection(), DObj.getStringSection(),
- DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
+ Unit = CompileUnitVector.addUnit(std::make_unique<DWARFCompileUnit>(
+ DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
+ &DObj.getLocSection(), DObj.getStrSection(),
+ DObj.getStrOffsetsSection(), &DObj.getAppleObjCSection(),
DObj.getLineSection(), DCtx.isLittleEndian(), false,
CompileUnitVector));
break;
@@ -449,7 +451,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
case DW_AT_ranges:
// Make sure the offset in the DW_AT_ranges attribute is valid.
if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
- if (*SectionOffset >= DObj.getRangeSection().Data.size())
+ if (*SectionOffset >= DObj.getRangesSection().Data.size())
ReportError("DW_AT_ranges offset is beyond .debug_ranges bounds:");
break;
}
@@ -466,9 +468,9 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
ReportError("DIE has invalid DW_AT_stmt_list encoding:");
break;
case DW_AT_location: {
- auto VerifyLocationExpr = [&](StringRef D) {
+ auto VerifyLocationExpr = [&](ArrayRef<uint8_t> D) {
DWARFUnit *U = Die.getDwarfUnit();
- DataExtractor Data(D, DCtx.isLittleEndian(), 0);
+ DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), 0);
DWARFExpression Expression(Data, U->getVersion(),
U->getAddressByteSize());
bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) {
@@ -479,13 +481,13 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
};
if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) {
// Verify inlined location.
- VerifyLocationExpr(llvm::toStringRef(*Expr));
+ VerifyLocationExpr(*Expr);
} else if (auto LocOffset = AttrValue.Value.getAsSectionOffset()) {
// Verify location list.
if (auto DebugLoc = DCtx.getDebugLoc())
if (auto LocList = DebugLoc->getLocationListAtOffset(*LocOffset))
for (const auto &Entry : LocList->Entries)
- VerifyLocationExpr({Entry.Loc.data(), Entry.Loc.size()});
+ VerifyLocationExpr(Entry.Loc);
}
break;
}
@@ -500,6 +502,9 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
break;
if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member)
break;
+ // This might be reference to a function declaration.
+ if (DieTag == DW_TAG_GNU_call_site && RefTag == DW_TAG_subprogram)
+ break;
ReportError("DIE with tag " + TagString(DieTag) + " has " +
AttributeString(Attr) +
" that points to DIE with "
@@ -545,7 +550,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
error() << FormEncodingString(Form) << " CU offset "
<< format("0x%08" PRIx64, CUOffset)
<< " is invalid (must be less than CU size of "
- << format("0x%08" PRIx32, CUSize) << "):\n";
+ << format("0x%08" PRIx64, CUSize) << "):\n";
Die.dump(OS, 0, DumpOpts);
dump(Die) << '\n';
} else {
@@ -578,7 +583,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
case DW_FORM_strp: {
auto SecOffset = AttrValue.Value.getAsSectionOffset();
assert(SecOffset); // DW_FORM_strp is a section offset.
- if (SecOffset && *SecOffset >= DObj.getStringSection().size()) {
+ if (SecOffset && *SecOffset >= DObj.getStrSection().size()) {
++NumErrors;
error() << "DW_FORM_strp offset beyond .debug_str bounds:\n";
dump(Die) << '\n';
@@ -605,7 +610,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
// Use a 64-bit type to calculate the offset to guard against overflow.
uint64_t Offset =
(uint64_t)DieCU->getStringOffsetsBase() + Index * ItemSize;
- if (DObj.getStringOffsetSection().Data.size() < Offset + ItemSize) {
+ if (DObj.getStrOffsetsSection().Data.size() < Offset + ItemSize) {
++NumErrors;
error() << FormEncodingString(Form) << " uses index "
<< format("%" PRIu64, Index) << ", which is too large:\n";
@@ -614,7 +619,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
}
// Check that the string offset is valid.
uint64_t StringOffset = *DieCU->getStringOffsetSectionItem(Index);
- if (StringOffset >= DObj.getStringSection().size()) {
+ if (StringOffset >= DObj.getStrSection().size()) {
++NumErrors;
error() << FormEncodingString(Form) << " uses index "
<< format("%" PRIu64, Index)
@@ -635,7 +640,7 @@ unsigned DWARFVerifier::verifyDebugInfoReferences() {
// getting the DIE by offset and emitting an error
OS << "Verifying .debug_info references...\n";
unsigned NumErrors = 0;
- for (const std::pair<uint64_t, std::set<uint32_t>> &Pair :
+ for (const std::pair<uint64_t, std::set<uint64_t>> &Pair :
ReferenceToDIEOffsets) {
if (DCtx.getDIEForOffset(Pair.first))
continue;
@@ -659,12 +664,12 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() {
auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
if (!StmtSectionOffset)
continue;
- const uint32_t LineTableOffset = *StmtSectionOffset;
+ const uint64_t LineTableOffset = *StmtSectionOffset;
auto LineTable = DCtx.getLineTableForUnit(CU.get());
if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
if (!LineTable) {
++NumDebugLineErrors;
- error() << ".debug_line[" << format("0x%08" PRIx32, LineTableOffset)
+ error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset)
<< "] was not able to be parsed for CU:\n";
dump(Die) << '\n';
continue;
@@ -680,8 +685,8 @@ void DWARFVerifier::verifyDebugLineStmtOffsets() {
if (Iter != StmtListToDie.end()) {
++NumDebugLineErrors;
error() << "two compile unit DIEs, "
- << format("0x%08" PRIx32, Iter->second.getOffset()) << " and "
- << format("0x%08" PRIx32, Die.getOffset())
+ << format("0x%08" PRIx64, Iter->second.getOffset()) << " and "
+ << format("0x%08" PRIx64, Die.getOffset())
<< ", have the same DW_AT_stmt_list section offset:\n";
dump(Iter->second);
dump(Die) << '\n';
@@ -826,10 +831,10 @@ unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
uint32_t NumBuckets = AccelTable.getNumBuckets();
uint32_t NumHashes = AccelTable.getNumHashes();
- uint32_t BucketsOffset =
+ uint64_t BucketsOffset =
AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
- uint32_t HashesBase = BucketsOffset + NumBuckets * 4;
- uint32_t OffsetsBase = HashesBase + NumHashes * 4;
+ uint64_t HashesBase = BucketsOffset + NumBuckets * 4;
+ uint64_t OffsetsBase = HashesBase + NumHashes * 4;
for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
@@ -849,28 +854,29 @@ unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
}
for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
- uint32_t HashOffset = HashesBase + 4 * HashIdx;
- uint32_t DataOffset = OffsetsBase + 4 * HashIdx;
+ uint64_t HashOffset = HashesBase + 4 * HashIdx;
+ uint64_t DataOffset = OffsetsBase + 4 * HashIdx;
uint32_t Hash = AccelSectionData.getU32(&HashOffset);
- uint32_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
+ uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
sizeof(uint64_t))) {
- error() << format("Hash[%d] has invalid HashData offset: 0x%08x.\n",
+ error() << format("Hash[%d] has invalid HashData offset: "
+ "0x%08" PRIx64 ".\n",
HashIdx, HashDataOffset);
++NumErrors;
}
- uint32_t StrpOffset;
- uint32_t StringOffset;
+ uint64_t StrpOffset;
+ uint64_t StringOffset;
uint32_t StringCount = 0;
- unsigned Offset;
+ uint64_t Offset;
unsigned Tag;
while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
const uint32_t NumHashDataObjects =
AccelSectionData.getU32(&HashDataOffset);
for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
++HashDataIdx) {
- std::tie(Offset, Tag) = AccelTable.readAtoms(HashDataOffset);
+ std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset);
auto Die = DCtx.getDIEForOffset(Offset);
if (!Die) {
const uint32_t BucketIdx =
@@ -882,8 +888,8 @@ unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
error() << format(
"%s Bucket[%d] Hash[%d] = 0x%08x "
- "Str[%u] = 0x%08x "
- "DIE[%d] = 0x%08x is not a valid DIE offset for \"%s\".\n",
+ "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " "
+ "is not a valid DIE offset for \"%s\".\n",
SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
HashDataIdx, Offset, Name);
@@ -908,8 +914,8 @@ unsigned
DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
// A map from CU offset to the (first) Name Index offset which claims to index
// this CU.
- DenseMap<uint32_t, uint32_t> CUMap;
- const uint32_t NotIndexed = std::numeric_limits<uint32_t>::max();
+ DenseMap<uint64_t, uint64_t> CUMap;
+ const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max();
CUMap.reserve(DCtx.getNumCompileUnits());
for (const auto &CU : DCtx.compile_units())
@@ -924,7 +930,7 @@ DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
continue;
}
for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
- uint32_t Offset = NI.getCUOffset(CU);
+ uint64_t Offset = NI.getCUOffset(CU);
auto Iter = CUMap.find(Offset);
if (Iter == CUMap.end()) {
@@ -1205,8 +1211,8 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
unsigned NumErrors = 0;
unsigned NumEntries = 0;
- uint32_t EntryID = NTE.getEntryOffset();
- uint32_t NextEntryID = EntryID;
+ uint64_t EntryID = NTE.getEntryOffset();
+ uint64_t NextEntryID = EntryID;
Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
EntryOr = NI.getEntry(&NextEntryID)) {
@@ -1218,7 +1224,7 @@ unsigned DWARFVerifier::verifyNameIndexEntries(
++NumErrors;
continue;
}
- uint32_t CUOffset = NI.getCUOffset(CUIndex);
+ uint64_t CUOffset = NI.getCUOffset(CUIndex);
uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
if (!DIE) {
@@ -1276,9 +1282,9 @@ static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
if (!Location)
return false;
- auto ContainsInterestingOperators = [&](StringRef D) {
+ auto ContainsInterestingOperators = [&](ArrayRef<uint8_t> D) {
DWARFUnit *U = Die.getDwarfUnit();
- DataExtractor Data(D, DCtx.isLittleEndian(), U->getAddressByteSize());
+ DataExtractor Data(toStringRef(D), DCtx.isLittleEndian(), U->getAddressByteSize());
DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize());
return any_of(Expression, [](DWARFExpression::Operation &Op) {
return !Op.isError() && (Op.getCode() == DW_OP_addr ||
@@ -1289,7 +1295,7 @@ static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
// Inlined location.
- if (ContainsInterestingOperators(toStringRef(*Expr)))
+ if (ContainsInterestingOperators(*Expr))
return true;
} else if (Optional<uint64_t> Offset = Location->getAsSectionOffset()) {
// Location list.
@@ -1297,7 +1303,7 @@ static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
if (const DWARFDebugLoc::LocationList *LocList =
DebugLoc->getLocationListAtOffset(*Offset)) {
if (any_of(LocList->Entries, [&](const DWARFDebugLoc::Entry &E) {
- return ContainsInterestingOperators({E.Loc.data(), E.Loc.size()});
+ return ContainsInterestingOperators(E.Loc);
}))
return true;
}
@@ -1455,7 +1461,7 @@ unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
bool DWARFVerifier::handleAccelTables() {
const DWARFObject &D = DCtx.getDWARFObj();
- DataExtractor StrData(D.getStringSection(), DCtx.isLittleEndian(), 0);
+ DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0);
unsigned NumErrors = 0;
if (!D.getAppleNamesSection().Data.empty())
NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
@@ -1470,8 +1476,8 @@ bool DWARFVerifier::handleAccelTables() {
NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
".apple_objc");
- if (!D.getDebugNamesSection().Data.empty())
- NumErrors += verifyDebugNames(D.getDebugNamesSection(), StrData);
+ if (!D.getNamesSection().Data.empty())
+ NumErrors += verifyDebugNames(D.getNamesSection(), StrData);
return NumErrors == 0;
}
diff --git a/lib/DebugInfo/GSYM/FileWriter.cpp b/lib/DebugInfo/GSYM/FileWriter.cpp
new file mode 100644
index 000000000000..4b30dcb60a7b
--- /dev/null
+++ b/lib/DebugInfo/GSYM/FileWriter.cpp
@@ -0,0 +1,78 @@
+//===- FileWriter.cpp -------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+
+using namespace llvm;
+using namespace gsym;
+
+FileWriter::~FileWriter() { OS.flush(); }
+
+void FileWriter::writeSLEB(int64_t S) {
+ uint8_t Bytes[32];
+ auto Length = encodeSLEB128(S, Bytes);
+ assert(Length < sizeof(Bytes));
+ OS.write(reinterpret_cast<const char *>(Bytes), Length);
+}
+
+void FileWriter::writeULEB(uint64_t U) {
+ uint8_t Bytes[32];
+ auto Length = encodeULEB128(U, Bytes);
+ assert(Length < sizeof(Bytes));
+ OS.write(reinterpret_cast<const char *>(Bytes), Length);
+}
+
+void FileWriter::writeU8(uint8_t U) {
+ OS.write(reinterpret_cast<const char *>(&U), sizeof(U));
+}
+
+void FileWriter::writeU16(uint16_t U) {
+ const uint16_t Swapped = support::endian::byte_swap(U, ByteOrder);
+ OS.write(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped));
+}
+
+void FileWriter::writeU32(uint32_t U) {
+ const uint32_t Swapped = support::endian::byte_swap(U, ByteOrder);
+ OS.write(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped));
+}
+
+void FileWriter::writeU64(uint64_t U) {
+ const uint64_t Swapped = support::endian::byte_swap(U, ByteOrder);
+ OS.write(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped));
+}
+
+void FileWriter::fixup32(uint32_t U, uint64_t Offset) {
+ const uint32_t Swapped = support::endian::byte_swap(U, ByteOrder);
+ OS.pwrite(reinterpret_cast<const char *>(&Swapped), sizeof(Swapped),
+ Offset);
+}
+
+void FileWriter::writeData(llvm::ArrayRef<uint8_t> Data) {
+ OS.write(reinterpret_cast<const char *>(Data.data()), Data.size());
+}
+
+void FileWriter::writeNullTerminated(llvm::StringRef Str) {
+ OS << Str << '\0';
+}
+
+uint64_t FileWriter::tell() {
+ return OS.tell();
+}
+
+void FileWriter::alignTo(size_t Align) {
+ off_t Offset = OS.tell();
+ off_t AlignedOffset = (Offset + Align - 1) / Align * Align;
+ if (AlignedOffset == Offset)
+ return;
+ off_t PadCount = AlignedOffset - Offset;
+ OS.write_zeros(PadCount);
+}
diff --git a/lib/DebugInfo/GSYM/FunctionInfo.cpp b/lib/DebugInfo/GSYM/FunctionInfo.cpp
index 55c36a55b4be..ad022fec9e32 100644
--- a/lib/DebugInfo/GSYM/FunctionInfo.cpp
+++ b/lib/DebugInfo/GSYM/FunctionInfo.cpp
@@ -1,22 +1,147 @@
-//===- FunctionInfo.cpp -----------------------------------------*- C++ -*-===//
+//===- FunctionInfo.cpp ---------------------------------------------------===//
//
-// 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
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/GSYM/FunctionInfo.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/Support/DataExtractor.h"
using namespace llvm;
using namespace gsym;
+/// FunctionInfo information type that is used to encode the optional data
+/// that is associated with a FunctionInfo object.
+enum InfoType : uint32_t {
+ EndOfList = 0u,
+ LineTableInfo = 1u,
+ InlineInfo = 2u
+};
+
raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const FunctionInfo &FI) {
OS << '[' << HEX64(FI.Range.Start) << '-' << HEX64(FI.Range.End) << "): "
- << "Name=" << HEX32(FI.Name) << '\n';
- for (const auto &Line : FI.Lines)
- OS << Line << '\n';
- OS << FI.Inline;
+ << "Name=" << HEX32(FI.Name) << '\n' << FI.OptLineTable << FI.Inline;
return OS;
}
+
+llvm::Expected<FunctionInfo> FunctionInfo::decode(DataExtractor &Data,
+ uint64_t BaseAddr) {
+ FunctionInfo FI;
+ FI.Range.Start = BaseAddr;
+ uint64_t Offset = 0;
+ if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing FunctionInfo Size", Offset);
+ FI.Range.End = FI.Range.Start + Data.getU32(&Offset);
+ if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing FunctionInfo Name", Offset);
+ FI.Name = Data.getU32(&Offset);
+ if (FI.Name == 0)
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": invalid FunctionInfo Name value 0x%8.8x",
+ Offset - 4, FI.Name);
+ bool Done = false;
+ while (!Done) {
+ if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing FunctionInfo InfoType value", Offset);
+ const uint32_t IT = Data.getU32(&Offset);
+ if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing FunctionInfo InfoType length", Offset);
+ const uint32_t InfoLength = Data.getU32(&Offset);
+ if (!Data.isValidOffsetForDataOfSize(Offset, InfoLength))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing FunctionInfo data for InfoType %u",
+ Offset, IT);
+ DataExtractor InfoData(Data.getData().substr(Offset, InfoLength),
+ Data.isLittleEndian(),
+ Data.getAddressSize());
+ switch (IT) {
+ case InfoType::EndOfList:
+ Done = true;
+ break;
+
+ case InfoType::LineTableInfo:
+ if (Expected<LineTable> LT = LineTable::decode(InfoData, BaseAddr))
+ FI.OptLineTable = std::move(LT.get());
+ else
+ return LT.takeError();
+ break;
+
+ case InfoType::InlineInfo:
+ if (Expected<InlineInfo> II = InlineInfo::decode(InfoData, BaseAddr))
+ FI.Inline = std::move(II.get());
+ else
+ return II.takeError();
+ break;
+
+ default:
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": unsupported InfoType %u",
+ Offset-8, IT);
+ }
+ Offset += InfoLength;
+ }
+ return std::move(FI);
+}
+
+llvm::Expected<uint64_t> FunctionInfo::encode(FileWriter &O) const {
+ if (!isValid())
+ return createStringError(std::errc::invalid_argument,
+ "attempted to encode invalid FunctionInfo object");
+ // Align FunctionInfo data to a 4 byte alignment.
+ O.alignTo(4);
+ const uint64_t FuncInfoOffset = O.tell();
+ // Write the size in bytes of this function as a uint32_t. This can be zero
+ // if we just have a symbol from a symbol table and that symbol has no size.
+ O.writeU32(size());
+ // Write the name of this function as a uint32_t string table offset.
+ O.writeU32(Name);
+
+ if (OptLineTable.hasValue()) {
+ O.writeU32(InfoType::LineTableInfo);
+ // Write a uint32_t length as zero for now, we will fix this up after
+ // writing the LineTable out with the number of bytes that were written.
+ O.writeU32(0);
+ const auto StartOffset = O.tell();
+ llvm::Error err = OptLineTable->encode(O, Range.Start);
+ if (err)
+ return std::move(err);
+ const off_t Length = O.tell() - StartOffset;
+ if (Length > UINT32_MAX)
+ return createStringError(std::errc::invalid_argument,
+ "LineTable length is greater than UINT32_MAX");
+ // Fixup the size of the LineTable data with the correct size.
+ O.fixup32(static_cast<uint32_t>(Length), StartOffset - 4);
+ }
+
+ // Write out the inline function info if we have any and if it is valid.
+ if (Inline.hasValue()) {
+ O.writeU32(InfoType::InlineInfo);
+ // Write a uint32_t length as zero for now, we will fix this up after
+ // writing the LineTable out with the number of bytes that were written.
+ O.writeU32(0);
+ const auto StartOffset = O.tell();
+ llvm::Error err = Inline->encode(O, Range.Start);
+ if (err)
+ return std::move(err);
+ const off_t Length = O.tell() - StartOffset;
+ if (Length > UINT32_MAX)
+ return createStringError(std::errc::invalid_argument,
+ "InlineInfo length is greater than UINT32_MAX");
+ // Fixup the size of the InlineInfo data with the correct size.
+ O.fixup32(static_cast<uint32_t>(Length), StartOffset - 4);
+ }
+
+ // Terminate the data chunks with and end of list with zero size
+ O.writeU32(InfoType::EndOfList);
+ O.writeU32(0);
+ return FuncInfoOffset;
+}
diff --git a/lib/DebugInfo/GSYM/GsymCreator.cpp b/lib/DebugInfo/GSYM/GsymCreator.cpp
new file mode 100644
index 000000000000..f371426f2010
--- /dev/null
+++ b/lib/DebugInfo/GSYM/GsymCreator.cpp
@@ -0,0 +1,275 @@
+//===- GsymCreator.cpp ----------------------------------------------------===//
+//
+// 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
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/GsymCreator.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/DebugInfo/GSYM/Header.h"
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/MC/StringTableBuilder.h"
+#include "llvm/Support/raw_ostream.h"
+
+#include <algorithm>
+#include <cassert>
+#include <functional>
+#include <vector>
+
+using namespace llvm;
+using namespace gsym;
+
+
+GsymCreator::GsymCreator() : StrTab(StringTableBuilder::ELF) {
+ insertFile(StringRef());
+}
+
+uint32_t GsymCreator::insertFile(StringRef Path,
+ llvm::sys::path::Style Style) {
+ llvm::StringRef directory = llvm::sys::path::parent_path(Path, Style);
+ llvm::StringRef filename = llvm::sys::path::filename(Path, Style);
+ FileEntry FE(insertString(directory), insertString(filename));
+
+ std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ const auto NextIndex = Files.size();
+ // Find FE in hash map and insert if not present.
+ auto R = FileEntryToIndex.insert(std::make_pair(FE, NextIndex));
+ if (R.second)
+ Files.emplace_back(FE);
+ return R.first->second;
+}
+
+llvm::Error GsymCreator::save(StringRef Path,
+ llvm::support::endianness ByteOrder) const {
+ std::error_code EC;
+ raw_fd_ostream OutStrm(Path, EC);
+ if (EC)
+ return llvm::errorCodeToError(EC);
+ FileWriter O(OutStrm, ByteOrder);
+ return encode(O);
+}
+
+llvm::Error GsymCreator::encode(FileWriter &O) const {
+ std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ if (Funcs.empty())
+ return createStringError(std::errc::invalid_argument,
+ "no functions to encode");
+ if (!Finalized)
+ return createStringError(std::errc::invalid_argument,
+ "GsymCreator wasn't finalized prior to encoding");
+
+ if (Funcs.size() > UINT32_MAX)
+ return createStringError(std::errc::invalid_argument,
+ "too many FunctionInfos");
+ const uint64_t MinAddr = Funcs.front().startAddress();
+ const uint64_t MaxAddr = Funcs.back().startAddress();
+ const uint64_t AddrDelta = MaxAddr - MinAddr;
+ Header Hdr;
+ Hdr.Magic = GSYM_MAGIC;
+ Hdr.Version = GSYM_VERSION;
+ Hdr.AddrOffSize = 0;
+ Hdr.UUIDSize = static_cast<uint8_t>(UUID.size());
+ Hdr.BaseAddress = MinAddr;
+ Hdr.NumAddresses = static_cast<uint32_t>(Funcs.size());
+ Hdr.StrtabOffset = 0; // We will fix this up later.
+ Hdr.StrtabOffset = 0; // We will fix this up later.
+ memset(Hdr.UUID, 0, sizeof(Hdr.UUID));
+ if (UUID.size() > sizeof(Hdr.UUID))
+ return createStringError(std::errc::invalid_argument,
+ "invalid UUID size %u", (uint32_t)UUID.size());
+ // Set the address offset size correctly in the GSYM header.
+ if (AddrDelta <= UINT8_MAX)
+ Hdr.AddrOffSize = 1;
+ else if (AddrDelta <= UINT16_MAX)
+ Hdr.AddrOffSize = 2;
+ else if (AddrDelta <= UINT32_MAX)
+ Hdr.AddrOffSize = 4;
+ else
+ Hdr.AddrOffSize = 8;
+ // Copy the UUID value if we have one.
+ if (UUID.size() > 0)
+ memcpy(Hdr.UUID, UUID.data(), UUID.size());
+ // Write out the header.
+ llvm::Error Err = Hdr.encode(O);
+ if (Err)
+ return Err;
+
+ // Write out the address offsets.
+ O.alignTo(Hdr.AddrOffSize);
+ for (const auto &FuncInfo : Funcs) {
+ uint64_t AddrOffset = FuncInfo.startAddress() - Hdr.BaseAddress;
+ switch(Hdr.AddrOffSize) {
+ case 1: O.writeU8(static_cast<uint8_t>(AddrOffset)); break;
+ case 2: O.writeU16(static_cast<uint16_t>(AddrOffset)); break;
+ case 4: O.writeU32(static_cast<uint32_t>(AddrOffset)); break;
+ case 8: O.writeU64(AddrOffset); break;
+ }
+ }
+
+ // Write out all zeros for the AddrInfoOffsets.
+ O.alignTo(4);
+ const off_t AddrInfoOffsetsOffset = O.tell();
+ for (size_t i = 0, n = Funcs.size(); i < n; ++i)
+ O.writeU32(0);
+
+ // Write out the file table
+ O.alignTo(4);
+ assert(!Files.empty());
+ assert(Files[0].Dir == 0);
+ assert(Files[0].Base == 0);
+ size_t NumFiles = Files.size();
+ if (NumFiles > UINT32_MAX)
+ return createStringError(std::errc::invalid_argument,
+ "too many files");
+ O.writeU32(static_cast<uint32_t>(NumFiles));
+ for (auto File: Files) {
+ O.writeU32(File.Dir);
+ O.writeU32(File.Base);
+ }
+
+ // Write out the sting table.
+ const off_t StrtabOffset = O.tell();
+ StrTab.write(O.get_stream());
+ const off_t StrtabSize = O.tell() - StrtabOffset;
+ std::vector<uint32_t> AddrInfoOffsets;
+
+ // Write out the address infos for each function info.
+ for (const auto &FuncInfo : Funcs) {
+ if (Expected<uint64_t> OffsetOrErr = FuncInfo.encode(O))
+ AddrInfoOffsets.push_back(OffsetOrErr.get());
+ else
+ return OffsetOrErr.takeError();
+ }
+ // Fixup the string table offset and size in the header
+ O.fixup32((uint32_t)StrtabOffset, offsetof(Header, StrtabOffset));
+ O.fixup32((uint32_t)StrtabSize, offsetof(Header, StrtabSize));
+
+ // Fixup all address info offsets
+ uint64_t Offset = 0;
+ for (auto AddrInfoOffset: AddrInfoOffsets) {
+ O.fixup32(AddrInfoOffset, AddrInfoOffsetsOffset + Offset);
+ Offset += 4;
+ }
+ return ErrorSuccess();
+}
+
+llvm::Error GsymCreator::finalize(llvm::raw_ostream &OS) {
+ std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ if (Finalized)
+ return createStringError(std::errc::invalid_argument,
+ "already finalized");
+ Finalized = true;
+
+ // Sort function infos so we can emit sorted functions.
+ llvm::sort(Funcs.begin(), Funcs.end());
+
+ // Don't let the string table indexes change by finalizing in order.
+ StrTab.finalizeInOrder();
+
+ // Remove duplicates function infos that have both entries from debug info
+ // (DWARF or Breakpad) and entries from the SymbolTable.
+ //
+ // Also handle overlapping function. Usually there shouldn't be any, but they
+ // can and do happen in some rare cases.
+ //
+ // (a) (b) (c)
+ // ^ ^ ^ ^
+ // |X |Y |X ^ |X
+ // | | | |Y | ^
+ // | | | v v |Y
+ // v v v v
+ //
+ // In (a) and (b), Y is ignored and X will be reported for the full range.
+ // In (c), both functions will be included in the result and lookups for an
+ // address in the intersection will return Y because of binary search.
+ //
+ // Note that in case of (b), we cannot include Y in the result because then
+ // we wouldn't find any function for range (end of Y, end of X)
+ // with binary search
+ auto NumBefore = Funcs.size();
+ auto Curr = Funcs.begin();
+ auto Prev = Funcs.end();
+ while (Curr != Funcs.end()) {
+ // Can't check for overlaps or same address ranges if we don't have a
+ // previous entry
+ if (Prev != Funcs.end()) {
+ if (Prev->Range.intersects(Curr->Range)) {
+ // Overlapping address ranges.
+ if (Prev->Range == Curr->Range) {
+ // Same address range. Check if one is from debug info and the other
+ // is from a symbol table. If so, then keep the one with debug info.
+ // Our sorting guarantees that entries with matching address ranges
+ // that have debug info are last in the sort.
+ if (*Prev == *Curr) {
+ // FunctionInfo entries match exactly (range, lines, inlines)
+ OS << "warning: duplicate function info entries, removing "
+ "duplicate:\n"
+ << *Curr << '\n';
+ Curr = Funcs.erase(Prev);
+ } else {
+ if (!Prev->hasRichInfo() && Curr->hasRichInfo()) {
+ // Same address range, one with no debug info (symbol) and the
+ // next with debug info. Keep the latter.
+ Curr = Funcs.erase(Prev);
+ } else {
+ OS << "warning: same address range contains different debug "
+ << "info. Removing:\n"
+ << *Prev << "\nIn favor of this one:\n"
+ << *Curr << "\n";
+ Curr = Funcs.erase(Prev);
+ }
+ }
+ } else {
+ // print warnings about overlaps
+ OS << "warning: function ranges overlap:\n"
+ << *Prev << "\n"
+ << *Curr << "\n";
+ }
+ } else if (Prev->Range.size() == 0 &&
+ Curr->Range.contains(Prev->Range.Start)) {
+ OS << "warning: removing symbol:\n"
+ << *Prev << "\nKeeping:\n"
+ << *Curr << "\n";
+ Curr = Funcs.erase(Prev);
+ }
+ }
+ if (Curr == Funcs.end())
+ break;
+ Prev = Curr++;
+ }
+
+ OS << "Pruned " << NumBefore - Funcs.size() << " functions, ended with "
+ << Funcs.size() << " total\n";
+ return Error::success();
+}
+
+uint32_t GsymCreator::insertString(StringRef S) {
+ std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ if (S.empty())
+ return 0;
+ return StrTab.add(S);
+}
+
+void GsymCreator::addFunctionInfo(FunctionInfo &&FI) {
+ std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ Funcs.emplace_back(FI);
+}
+
+void GsymCreator::forEachFunctionInfo(
+ std::function<bool(FunctionInfo &)> const &Callback) {
+ std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ for (auto &FI : Funcs) {
+ if (!Callback(FI))
+ break;
+ }
+}
+
+void GsymCreator::forEachFunctionInfo(
+ std::function<bool(const FunctionInfo &)> const &Callback) const {
+ std::lock_guard<std::recursive_mutex> Guard(Mutex);
+ for (const auto &FI : Funcs) {
+ if (!Callback(FI))
+ break;
+ }
+}
diff --git a/lib/DebugInfo/GSYM/GsymReader.cpp b/lib/DebugInfo/GSYM/GsymReader.cpp
new file mode 100644
index 000000000000..1b448cf80b70
--- /dev/null
+++ b/lib/DebugInfo/GSYM/GsymReader.cpp
@@ -0,0 +1,265 @@
+//===- GsymReader.cpp -----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/GsymReader.h"
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "llvm/DebugInfo/GSYM/GsymCreator.h"
+#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace gsym;
+
+GsymReader::GsymReader(std::unique_ptr<MemoryBuffer> Buffer) :
+ MemBuffer(std::move(Buffer)),
+ Endian(support::endian::system_endianness()) {}
+
+ GsymReader::GsymReader(GsymReader &&RHS) = default;
+
+GsymReader::~GsymReader() = default;
+
+llvm::Expected<GsymReader> GsymReader::openFile(StringRef Filename) {
+ // Open the input file and return an appropriate error if needed.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BuffOrErr =
+ MemoryBuffer::getFileOrSTDIN(Filename);
+ auto Err = BuffOrErr.getError();
+ if (Err)
+ return llvm::errorCodeToError(Err);
+ return create(BuffOrErr.get());
+}
+
+llvm::Expected<GsymReader> GsymReader::copyBuffer(StringRef Bytes) {
+ auto MemBuffer = MemoryBuffer::getMemBufferCopy(Bytes, "GSYM bytes");
+ return create(MemBuffer);
+}
+
+llvm::Expected<llvm::gsym::GsymReader>
+GsymReader::create(std::unique_ptr<MemoryBuffer> &MemBuffer) {
+ if (!MemBuffer.get())
+ return createStringError(std::errc::invalid_argument,
+ "invalid memory buffer");
+ GsymReader GR(std::move(MemBuffer));
+ llvm::Error Err = GR.parse();
+ if (Err)
+ return std::move(Err);
+ return std::move(GR);
+}
+
+llvm::Error
+GsymReader::parse() {
+ BinaryStreamReader FileData(MemBuffer->getBuffer(),
+ support::endian::system_endianness());
+ // Check for the magic bytes. This file format is designed to be mmap'ed
+ // into a process and accessed as read only. This is done for performance
+ // and efficiency for symbolicating and parsing GSYM data.
+ if (FileData.readObject(Hdr))
+ return createStringError(std::errc::invalid_argument,
+ "not enough data for a GSYM header");
+
+ const auto HostByteOrder = support::endian::system_endianness();
+ switch (Hdr->Magic) {
+ case GSYM_MAGIC:
+ Endian = HostByteOrder;
+ break;
+ case GSYM_CIGAM:
+ // This is a GSYM file, but not native endianness.
+ Endian = sys::IsBigEndianHost ? support::little : support::big;
+ Swap.reset(new SwappedData);
+ break;
+ default:
+ return createStringError(std::errc::invalid_argument,
+ "not a GSYM file");
+ }
+
+ bool DataIsLittleEndian = HostByteOrder != support::little;
+ // Read a correctly byte swapped header if we need to.
+ if (Swap) {
+ DataExtractor Data(MemBuffer->getBuffer(), DataIsLittleEndian, 4);
+ if (auto ExpectedHdr = Header::decode(Data))
+ Swap->Hdr = ExpectedHdr.get();
+ else
+ return ExpectedHdr.takeError();
+ Hdr = &Swap->Hdr;
+ }
+
+ // Detect errors in the header and report any that are found. If we make it
+ // past this without errors, we know we have a good magic value, a supported
+ // version number, verified address offset size and a valid UUID size.
+ if (Error Err = Hdr->checkForError())
+ return Err;
+
+ if (!Swap) {
+ // This is the native endianness case that is most common and optimized for
+ // efficient lookups. Here we just grab pointers to the native data and
+ // use ArrayRef objects to allow efficient read only access.
+
+ // Read the address offsets.
+ if (FileData.padToAlignment(Hdr->AddrOffSize) ||
+ FileData.readArray(AddrOffsets,
+ Hdr->NumAddresses * Hdr->AddrOffSize))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read address table");
+
+ // Read the address info offsets.
+ if (FileData.padToAlignment(4) ||
+ FileData.readArray(AddrInfoOffsets, Hdr->NumAddresses))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read address info offsets table");
+
+ // Read the file table.
+ uint32_t NumFiles = 0;
+ if (FileData.readInteger(NumFiles) || FileData.readArray(Files, NumFiles))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read file table");
+
+ // Get the string table.
+ FileData.setOffset(Hdr->StrtabOffset);
+ if (FileData.readFixedString(StrTab.Data, Hdr->StrtabSize))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read string table");
+} else {
+ // This is the non native endianness case that is not common and not
+ // optimized for lookups. Here we decode the important tables into local
+ // storage and then set the ArrayRef objects to point to these swapped
+ // copies of the read only data so lookups can be as efficient as possible.
+ DataExtractor Data(MemBuffer->getBuffer(), DataIsLittleEndian, 4);
+
+ // Read the address offsets.
+ uint64_t Offset = alignTo(sizeof(Header), Hdr->AddrOffSize);
+ Swap->AddrOffsets.resize(Hdr->NumAddresses * Hdr->AddrOffSize);
+ switch (Hdr->AddrOffSize) {
+ case 1:
+ if (!Data.getU8(&Offset, Swap->AddrOffsets.data(), Hdr->NumAddresses))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read address table");
+ break;
+ case 2:
+ if (!Data.getU16(&Offset,
+ reinterpret_cast<uint16_t *>(Swap->AddrOffsets.data()),
+ Hdr->NumAddresses))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read address table");
+ break;
+ case 4:
+ if (!Data.getU32(&Offset,
+ reinterpret_cast<uint32_t *>(Swap->AddrOffsets.data()),
+ Hdr->NumAddresses))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read address table");
+ break;
+ case 8:
+ if (!Data.getU64(&Offset,
+ reinterpret_cast<uint64_t *>(Swap->AddrOffsets.data()),
+ Hdr->NumAddresses))
+ return createStringError(std::errc::invalid_argument,
+ "failed to read address table");
+ }
+ AddrOffsets = ArrayRef<uint8_t>(Swap->AddrOffsets);
+
+ // Read the address info offsets.
+ Offset = alignTo(Offset, 4);
+ Swap->AddrInfoOffsets.resize(Hdr->NumAddresses);
+ if (Data.getU32(&Offset, Swap->AddrInfoOffsets.data(), Hdr->NumAddresses))
+ AddrInfoOffsets = ArrayRef<uint32_t>(Swap->AddrInfoOffsets);
+ else
+ return createStringError(std::errc::invalid_argument,
+ "failed to read address table");
+ // Read the file table.
+ const uint32_t NumFiles = Data.getU32(&Offset);
+ if (NumFiles > 0) {
+ Swap->Files.resize(NumFiles);
+ if (Data.getU32(&Offset, &Swap->Files[0].Dir, NumFiles*2))
+ Files = ArrayRef<FileEntry>(Swap->Files);
+ else
+ return createStringError(std::errc::invalid_argument,
+ "failed to read file table");
+ }
+ // Get the string table.
+ StrTab.Data = MemBuffer->getBuffer().substr(Hdr->StrtabOffset,
+ Hdr->StrtabSize);
+ if (StrTab.Data.empty())
+ return createStringError(std::errc::invalid_argument,
+ "failed to read string table");
+ }
+ return Error::success();
+
+}
+
+const Header &GsymReader::getHeader() const {
+ // The only way to get a GsymReader is from GsymReader::openFile(...) or
+ // GsymReader::copyBuffer() and the header must be valid and initialized to
+ // a valid pointer value, so the assert below should not trigger.
+ assert(Hdr);
+ return *Hdr;
+}
+
+Optional<uint64_t> GsymReader::getAddress(size_t Index) const {
+ switch (Hdr->AddrOffSize) {
+ case 1: return addressForIndex<uint8_t>(Index);
+ case 2: return addressForIndex<uint16_t>(Index);
+ case 4: return addressForIndex<uint32_t>(Index);
+ case 8: return addressForIndex<uint64_t>(Index);
+ }
+ return llvm::None;
+}
+
+Optional<uint64_t> GsymReader::getAddressInfoOffset(size_t Index) const {
+ const auto NumAddrInfoOffsets = AddrInfoOffsets.size();
+ if (Index < NumAddrInfoOffsets)
+ return AddrInfoOffsets[Index];
+ return llvm::None;
+}
+
+Expected<uint64_t>
+GsymReader::getAddressIndex(const uint64_t Addr) const {
+ if (Addr < Hdr->BaseAddress)
+ return createStringError(std::errc::invalid_argument,
+ "address 0x%" PRIx64 " not in GSYM", Addr);
+ const uint64_t AddrOffset = Addr - Hdr->BaseAddress;
+ switch (Hdr->AddrOffSize) {
+ case 1: return getAddressOffsetIndex<uint8_t>(AddrOffset);
+ case 2: return getAddressOffsetIndex<uint16_t>(AddrOffset);
+ case 4: return getAddressOffsetIndex<uint32_t>(AddrOffset);
+ case 8: return getAddressOffsetIndex<uint64_t>(AddrOffset);
+ default: break;
+ }
+ return createStringError(std::errc::invalid_argument,
+ "unsupported address offset size %u",
+ Hdr->AddrOffSize);
+}
+
+llvm::Expected<FunctionInfo> GsymReader::getFunctionInfo(uint64_t Addr) const {
+ Expected<uint64_t> AddressIndex = getAddressIndex(Addr);
+ if (!AddressIndex)
+ return AddressIndex.takeError();
+ // Address info offsets size should have been checked in parse().
+ assert(*AddressIndex < AddrInfoOffsets.size());
+ auto AddrInfoOffset = AddrInfoOffsets[*AddressIndex];
+ DataExtractor Data(MemBuffer->getBuffer().substr(AddrInfoOffset), Endian, 4);
+ if (Optional<uint64_t> OptAddr = getAddress(*AddressIndex)) {
+ auto ExpectedFI = FunctionInfo::decode(Data, *OptAddr);
+ if (ExpectedFI) {
+ if (ExpectedFI->Range.contains(Addr) || ExpectedFI->Range.size() == 0)
+ return ExpectedFI;
+ return createStringError(std::errc::invalid_argument,
+ "address 0x%" PRIx64 " not in GSYM", Addr);
+ }
+ }
+ return createStringError(std::errc::invalid_argument,
+ "failed to extract address[%" PRIu64 "]",
+ *AddressIndex);
+}
diff --git a/lib/DebugInfo/GSYM/Header.cpp b/lib/DebugInfo/GSYM/Header.cpp
new file mode 100644
index 000000000000..0b3fb9c49894
--- /dev/null
+++ b/lib/DebugInfo/GSYM/Header.cpp
@@ -0,0 +1,109 @@
+//===- Header.cpp -----------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/Header.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+#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)
+
+using namespace llvm;
+using namespace gsym;
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const Header &H) {
+ OS << "Header:\n";
+ OS << " Magic = " << HEX32(H.Magic) << "\n";
+ OS << " Version = " << HEX16(H.Version) << '\n';
+ OS << " AddrOffSize = " << HEX8(H.AddrOffSize) << '\n';
+ OS << " UUIDSize = " << HEX8(H.UUIDSize) << '\n';
+ OS << " BaseAddress = " << HEX64(H.BaseAddress) << '\n';
+ OS << " NumAddresses = " << HEX32(H.NumAddresses) << '\n';
+ OS << " StrtabOffset = " << HEX32(H.StrtabOffset) << '\n';
+ OS << " StrtabSize = " << HEX32(H.StrtabSize) << '\n';
+ OS << " UUID = ";
+ for (uint8_t I = 0; I < H.UUIDSize; ++I)
+ OS << format_hex_no_prefix(H.UUID[I], 2);
+ OS << '\n';
+ return OS;
+}
+
+/// Check the header and detect any errors.
+llvm::Error Header::checkForError() const {
+ if (Magic != GSYM_MAGIC)
+ return createStringError(std::errc::invalid_argument,
+ "invalid GSYM magic 0x%8.8x", Magic);
+ if (Version != GSYM_VERSION)
+ return createStringError(std::errc::invalid_argument,
+ "unsupported GSYM version %u", Version);
+ switch (AddrOffSize) {
+ case 1: break;
+ case 2: break;
+ case 4: break;
+ case 8: break;
+ default:
+ return createStringError(std::errc::invalid_argument,
+ "invalid address offset size %u",
+ AddrOffSize);
+ }
+ if (UUIDSize > GSYM_MAX_UUID_SIZE)
+ return createStringError(std::errc::invalid_argument,
+ "invalid UUID size %u", UUIDSize);
+ return Error::success();
+}
+
+llvm::Expected<Header> Header::decode(DataExtractor &Data) {
+ uint64_t Offset = 0;
+ // The header is stored as a single blob of data that has a fixed byte size.
+ if (!Data.isValidOffsetForDataOfSize(Offset, sizeof(Header)))
+ return createStringError(std::errc::invalid_argument,
+ "not enough data for a gsym::Header");
+ Header H;
+ H.Magic = Data.getU32(&Offset);
+ H.Version = Data.getU16(&Offset);
+ H.AddrOffSize = Data.getU8(&Offset);
+ H.UUIDSize = Data.getU8(&Offset);
+ H.BaseAddress = Data.getU64(&Offset);
+ H.NumAddresses = Data.getU32(&Offset);
+ H.StrtabOffset = Data.getU32(&Offset);
+ H.StrtabSize = Data.getU32(&Offset);
+ Data.getU8(&Offset, H.UUID, GSYM_MAX_UUID_SIZE);
+ if (llvm::Error Err = H.checkForError())
+ return std::move(Err);
+ return H;
+}
+
+llvm::Error Header::encode(FileWriter &O) const {
+ // Users must verify the Header is valid prior to calling this funtion.
+ if (llvm::Error Err = checkForError())
+ return Err;
+ O.writeU32(Magic);
+ O.writeU16(Version);
+ O.writeU8(AddrOffSize);
+ O.writeU8(UUIDSize);
+ O.writeU64(BaseAddress);
+ O.writeU32(NumAddresses);
+ O.writeU32(StrtabOffset);
+ O.writeU32(StrtabSize);
+ O.writeData(llvm::ArrayRef<uint8_t>(UUID));
+ return Error::success();
+}
+
+bool llvm::gsym::operator==(const Header &LHS, const Header &RHS) {
+ return LHS.Magic == RHS.Magic && LHS.Version == RHS.Version &&
+ LHS.AddrOffSize == RHS.AddrOffSize && LHS.UUIDSize == RHS.UUIDSize &&
+ LHS.BaseAddress == RHS.BaseAddress &&
+ LHS.NumAddresses == RHS.NumAddresses &&
+ LHS.StrtabOffset == RHS.StrtabOffset &&
+ LHS.StrtabSize == RHS.StrtabSize &&
+ memcmp(LHS.UUID, RHS.UUID, LHS.UUIDSize) == 0;
+}
diff --git a/lib/DebugInfo/GSYM/InlineInfo.cpp b/lib/DebugInfo/GSYM/InlineInfo.cpp
index 781c1755241d..32ed2c709575 100644
--- a/lib/DebugInfo/GSYM/InlineInfo.cpp
+++ b/lib/DebugInfo/GSYM/InlineInfo.cpp
@@ -8,7 +8,9 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/GSYM/FileEntry.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
#include "llvm/DebugInfo/GSYM/InlineInfo.h"
+#include "llvm/Support/DataExtractor.h"
#include <algorithm>
#include <inttypes.h>
@@ -57,3 +59,101 @@ llvm::Optional<InlineInfo::InlineArray> InlineInfo::getInlineStack(uint64_t Addr
return Result;
return llvm::None;
}
+
+/// Decode an InlineInfo in Data at the specified offset.
+///
+/// A local helper function to decode InlineInfo objects. This function is
+/// called recursively when parsing child InlineInfo objects.
+///
+/// \param Data The data extractor to decode from.
+/// \param Offset The offset within \a Data to decode from.
+/// \param BaseAddr The base address to use when decoding address ranges.
+/// \returns An InlineInfo or an error describing the issue that was
+/// encountered during decoding.
+static llvm::Expected<InlineInfo> decode(DataExtractor &Data, uint64_t &Offset,
+ uint64_t BaseAddr) {
+ InlineInfo Inline;
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing InlineInfo address ranges data", Offset);
+ Inline.Ranges.decode(Data, BaseAddr, Offset);
+ if (Inline.Ranges.empty())
+ return Inline;
+ if (!Data.isValidOffsetForDataOfSize(Offset, 1))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing InlineInfo uint8_t indicating children",
+ Offset);
+ bool HasChildren = Data.getU8(&Offset) != 0;
+ if (!Data.isValidOffsetForDataOfSize(Offset, 4))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing InlineInfo uint32_t for name", Offset);
+ Inline.Name = Data.getU32(&Offset);
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing ULEB128 for InlineInfo call file", Offset);
+ Inline.CallFile = (uint32_t)Data.getULEB128(&Offset);
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing ULEB128 for InlineInfo call line", Offset);
+ Inline.CallLine = (uint32_t)Data.getULEB128(&Offset);
+ if (HasChildren) {
+ // Child address ranges are encoded relative to the first address in the
+ // parent InlineInfo object.
+ const auto ChildBaseAddr = Inline.Ranges[0].Start;
+ while (true) {
+ llvm::Expected<InlineInfo> Child = decode(Data, Offset, ChildBaseAddr);
+ if (!Child)
+ return Child.takeError();
+ // InlineInfo with empty Ranges termintes a child sibling chain.
+ if (Child.get().Ranges.empty())
+ break;
+ Inline.Children.emplace_back(std::move(*Child));
+ }
+ }
+ return Inline;
+}
+
+llvm::Expected<InlineInfo> InlineInfo::decode(DataExtractor &Data,
+ uint64_t BaseAddr) {
+ uint64_t Offset = 0;
+ return ::decode(Data, Offset, BaseAddr);
+}
+
+llvm::Error InlineInfo::encode(FileWriter &O, uint64_t BaseAddr) const {
+ // Users must verify the InlineInfo is valid prior to calling this funtion.
+ // We don't want to emit any InlineInfo objects if they are not valid since
+ // it will waste space in the GSYM file.
+ if (!isValid())
+ return createStringError(std::errc::invalid_argument,
+ "attempted to encode invalid InlineInfo object");
+ Ranges.encode(O, BaseAddr);
+ bool HasChildren = !Children.empty();
+ O.writeU8(HasChildren);
+ O.writeU32(Name);
+ O.writeULEB(CallFile);
+ O.writeULEB(CallLine);
+ if (HasChildren) {
+ // Child address ranges are encoded as relative to the first
+ // address in the Ranges for this object. This keeps the offsets
+ // small and allows for efficient encoding using ULEB offsets.
+ const uint64_t ChildBaseAddr = Ranges[0].Start;
+ for (const auto &Child : Children) {
+ // Make sure all child address ranges are contained in the parent address
+ // ranges.
+ for (const auto &ChildRange: Child.Ranges) {
+ if (!Ranges.contains(ChildRange))
+ return createStringError(std::errc::invalid_argument,
+ "child range not contained in parent");
+ }
+ llvm::Error Err = Child.encode(O, ChildBaseAddr);
+ if (Err)
+ return Err;
+ }
+
+ // Terminate child sibling chain by emitting a zero. This zero will cause
+ // the decodeAll() function above to return false and stop the decoding
+ // of child InlineInfo objects that are siblings.
+ O.writeULEB(0);
+ }
+ return Error::success();
+}
diff --git a/lib/DebugInfo/GSYM/LineTable.cpp b/lib/DebugInfo/GSYM/LineTable.cpp
new file mode 100644
index 000000000000..824c0041be9f
--- /dev/null
+++ b/lib/DebugInfo/GSYM/LineTable.cpp
@@ -0,0 +1,287 @@
+//===- LineTable.cpp --------------------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/GSYM/LineTable.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/DataExtractor.h"
+
+using namespace llvm;
+using namespace gsym;
+
+enum LineTableOpCode {
+ EndSequence = 0x00, ///< End of the line table.
+ SetFile = 0x01, ///< Set LineTableRow.file_idx, don't push a row.
+ AdvancePC = 0x02, ///< Increment LineTableRow.address, and push a row.
+ AdvanceLine = 0x03, ///< Set LineTableRow.file_line, don't push a row.
+ FirstSpecial = 0x04, ///< All special opcodes push a row.
+};
+
+struct DeltaInfo {
+ int64_t Delta;
+ uint32_t Count;
+ DeltaInfo(int64_t D, uint32_t C) : Delta(D), Count(C) {}
+};
+
+inline bool operator<(const DeltaInfo &LHS, int64_t Delta) {
+ return LHS.Delta < Delta;
+}
+
+static bool encodeSpecial(int64_t MinLineDelta, int64_t MaxLineDelta,
+ int64_t LineDelta, uint64_t AddrDelta,
+ uint8_t &SpecialOp) {
+ if (LineDelta < MinLineDelta)
+ return false;
+ if (LineDelta > MaxLineDelta)
+ return false;
+ int64_t LineRange = MaxLineDelta - MinLineDelta + 1;
+ int64_t AdjustedOp = ((LineDelta - MinLineDelta) + AddrDelta * LineRange);
+ int64_t Op = AdjustedOp + FirstSpecial;
+ if (Op < 0)
+ return false;
+ if (Op > 255)
+ return false;
+ SpecialOp = (uint8_t)Op;
+ return true;
+}
+
+typedef std::function<bool(const LineEntry &Row)> LineEntryCallback;
+
+static llvm::Error parse(DataExtractor &Data, uint64_t BaseAddr,
+ LineEntryCallback const &Callback) {
+ uint64_t Offset = 0;
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing LineTable MinDelta", Offset);
+ int64_t MinDelta = Data.getSLEB128(&Offset);
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing LineTable MaxDelta", Offset);
+ int64_t MaxDelta = Data.getSLEB128(&Offset);
+ int64_t LineRange = MaxDelta - MinDelta + 1;
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": missing LineTable FirstLine", Offset);
+ const uint32_t FirstLine = (uint32_t)Data.getULEB128(&Offset);
+ LineEntry Row(BaseAddr, 1, FirstLine);
+ bool Done = false;
+ while (!Done) {
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": EOF found before EndSequence", Offset);
+ uint8_t Op = Data.getU8(&Offset);
+ switch (Op) {
+ case EndSequence:
+ Done = true;
+ break;
+ case SetFile:
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": EOF found before SetFile value",
+ Offset);
+ Row.File = (uint32_t)Data.getULEB128(&Offset);
+ break;
+ case AdvancePC:
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": EOF found before AdvancePC value",
+ Offset);
+ Row.Addr += Data.getULEB128(&Offset);
+ // If the function callback returns false, we stop parsing.
+ if (Callback(Row) == false)
+ return Error::success();
+ break;
+ case AdvanceLine:
+ if (!Data.isValidOffset(Offset))
+ return createStringError(std::errc::io_error,
+ "0x%8.8" PRIx64 ": EOF found before AdvanceLine value",
+ Offset);
+ Row.Line += Data.getSLEB128(&Offset);
+ break;
+ default: {
+ // A byte that contains both address and line increment.
+ uint8_t AdjustedOp = Op - FirstSpecial;
+ int64_t LineDelta = MinDelta + (AdjustedOp % LineRange);
+ uint64_t AddrDelta = (AdjustedOp / LineRange);
+ Row.Line += LineDelta;
+ Row.Addr += AddrDelta;
+ // If the function callback returns false, we stop parsing.
+ if (Callback(Row) == false)
+ return Error::success();
+ break;
+ }
+ }
+ }
+ return Error::success();
+}
+
+llvm::Error LineTable::encode(FileWriter &Out, uint64_t BaseAddr) const {
+ // Users must verify the LineTable is valid prior to calling this funtion.
+ // We don't want to emit any LineTable objects if they are not valid since
+ // it will waste space in the GSYM file.
+ if (!isValid())
+ return createStringError(std::errc::invalid_argument,
+ "attempted to encode invalid LineTable object");
+
+ int64_t MinLineDelta = INT64_MAX;
+ int64_t MaxLineDelta = INT64_MIN;
+ std::vector<DeltaInfo> DeltaInfos;
+ if (Lines.size() == 1) {
+ MinLineDelta = 0;
+ MaxLineDelta = 0;
+ } else {
+ int64_t PrevLine = 1;
+ bool First = true;
+ for (const auto &line_entry : Lines) {
+ if (First)
+ First = false;
+ else {
+ int64_t LineDelta = (int64_t)line_entry.Line - PrevLine;
+ auto End = DeltaInfos.end();
+ auto Pos = std::lower_bound(DeltaInfos.begin(), End, LineDelta);
+ if (Pos != End && Pos->Delta == LineDelta)
+ ++Pos->Count;
+ else
+ DeltaInfos.insert(Pos, DeltaInfo(LineDelta, 1));
+ if (LineDelta < MinLineDelta)
+ MinLineDelta = LineDelta;
+ if (LineDelta > MaxLineDelta)
+ MaxLineDelta = LineDelta;
+ }
+ PrevLine = (int64_t)line_entry.Line;
+ }
+ assert(MinLineDelta <= MaxLineDelta);
+ }
+ // Set the min and max line delta intelligently based on the counts of
+ // the line deltas. if our range is too large.
+ const int64_t MaxLineRange = 14;
+ if (MaxLineDelta - MinLineDelta > MaxLineRange) {
+ uint32_t BestIndex = 0;
+ uint32_t BestEndIndex = 0;
+ uint32_t BestCount = 0;
+ const size_t NumDeltaInfos = DeltaInfos.size();
+ for (uint32_t I = 0; I < NumDeltaInfos; ++I) {
+ const int64_t FirstDelta = DeltaInfos[I].Delta;
+ uint32_t CurrCount = 0;
+ uint32_t J;
+ for (J = I; J < NumDeltaInfos; ++J) {
+ auto LineRange = DeltaInfos[J].Delta - FirstDelta;
+ if (LineRange > MaxLineRange)
+ break;
+ CurrCount += DeltaInfos[J].Count;
+ }
+ if (CurrCount > BestCount) {
+ BestIndex = I;
+ BestEndIndex = J - 1;
+ BestCount = CurrCount;
+ }
+ }
+ MinLineDelta = DeltaInfos[BestIndex].Delta;
+ MaxLineDelta = DeltaInfos[BestEndIndex].Delta;
+ }
+ if (MinLineDelta == MaxLineDelta && MinLineDelta > 0 &&
+ MinLineDelta < MaxLineRange)
+ MinLineDelta = 0;
+ assert(MinLineDelta <= MaxLineDelta);
+
+ // Initialize the line entry state as a starting point. All line entries
+ // will be deltas from this.
+ LineEntry Prev(BaseAddr, 1, Lines.front().Line);
+
+ // Write out the min and max line delta as signed LEB128.
+ Out.writeSLEB(MinLineDelta);
+ Out.writeSLEB(MaxLineDelta);
+ // Write out the starting line number as a unsigned LEB128.
+ Out.writeULEB(Prev.Line);
+
+ for (const auto &Curr : Lines) {
+ if (Curr.Addr < BaseAddr)
+ return createStringError(std::errc::invalid_argument,
+ "LineEntry has address 0x%" PRIx64 " which is "
+ "less than the function start address 0x%"
+ PRIx64, Curr.Addr, BaseAddr);
+ if (Curr.Addr < Prev.Addr)
+ return createStringError(std::errc::invalid_argument,
+ "LineEntry in LineTable not in ascending order");
+ const uint64_t AddrDelta = Curr.Addr - Prev.Addr;
+ int64_t LineDelta = 0;
+ if (Curr.Line > Prev.Line)
+ LineDelta = Curr.Line - Prev.Line;
+ else if (Prev.Line > Curr.Line)
+ LineDelta = -((int32_t)(Prev.Line - Curr.Line));
+
+ // Set the file if it doesn't match the current one.
+ if (Curr.File != Prev.File) {
+ Out.writeU8(SetFile);
+ Out.writeULEB(Curr.File);
+ }
+
+ uint8_t SpecialOp;
+ if (encodeSpecial(MinLineDelta, MaxLineDelta, LineDelta, AddrDelta,
+ SpecialOp)) {
+ // Advance the PC and line and push a row.
+ Out.writeU8(SpecialOp);
+ } else {
+ // We can't encode the address delta and line delta into
+ // a single special opcode, we must do them separately.
+
+ // Advance the line.
+ if (LineDelta != 0) {
+ Out.writeU8(AdvanceLine);
+ Out.writeSLEB(LineDelta);
+ }
+
+ // Advance the PC and push a row.
+ Out.writeU8(AdvancePC);
+ Out.writeULEB(AddrDelta);
+ }
+ Prev = Curr;
+ }
+ Out.writeU8(EndSequence);
+ return Error::success();
+}
+
+// Parse all line table entries into the "LineTable" vector. We can
+// cache the results of this if needed, or we can call LineTable::lookup()
+// below.
+llvm::Expected<LineTable> LineTable::decode(DataExtractor &Data,
+ uint64_t BaseAddr) {
+ LineTable LT;
+ llvm::Error Err = parse(Data, BaseAddr, [&](const LineEntry &Row) -> bool {
+ LT.Lines.push_back(Row);
+ return true; // Keep parsing by returning true.
+ });
+ if (Err)
+ return std::move(Err);
+ return LT;
+}
+// Parse the line table on the fly and find the row we are looking for.
+// We will need to determine if we need to cache the line table by calling
+// LineTable::parseAllEntries(...) or just call this function each time.
+// There is a CPU vs memory tradeoff we will need to determine.
+LineEntry LineTable::lookup(DataExtractor &Data, uint64_t BaseAddr, uint64_t Addr) {
+ LineEntry Result;
+ llvm::Error Err = parse(Data, BaseAddr,
+ [Addr, &Result](const LineEntry &Row) -> bool {
+ if (Addr < Row.Addr)
+ return false; // Stop parsing, result contains the line table row!
+ Result = Row;
+ if (Addr == Row.Addr) {
+ // Stop parsing, this is the row we are looking for since the address
+ // matches.
+ return false;
+ }
+ return true; // Keep parsing till we find the right row.
+ });
+ return Result;
+}
+
+raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const LineTable &LT) {
+ for (const auto &LineEntry : LT)
+ OS << LineEntry << '\n';
+ return OS;
+}
diff --git a/lib/DebugInfo/GSYM/Range.cpp b/lib/DebugInfo/GSYM/Range.cpp
index ca61984dacbd..19ab700fdd57 100644
--- a/lib/DebugInfo/GSYM/Range.cpp
+++ b/lib/DebugInfo/GSYM/Range.cpp
@@ -8,6 +8,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/GSYM/Range.h"
+#include "llvm/DebugInfo/GSYM/FileWriter.h"
+#include "llvm/Support/DataExtractor.h"
#include <algorithm>
#include <inttypes.h>
@@ -40,6 +42,17 @@ bool AddressRanges::contains(uint64_t Addr) const {
return It != Ranges.begin() && Addr < It[-1].End;
}
+bool AddressRanges::contains(AddressRange Range) const {
+ if (Range.size() == 0)
+ return false;
+ auto It = std::partition_point(
+ Ranges.begin(), Ranges.end(),
+ [=](const AddressRange &R) { return R.Start <= Range.Start; });
+ if (It == Ranges.begin())
+ return false;
+ return Range.End <= It[-1].End;
+}
+
raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) {
return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")";
}
@@ -53,3 +66,37 @@ raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) {
}
return OS;
}
+
+void AddressRange::encode(FileWriter &O, uint64_t BaseAddr) const {
+ assert(Start >= BaseAddr);
+ O.writeULEB(Start - BaseAddr);
+ O.writeULEB(size());
+}
+
+void AddressRange::decode(DataExtractor &Data, uint64_t BaseAddr,
+ uint64_t &Offset) {
+ const uint64_t AddrOffset = Data.getULEB128(&Offset);
+ const uint64_t Size = Data.getULEB128(&Offset);
+ const uint64_t StartAddr = BaseAddr + AddrOffset;
+ Start = StartAddr;
+ End = StartAddr + Size;
+}
+
+void AddressRanges::encode(FileWriter &O, uint64_t BaseAddr) const {
+ O.writeULEB(Ranges.size());
+ if (Ranges.empty())
+ return;
+ for (auto Range : Ranges)
+ Range.encode(O, BaseAddr);
+}
+
+void AddressRanges::decode(DataExtractor &Data, uint64_t BaseAddr,
+ uint64_t &Offset) {
+ clear();
+ uint64_t NumRanges = Data.getULEB128(&Offset);
+ if (NumRanges == 0)
+ return;
+ Ranges.resize(NumRanges);
+ for (auto &Range : Ranges)
+ Range.decode(Data, BaseAddr, Offset);
+}
diff --git a/lib/DebugInfo/MSF/MappedBlockStream.cpp b/lib/DebugInfo/MSF/MappedBlockStream.cpp
index df925771f0d9..5dc9c86b34fd 100644
--- a/lib/DebugInfo/MSF/MappedBlockStream.cpp
+++ b/lib/DebugInfo/MSF/MappedBlockStream.cpp
@@ -52,7 +52,7 @@ MappedBlockStream::MappedBlockStream(uint32_t BlockSize,
std::unique_ptr<MappedBlockStream> MappedBlockStream::createStream(
uint32_t BlockSize, const MSFStreamLayout &Layout, BinaryStreamRef MsfData,
BumpPtrAllocator &Allocator) {
- return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+ return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
BlockSize, Layout, MsfData, Allocator);
}
@@ -63,7 +63,7 @@ std::unique_ptr<MappedBlockStream> MappedBlockStream::createIndexedStream(
MSFStreamLayout SL;
SL.Blocks = Layout.StreamMap[StreamIndex];
SL.Length = Layout.StreamSizes[StreamIndex];
- return llvm::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+ return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
Layout.SB->BlockSize, SL, MsfData, Allocator);
}
@@ -318,7 +318,7 @@ WritableMappedBlockStream::createStream(uint32_t BlockSize,
const MSFStreamLayout &Layout,
WritableBinaryStreamRef MsfData,
BumpPtrAllocator &Allocator) {
- return llvm::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
+ return std::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
BlockSize, Layout, MsfData, Allocator);
}
diff --git a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
index a8ae076e1d6c..c2552f55703c 100644
--- a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp
@@ -405,7 +405,7 @@ DIARawSymbol::findChildren(PDB_SymType Type) const {
return nullptr;
}
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -423,7 +423,7 @@ DIARawSymbol::findChildren(PDB_SymType Type, StringRef Name,
Symbol->findChildrenEx(EnumVal, Name16Str, CompareFlags, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -443,7 +443,7 @@ DIARawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
Section, Offset, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -462,7 +462,7 @@ DIARawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
&DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -480,7 +480,7 @@ DIARawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
&DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -489,7 +489,7 @@ DIARawSymbol::findInlineFramesByAddr(uint32_t Section, uint32_t Offset) const {
if (S_OK != Symbol->findInlineFramesByAddr(Section, Offset, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -498,7 +498,7 @@ DIARawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
if (S_OK != Symbol->findInlineFramesByRVA(RVA, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumSymbols>
@@ -507,7 +507,7 @@ DIARawSymbol::findInlineFramesByVA(uint64_t VA) const {
if (S_OK != Symbol->findInlineFramesByVA(VA, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
+ return std::make_unique<DIAEnumSymbols>(Session, DiaEnumerator);
}
std::unique_ptr<IPDBEnumLineNumbers> DIARawSymbol::findInlineeLines() const {
@@ -515,7 +515,7 @@ std::unique_ptr<IPDBEnumLineNumbers> DIARawSymbol::findInlineeLines() const {
if (S_OK != Symbol->findInlineeLines(&DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+ return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
}
std::unique_ptr<IPDBEnumLineNumbers>
@@ -526,7 +526,7 @@ DIARawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
Symbol->findInlineeLinesByAddr(Section, Offset, Length, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+ return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
}
std::unique_ptr<IPDBEnumLineNumbers>
@@ -535,7 +535,7 @@ DIARawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
if (S_OK != Symbol->findInlineeLinesByRVA(RVA, Length, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+ return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
}
std::unique_ptr<IPDBEnumLineNumbers>
@@ -544,7 +544,7 @@ DIARawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
if (S_OK != Symbol->findInlineeLinesByVA(VA, Length, &DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
+ return std::make_unique<DIAEnumLineNumbers>(DiaEnumerator);
}
void DIARawSymbol::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) const {
@@ -776,7 +776,7 @@ std::unique_ptr<IPDBLineNumber> DIARawSymbol::getSrcLineOnTypeDefn() const {
if (FAILED(Symbol->getSrcLineOnTypeDefn(&LineNumber)) || !LineNumber)
return nullptr;
- return llvm::make_unique<DIALineNumber>(LineNumber);
+ return std::make_unique<DIALineNumber>(LineNumber);
}
uint32_t DIARawSymbol::getStride() const {
@@ -871,7 +871,7 @@ DIARawSymbol::getVirtualBaseTableType() const {
if (FAILED(Symbol->get_virtualBaseTableType(&TableType)) || !TableType)
return nullptr;
- auto RawVT = llvm::make_unique<DIARawSymbol>(Session, TableType);
+ auto RawVT = std::make_unique<DIARawSymbol>(Session, TableType);
auto Pointer =
PDBSymbol::createAs<PDBSymbolTypePointer>(Session, std::move(RawVT));
return unique_dyn_cast<PDBSymbolTypeBuiltin>(Pointer->getPointeeType());
diff --git a/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp b/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
index e2d928f2c4b2..4f0e078e6712 100644
--- a/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp
@@ -23,7 +23,7 @@ std::unique_ptr<PDBSymbolCompiland> DIASectionContrib::getCompiland() const {
if (FAILED(Section->get_compiland(&Symbol)))
return nullptr;
- auto RawSymbol = llvm::make_unique<DIARawSymbol>(Session, Symbol);
+ auto RawSymbol = std::make_unique<DIARawSymbol>(Session, Symbol);
return PDBSymbol::createAs<PDBSymbolCompiland>(Session, std::move(RawSymbol));
}
diff --git a/lib/DebugInfo/PDB/DIA/DIASession.cpp b/lib/DebugInfo/PDB/DIA/DIASession.cpp
index 4e0b8587c613..64ffa776bbd6 100644
--- a/lib/DebugInfo/PDB/DIA/DIASession.cpp
+++ b/lib/DebugInfo/PDB/DIA/DIASession.cpp
@@ -73,15 +73,7 @@ static Error LoadDIA(CComPtr<IDiaDataSource> &DiaDataSource) {
#if !defined(_MSC_VER)
return llvm::make_error<PDBError>(pdb_error_code::dia_failed_loading);
#else
- const wchar_t *msdia_dll = nullptr;
-#if _MSC_VER >= 1900 && _MSC_VER < 2000
- msdia_dll = L"msdia140.dll"; // VS2015
-#elif _MSC_VER >= 1800
- msdia_dll = L"msdia120.dll"; // VS2013
-#else
-#error "Unknown Visual Studio version."
-#endif
-
+ const wchar_t *msdia_dll = L"msdia140.dll";
HRESULT HR;
if (FAILED(HR = NoRegCoCreate(msdia_dll, CLSID_DiaSource, IID_IDiaDataSource,
reinterpret_cast<LPVOID *>(&DiaDataSource))))
@@ -158,7 +150,7 @@ std::unique_ptr<PDBSymbolExe> DIASession::getGlobalScope() {
if (S_OK != Session->get_globalScope(&GlobalScope))
return nullptr;
- auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, GlobalScope);
+ auto RawSymbol = std::make_unique<DIARawSymbol>(*this, GlobalScope);
auto PdbSymbol(PDBSymbol::create(*this, std::move(RawSymbol)));
std::unique_ptr<PDBSymbolExe> ExeSymbol(
static_cast<PDBSymbolExe *>(PdbSymbol.release()));
@@ -193,7 +185,7 @@ DIASession::getSymbolById(SymIndexId SymbolId) const {
if (S_OK != Session->symbolById(SymbolId, &LocatedSymbol))
return nullptr;
- auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, LocatedSymbol);
+ auto RawSymbol = std::make_unique<DIARawSymbol>(*this, LocatedSymbol);
return PDBSymbol::create(*this, std::move(RawSymbol));
}
@@ -210,7 +202,7 @@ DIASession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) const {
if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
return nullptr;
}
- auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
+ auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol);
return PDBSymbol::create(*this, std::move(RawSymbol));
}
@@ -222,7 +214,7 @@ std::unique_ptr<PDBSymbol> DIASession::findSymbolByRVA(uint32_t RVA,
if (S_OK != Session->findSymbolByRVA(RVA, EnumVal, &Symbol))
return nullptr;
- auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
+ auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol);
return PDBSymbol::create(*this, std::move(RawSymbol));
}
@@ -235,7 +227,7 @@ DIASession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
if (S_OK != Session->findSymbolByAddr(Sect, Offset, EnumVal, &Symbol))
return nullptr;
- auto RawSymbol = llvm::make_unique<DIARawSymbol>(*this, Symbol);
+ auto RawSymbol = std::make_unique<DIARawSymbol>(*this, Symbol);
return PDBSymbol::create(*this, std::move(RawSymbol));
}
@@ -251,7 +243,7 @@ DIASession::findLineNumbers(const PDBSymbolCompiland &Compiland,
RawFile.getDiaFile(), &LineNumbers))
return nullptr;
- return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+ return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
}
std::unique_ptr<IPDBEnumLineNumbers>
@@ -265,7 +257,7 @@ DIASession::findLineNumbersByAddress(uint64_t Address, uint32_t Length) const {
if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers))
return nullptr;
}
- return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+ return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
}
std::unique_ptr<IPDBEnumLineNumbers>
@@ -274,7 +266,7 @@ DIASession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
if (S_OK != Session->findLinesByRVA(RVA, Length, &LineNumbers))
return nullptr;
- return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+ return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
}
std::unique_ptr<IPDBEnumLineNumbers>
@@ -284,7 +276,7 @@ DIASession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
if (S_OK != Session->findLinesByAddr(Section, Offset, Length, &LineNumbers))
return nullptr;
- return llvm::make_unique<DIAEnumLineNumbers>(LineNumbers);
+ return std::make_unique<DIAEnumLineNumbers>(LineNumbers);
}
std::unique_ptr<IPDBEnumSourceFiles>
@@ -306,7 +298,7 @@ DIASession::findSourceFiles(const PDBSymbolCompiland *Compiland,
if (S_OK !=
Session->findFile(DiaCompiland, Utf16Pattern.m_str, Flags, &SourceFiles))
return nullptr;
- return llvm::make_unique<DIAEnumSourceFiles>(*this, SourceFiles);
+ return std::make_unique<DIAEnumSourceFiles>(*this, SourceFiles);
}
std::unique_ptr<IPDBSourceFile>
@@ -342,7 +334,7 @@ std::unique_ptr<IPDBEnumSourceFiles> DIASession::getAllSourceFiles() const {
if (S_OK != Session->findFile(nullptr, nullptr, nsNone, &Files))
return nullptr;
- return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
+ return std::make_unique<DIAEnumSourceFiles>(*this, Files);
}
std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland(
@@ -355,7 +347,7 @@ std::unique_ptr<IPDBEnumSourceFiles> DIASession::getSourceFilesForCompiland(
Session->findFile(RawSymbol.getDiaSymbol(), nullptr, nsNone, &Files))
return nullptr;
- return llvm::make_unique<DIAEnumSourceFiles>(*this, Files);
+ return std::make_unique<DIAEnumSourceFiles>(*this, Files);
}
std::unique_ptr<IPDBSourceFile>
@@ -364,7 +356,7 @@ DIASession::getSourceFileById(uint32_t FileId) const {
if (S_OK != Session->findFileById(FileId, &LocatedFile))
return nullptr;
- return llvm::make_unique<DIASourceFile>(*this, LocatedFile);
+ return std::make_unique<DIASourceFile>(*this, LocatedFile);
}
std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
@@ -372,7 +364,7 @@ std::unique_ptr<IPDBEnumDataStreams> DIASession::getDebugStreams() const {
if (S_OK != Session->getEnumDebugStreams(&DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
+ return std::make_unique<DIAEnumDebugStreams>(DiaEnumerator);
}
std::unique_ptr<IPDBEnumTables> DIASession::getEnumTables() const {
@@ -380,7 +372,7 @@ std::unique_ptr<IPDBEnumTables> DIASession::getEnumTables() const {
if (S_OK != Session->getEnumTables(&DiaEnumerator))
return nullptr;
- return llvm::make_unique<DIAEnumTables>(DiaEnumerator);
+ return std::make_unique<DIAEnumTables>(DiaEnumerator);
}
template <class T> static CComPtr<T> getTableEnumerator(IDiaSession &Session) {
@@ -407,7 +399,7 @@ DIASession::getInjectedSources() const {
if (!Files)
return nullptr;
- return llvm::make_unique<DIAEnumInjectedSources>(Files);
+ return std::make_unique<DIAEnumInjectedSources>(Files);
}
std::unique_ptr<IPDBEnumSectionContribs>
@@ -417,7 +409,7 @@ DIASession::getSectionContribs() const {
if (!Sections)
return nullptr;
- return llvm::make_unique<DIAEnumSectionContribs>(*this, Sections);
+ return std::make_unique<DIAEnumSectionContribs>(*this, Sections);
}
std::unique_ptr<IPDBEnumFrameData>
@@ -427,5 +419,5 @@ DIASession::getFrameData() const {
if (!FD)
return nullptr;
- return llvm::make_unique<DIAEnumFrameData>(FD);
+ return std::make_unique<DIAEnumFrameData>(FD);
}
diff --git a/lib/DebugInfo/PDB/GenericError.cpp b/lib/DebugInfo/PDB/GenericError.cpp
index 70dc094c42ec..0e4cba3174b2 100644
--- a/lib/DebugInfo/PDB/GenericError.cpp
+++ b/lib/DebugInfo/PDB/GenericError.cpp
@@ -34,8 +34,8 @@ public:
return "The PDB file path is an invalid UTF8 sequence.";
case pdb_error_code::signature_out_of_date:
return "The signature does not match; the file(s) might be out of date.";
- case pdb_error_code::external_cmdline_ref:
- return "The path to this file must be provided on the command-line.";
+ case pdb_error_code::no_matching_pch:
+ return "No matching precompiled header could be located.";
}
llvm_unreachable("Unrecognized generic_error_code");
}
diff --git a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index 20b6c6142547..419734771ccd 100644
--- a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -180,12 +180,12 @@ Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter,
void DbiModuleDescriptorBuilder::addDebugSubsection(
std::shared_ptr<DebugSubsection> Subsection) {
assert(Subsection);
- C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+ C13Builders.push_back(std::make_unique<DebugSubsectionRecordBuilder>(
std::move(Subsection), CodeViewContainer::Pdb));
}
void DbiModuleDescriptorBuilder::addDebugSubsection(
const DebugSubsectionRecord &SubsectionContents) {
- C13Builders.push_back(llvm::make_unique<DebugSubsectionRecordBuilder>(
+ C13Builders.push_back(std::make_unique<DebugSubsectionRecordBuilder>(
SubsectionContents, CodeViewContainer::Pdb));
}
diff --git a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index b7ade0072ee5..0e00c2f7ff98 100644
--- a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -114,7 +114,7 @@ Expected<DbiModuleDescriptorBuilder &>
DbiStreamBuilder::addModuleInfo(StringRef ModuleName) {
uint32_t Index = ModiList.size();
ModiList.push_back(
- llvm::make_unique<DbiModuleDescriptorBuilder>(ModuleName, Index, Msf));
+ std::make_unique<DbiModuleDescriptorBuilder>(ModuleName, Index, Msf));
return *ModiList.back();
}
diff --git a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 8ed5b8b44c59..432f1e9b24d3 100644
--- a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -183,8 +183,8 @@ void GSIHashStreamBuilder::finalizeBuckets(uint32_t RecordZeroOffset) {
}
GSIStreamBuilder::GSIStreamBuilder(msf::MSFBuilder &Msf)
- : Msf(Msf), PSH(llvm::make_unique<GSIHashStreamBuilder>()),
- GSH(llvm::make_unique<GSIHashStreamBuilder>()) {}
+ : Msf(Msf), PSH(std::make_unique<GSIHashStreamBuilder>()),
+ GSH(std::make_unique<GSIHashStreamBuilder>()) {}
GSIStreamBuilder::~GSIStreamBuilder() {}
diff --git a/lib/DebugInfo/PDB/Native/Hash.cpp b/lib/DebugInfo/PDB/Native/Hash.cpp
index b5c139ecbec0..7fb6b4bd5d31 100644
--- a/lib/DebugInfo/PDB/Native/Hash.cpp
+++ b/lib/DebugInfo/PDB/Native/Hash.cpp
@@ -8,8 +8,8 @@
#include "llvm/DebugInfo/PDB/Native/Hash.h"
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/CRC.h"
#include "llvm/Support/Endian.h"
-#include "llvm/Support/JamCRC.h"
#include <cstdint>
using namespace llvm;
@@ -79,7 +79,6 @@ uint32_t pdb::hashStringV2(StringRef Str) {
// Corresponds to `SigForPbCb` in langapi/shared/crc32.h.
uint32_t pdb::hashBufferV8(ArrayRef<uint8_t> Buf) {
JamCRC JC(/*Init=*/0U);
- JC.update(makeArrayRef<char>(reinterpret_cast<const char *>(Buf.data()),
- Buf.size()));
+ JC.update(Buf);
return JC.getCRC();
}
diff --git a/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp b/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
index f17ff5bb01f2..2f6a5bc3d574 100644
--- a/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
@@ -46,30 +46,31 @@ public:
uint64_t getCodeByteSize() const override { return Entry.FileSize; }
std::string getFileName() const override {
- auto Name = Strings.getStringForID(Entry.FileNI);
- assert(Name && "InjectedSourceStream should have rejected this");
- return *Name;
+ StringRef Ret = cantFail(Strings.getStringForID(Entry.FileNI),
+ "InjectedSourceStream should have rejected this");
+ return Ret;
}
std::string getObjectFileName() const override {
- auto ObjName = Strings.getStringForID(Entry.ObjNI);
- assert(ObjName && "InjectedSourceStream should have rejected this");
- return *ObjName;
+ StringRef Ret = cantFail(Strings.getStringForID(Entry.ObjNI),
+ "InjectedSourceStream should have rejected this");
+ return Ret;
}
std::string getVirtualFileName() const override {
- auto VName = Strings.getStringForID(Entry.VFileNI);
- assert(VName && "InjectedSourceStream should have rejected this");
- return *VName;
+ StringRef Ret = cantFail(Strings.getStringForID(Entry.VFileNI),
+ "InjectedSourceStream should have rejected this");
+ return Ret;
}
uint32_t getCompression() const override { return Entry.Compression; }
std::string getCode() const override {
// Get name of stream storing the data.
- auto VName = Strings.getStringForID(Entry.VFileNI);
- assert(VName && "InjectedSourceStream should have rejected this");
- std::string StreamName = ("/src/files/" + *VName).str();
+ StringRef VName =
+ cantFail(Strings.getStringForID(Entry.VFileNI),
+ "InjectedSourceStream should have rejected this");
+ std::string StreamName = ("/src/files/" + VName).str();
// Find stream with that name and read its data.
// FIXME: Consider validating (or even loading) all this in
@@ -104,14 +105,14 @@ std::unique_ptr<IPDBInjectedSource>
NativeEnumInjectedSources::getChildAtIndex(uint32_t N) const {
if (N >= getChildCount())
return nullptr;
- return make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
+ return std::make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
File, Strings);
}
std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() {
if (Cur == Stream.end())
return nullptr;
- return make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
+ return std::make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
}
void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }
diff --git a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index 8e43cf24495a..2ad552470b61 100644
--- a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -30,68 +30,68 @@ void NativeRawSymbol::dump(raw_ostream &OS, int Indent,
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildren(PDB_SymType Type) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildren(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags, uint32_t Section, uint32_t Offset) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags, uint64_t VA) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
PDB_NameSearchFlags Flags, uint32_t RVA) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findInlineFramesByAddr(uint32_t Section,
uint32_t Offset) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumSymbols>
NativeRawSymbol::findInlineFramesByVA(uint64_t VA) const {
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLines() const {
- return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
uint32_t Length) const {
- return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
- return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
}
std::unique_ptr<IPDBEnumLineNumbers>
NativeRawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
- return llvm::make_unique<NullEnumerator<IPDBLineNumber>>();
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
}
void NativeRawSymbol::getDataBytes(SmallVector<uint8_t, 32> &bytes) const {
diff --git a/lib/DebugInfo/PDB/Native/NativeSession.cpp b/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 8a49cb1c5963..b45a5881dcb5 100644
--- a/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -59,18 +59,18 @@ NativeSession::~NativeSession() = default;
Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
std::unique_ptr<IPDBSession> &Session) {
StringRef Path = Buffer->getBufferIdentifier();
- auto Stream = llvm::make_unique<MemoryBufferByteStream>(
+ auto Stream = std::make_unique<MemoryBufferByteStream>(
std::move(Buffer), llvm::support::little);
- auto Allocator = llvm::make_unique<BumpPtrAllocator>();
- auto File = llvm::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
+ auto Allocator = std::make_unique<BumpPtrAllocator>();
+ auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
if (auto EC = File->parseFileHeaders())
return EC;
if (auto EC = File->parseStreamData())
return EC;
Session =
- llvm::make_unique<NativeSession>(std::move(File), std::move(Allocator));
+ std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
return Error::success();
}
@@ -202,7 +202,7 @@ NativeSession::getInjectedSources() const {
consumeError(Strings.takeError());
return nullptr;
}
- return make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
+ return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
}
std::unique_ptr<IPDBEnumSectionContribs>
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
index 9f5e86281a23..26ccb7daece0 100644
--- a/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
@@ -163,14 +163,14 @@ void NativeTypeEnum::dump(raw_ostream &OS, int Indent,
std::unique_ptr<IPDBEnumSymbols>
NativeTypeEnum::findChildren(PDB_SymType Type) const {
if (Type != PDB_SymType::Data)
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
const NativeTypeEnum *ClassParent = nullptr;
if (!Modifiers)
ClassParent = this;
else
ClassParent = UnmodifiedType;
- return llvm::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
+ return std::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
}
PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
diff --git a/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
index 405303469c18..f98a4c3043eb 100644
--- a/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
+++ b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
@@ -65,7 +65,7 @@ private:
std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
if (!S)
return nullptr;
- auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
+ auto NTFA = std::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
return PDBSymbol::create(Session, std::move(NTFA));
}
NativeSession &Session;
@@ -133,9 +133,9 @@ void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
std::unique_ptr<IPDBEnumSymbols>
NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
if (Type != PDB_SymType::FunctionArg)
- return llvm::make_unique<NullEnumerator<PDBSymbol>>();
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
- auto NET = llvm::make_unique<NativeEnumTypes>(Session,
+ auto NET = std::make_unique<NativeEnumTypes>(Session,
/* copy */ ArgList.ArgIndices);
return std::unique_ptr<IPDBEnumSymbols>(
new NativeEnumFunctionArgs(Session, std::move(NET)));
diff --git a/lib/DebugInfo/PDB/Native/PDBFile.cpp b/lib/DebugInfo/PDB/Native/PDBFile.cpp
index 983031dfcb78..9ac226b89139 100644
--- a/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -264,7 +264,7 @@ Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
safelyCreateIndexedStream(DbiS->getGlobalSymbolStreamIndex());
if (!GlobalS)
return GlobalS.takeError();
- auto TempGlobals = llvm::make_unique<GlobalsStream>(std::move(*GlobalS));
+ auto TempGlobals = std::make_unique<GlobalsStream>(std::move(*GlobalS));
if (auto EC = TempGlobals->reload())
return std::move(EC);
Globals = std::move(TempGlobals);
@@ -277,7 +277,7 @@ Expected<InfoStream &> PDBFile::getPDBInfoStream() {
auto InfoS = safelyCreateIndexedStream(StreamPDB);
if (!InfoS)
return InfoS.takeError();
- auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS));
+ auto TempInfo = std::make_unique<InfoStream>(std::move(*InfoS));
if (auto EC = TempInfo->reload())
return std::move(EC);
Info = std::move(TempInfo);
@@ -290,7 +290,7 @@ Expected<DbiStream &> PDBFile::getPDBDbiStream() {
auto DbiS = safelyCreateIndexedStream(StreamDBI);
if (!DbiS)
return DbiS.takeError();
- auto TempDbi = llvm::make_unique<DbiStream>(std::move(*DbiS));
+ auto TempDbi = std::make_unique<DbiStream>(std::move(*DbiS));
if (auto EC = TempDbi->reload(this))
return std::move(EC);
Dbi = std::move(TempDbi);
@@ -303,7 +303,7 @@ Expected<TpiStream &> PDBFile::getPDBTpiStream() {
auto TpiS = safelyCreateIndexedStream(StreamTPI);
if (!TpiS)
return TpiS.takeError();
- auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS));
+ auto TempTpi = std::make_unique<TpiStream>(*this, std::move(*TpiS));
if (auto EC = TempTpi->reload())
return std::move(EC);
Tpi = std::move(TempTpi);
@@ -319,7 +319,7 @@ Expected<TpiStream &> PDBFile::getPDBIpiStream() {
auto IpiS = safelyCreateIndexedStream(StreamIPI);
if (!IpiS)
return IpiS.takeError();
- auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS));
+ auto TempIpi = std::make_unique<TpiStream>(*this, std::move(*IpiS));
if (auto EC = TempIpi->reload())
return std::move(EC);
Ipi = std::move(TempIpi);
@@ -337,7 +337,7 @@ Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
safelyCreateIndexedStream(DbiS->getPublicSymbolStreamIndex());
if (!PublicS)
return PublicS.takeError();
- auto TempPublics = llvm::make_unique<PublicsStream>(std::move(*PublicS));
+ auto TempPublics = std::make_unique<PublicsStream>(std::move(*PublicS));
if (auto EC = TempPublics->reload())
return std::move(EC);
Publics = std::move(TempPublics);
@@ -356,7 +356,7 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
if (!SymbolS)
return SymbolS.takeError();
- auto TempSymbols = llvm::make_unique<SymbolStream>(std::move(*SymbolS));
+ auto TempSymbols = std::make_unique<SymbolStream>(std::move(*SymbolS));
if (auto EC = TempSymbols->reload())
return std::move(EC);
Symbols = std::move(TempSymbols);
@@ -370,7 +370,7 @@ Expected<PDBStringTable &> PDBFile::getStringTable() {
if (!NS)
return NS.takeError();
- auto N = llvm::make_unique<PDBStringTable>();
+ auto N = std::make_unique<PDBStringTable>();
BinaryStreamReader Reader(**NS);
if (auto EC = N->reload(Reader))
return std::move(EC);
@@ -391,7 +391,7 @@ Expected<InjectedSourceStream &> PDBFile::getInjectedSourceStream() {
if (!Strings)
return Strings.takeError();
- auto IJ = llvm::make_unique<InjectedSourceStream>(std::move(*IJS));
+ auto IJ = std::make_unique<InjectedSourceStream>(std::move(*IJS));
if (auto EC = IJ->reload(*Strings))
return std::move(EC);
InjectedSources = std::move(IJ);
diff --git a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index 8f5a048ea4b5..aa3288724390 100644
--- a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -22,7 +22,7 @@
#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
#include "llvm/Support/BinaryStream.h"
#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/JamCRC.h"
+#include "llvm/Support/CRC.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/xxhash.h"
@@ -42,7 +42,7 @@ Error PDBFileBuilder::initialize(uint32_t BlockSize) {
auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
if (!ExpectedMsf)
return ExpectedMsf.takeError();
- Msf = llvm::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
+ Msf = std::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
return Error::success();
}
@@ -50,25 +50,25 @@ MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
if (!Info)
- Info = llvm::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
+ Info = std::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
return *Info;
}
DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
if (!Dbi)
- Dbi = llvm::make_unique<DbiStreamBuilder>(*Msf);
+ Dbi = std::make_unique<DbiStreamBuilder>(*Msf);
return *Dbi;
}
TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
if (!Tpi)
- Tpi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
+ Tpi = std::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
return *Tpi;
}
TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
if (!Ipi)
- Ipi = llvm::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
+ Ipi = std::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
return *Ipi;
}
@@ -78,7 +78,7 @@ PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() {
if (!Gsi)
- Gsi = llvm::make_unique<GSIStreamBuilder>(*Msf);
+ Gsi = std::make_unique<GSIStreamBuilder>(*Msf);
return *Gsi;
}
@@ -174,8 +174,7 @@ Error PDBFileBuilder::finalizeMsfLayout() {
if (!InjectedSources.empty()) {
for (const auto &IS : InjectedSources) {
JamCRC CRC(0);
- CRC.update(makeArrayRef(IS.Content->getBufferStart(),
- IS.Content->getBufferSize()));
+ CRC.update(arrayRefFromStringRef(IS.Content->getBuffer()));
SrcHeaderBlockEntry Entry;
::memset(&Entry, 0, sizeof(SrcHeaderBlockEntry));
diff --git a/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/lib/DebugInfo/PDB/Native/TpiHashing.cpp
index b21b82bf76fd..b71b2b158144 100644
--- a/lib/DebugInfo/PDB/Native/TpiHashing.cpp
+++ b/lib/DebugInfo/PDB/Native/TpiHashing.cpp
@@ -10,7 +10,7 @@
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/Support/JamCRC.h"
+#include "llvm/Support/CRC.h"
using namespace llvm;
using namespace llvm::codeview;
@@ -124,8 +124,6 @@ Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) {
// Run CRC32 over the bytes. This corresponds to `hashBufv8`.
JamCRC JC(/*Init=*/0U);
- ArrayRef<char> Bytes(reinterpret_cast<const char *>(Rec.data().data()),
- Rec.data().size());
- JC.update(Bytes);
+ JC.update(Rec.data());
return JC.getCRC();
}
diff --git a/lib/DebugInfo/PDB/Native/TpiStream.cpp b/lib/DebugInfo/PDB/Native/TpiStream.cpp
index 8ee7f897b8bb..ac19db03fab2 100644
--- a/lib/DebugInfo/PDB/Native/TpiStream.cpp
+++ b/lib/DebugInfo/PDB/Native/TpiStream.cpp
@@ -112,7 +112,7 @@ Error TpiStream::reload() {
HashStream = std::move(*HS);
}
- Types = llvm::make_unique<LazyRandomTypeCollection>(
+ Types = std::make_unique<LazyRandomTypeCollection>(
TypeRecords, getNumTypeRecords(), getTypeIndexOffsets());
return Error::success();
}
diff --git a/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 6b308453c2de..4f10f8524a9b 100644
--- a/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -135,7 +135,7 @@ Error TpiStreamBuilder::finalizeMsfLayout() {
reinterpret_cast<const uint8_t *>(HashBuffer.data()),
calculateHashBufferSize());
HashValueStream =
- llvm::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
+ std::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
}
return Error::success();
}
diff --git a/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
index 7c3ba981fd6b..cb0329bc0ed7 100644
--- a/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -79,7 +79,7 @@ private:
std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
PDBSymbolFunc::getArguments() const {
- return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
+ return std::make_unique<FunctionArgEnumerator>(Session, *this);
}
void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
index 292320a6fe6d..1373615522eb 100644
--- a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
+++ b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
@@ -63,7 +63,7 @@ private:
std::unique_ptr<IPDBEnumSymbols>
PDBSymbolTypeFunctionSig::getArguments() const {
- return llvm::make_unique<FunctionArgEnumerator>(Session, *this);
+ return std::make_unique<FunctionArgEnumerator>(Session, *this);
}
void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const {
diff --git a/lib/DebugInfo/PDB/UDTLayout.cpp b/lib/DebugInfo/PDB/UDTLayout.cpp
index acb1599480b0..a8e1d0a619ca 100644
--- a/lib/DebugInfo/PDB/UDTLayout.cpp
+++ b/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -71,7 +71,7 @@ DataMemberLayoutItem::DataMemberLayoutItem(
DataMember(std::move(Member)) {
auto Type = DataMember->getType();
if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
- UdtLayout = llvm::make_unique<ClassLayout>(std::move(UDT));
+ UdtLayout = std::make_unique<ClassLayout>(std::move(UDT));
UsedBytes = UdtLayout->usedBytes();
}
}
@@ -84,7 +84,7 @@ VBPtrLayoutItem::VBPtrLayoutItem(const UDTLayoutBase &Parent,
}
const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
- return *dyn_cast<PDBSymbolData>(Symbol);
+ return *cast<PDBSymbolData>(Symbol);
}
bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
@@ -205,7 +205,7 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
for (auto &Base : Bases) {
uint32_t Offset = Base->getOffset();
// Non-virtual bases never get elided.
- auto BL = llvm::make_unique<BaseClassLayout>(*this, Offset, false,
+ auto BL = std::make_unique<BaseClassLayout>(*this, Offset, false,
std::move(Base));
AllBases.push_back(BL.get());
@@ -216,7 +216,7 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
assert(VTables.size() <= 1);
if (!VTables.empty()) {
auto VTLayout =
- llvm::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
+ std::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
VTable = VTLayout.get();
@@ -224,7 +224,7 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
}
for (auto &Data : Members) {
- auto DM = llvm::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
+ auto DM = std::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
addChildToLayout(std::move(DM));
}
@@ -236,7 +236,7 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
int VBPO = VB->getVirtualBasePointerOffset();
if (!hasVBPtrAtOffset(VBPO)) {
if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
- auto VBPL = llvm::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
+ auto VBPL = std::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
VBPO, VBP->getLength());
VBPtr = VBPL.get();
addChildToLayout(std::move(VBPL));
@@ -250,7 +250,7 @@ void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
uint32_t Offset = UsedBytes.find_last() + 1;
bool Elide = (Parent != nullptr);
auto BL =
- llvm::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
+ std::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
AllBases.push_back(BL.get());
// Only lay this virtual base out directly inside of *this* class if this
diff --git a/lib/DebugInfo/Symbolize/DIPrinter.cpp b/lib/DebugInfo/Symbolize/DIPrinter.cpp
index b2bfef251485..b1a80cbc4580 100644
--- a/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -30,11 +30,6 @@
namespace llvm {
namespace symbolize {
-// By default, DILineInfo contains "<invalid>" for function/filename it
-// cannot fetch. We replace it to "??" to make our output closer to addr2line.
-static const char kDILineInfoBadString[] = "<invalid>";
-static const char kBadString[] = "??";
-
// Prints source code around in the FileName the Line.
void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
if (PrintSourceContext <= 0)
@@ -68,16 +63,16 @@ void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
if (PrintFunctionNames) {
std::string FunctionName = Info.FunctionName;
- if (FunctionName == kDILineInfoBadString)
- FunctionName = kBadString;
+ if (FunctionName == DILineInfo::BadString)
+ FunctionName = DILineInfo::Addr2LineBadString;
StringRef Delimiter = PrintPretty ? " at " : "\n";
StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
OS << Prefix << FunctionName << Delimiter;
}
std::string Filename = Info.FileName;
- if (Filename == kDILineInfoBadString)
- Filename = kBadString;
+ if (Filename == DILineInfo::BadString)
+ Filename = DILineInfo::Addr2LineBadString;
else if (Basenames)
Filename = llvm::sys::path::filename(Filename);
if (!Verbose) {
@@ -115,8 +110,8 @@ DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
std::string Name = Global.Name;
- if (Name == kDILineInfoBadString)
- Name = kBadString;
+ if (Name == DILineInfo::BadString)
+ Name = DILineInfo::Addr2LineBadString;
OS << Name << "\n";
OS << Global.Start << " " << Global.Size << "\n";
return *this;
diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 2765bf44d504..b4d49d9ff958 100644
--- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -43,20 +43,22 @@ getDILineInfoSpecifier(FunctionNameKind FNKind) {
ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
SymbolizableObjectFile::create(const object::ObjectFile *Obj,
- std::unique_ptr<DIContext> DICtx) {
+ std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses) {
assert(DICtx);
std::unique_ptr<SymbolizableObjectFile> res(
- new SymbolizableObjectFile(Obj, std::move(DICtx)));
+ new SymbolizableObjectFile(Obj, std::move(DICtx), UntagAddresses));
std::unique_ptr<DataExtractor> OpdExtractor;
uint64_t OpdAddress = 0;
// Find the .opd (function descriptor) section if any, for big-endian
// PowerPC64 ELF.
if (Obj->getArch() == Triple::ppc64) {
for (section_iterator Section : Obj->sections()) {
- StringRef Name;
- if (auto EC = Section->getName(Name))
- return EC;
- if (Name == ".opd") {
+ Expected<StringRef> NameOrErr = Section->getName();
+ if (!NameOrErr)
+ return errorToErrorCode(NameOrErr.takeError());
+
+ if (*NameOrErr == ".opd") {
Expected<StringRef> E = Section->getContents();
if (!E)
return errorToErrorCode(E.takeError());
@@ -103,8 +105,10 @@ SymbolizableObjectFile::create(const object::ObjectFile *Obj,
}
SymbolizableObjectFile::SymbolizableObjectFile(const ObjectFile *Obj,
- std::unique_ptr<DIContext> DICtx)
- : Module(Obj), DebugInfoContext(std::move(DICtx)) {}
+ std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses)
+ : Module(Obj), DebugInfoContext(std::move(DICtx)),
+ UntagAddresses(UntagAddresses) {}
namespace {
@@ -172,6 +176,12 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
if (!SymbolAddressOrErr)
return errorToErrorCode(SymbolAddressOrErr.takeError());
uint64_t SymbolAddress = *SymbolAddressOrErr;
+ if (UntagAddresses) {
+ // For kernel addresses, bits 56-63 need to be set, so we sign extend bit 55
+ // into bits 56-63 instead of masking them out.
+ SymbolAddress &= (1ull << 56) - 1;
+ SymbolAddress = (int64_t(SymbolAddress) << 8) >> 8;
+ }
if (OpdExtractor) {
// For big-endian PowerPC64 ELF, symbols in the .opd section refer to
// function descriptors. The first word of the descriptor is a pointer to
@@ -179,10 +189,8 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol,
// For the purposes of symbolization, pretend the symbol's address is that
// of the function's code, not the descriptor.
uint64_t OpdOffset = SymbolAddress - OpdAddress;
- uint32_t OpdOffset32 = OpdOffset;
- if (OpdOffset == OpdOffset32 &&
- OpdExtractor->isValidOffsetForAddress(OpdOffset32))
- SymbolAddress = OpdExtractor->getAddress(&OpdOffset32);
+ if (OpdExtractor->isValidOffsetForAddress(OpdOffset))
+ SymbolAddress = OpdExtractor->getAddress(&OpdOffset);
}
Expected<StringRef> SymbolNameOrErr = Symbol.getName();
if (!SymbolNameOrErr)
diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index 9cab94178c1b..b5b9793a44d9 100644
--- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -31,7 +31,8 @@ namespace symbolize {
class SymbolizableObjectFile : public SymbolizableModule {
public:
static ErrorOr<std::unique_ptr<SymbolizableObjectFile>>
- create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx);
+ create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses);
DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
FunctionNameKind FNKind,
@@ -70,6 +71,7 @@ private:
const object::ObjectFile *Module;
std::unique_ptr<DIContext> DebugInfoContext;
+ bool UntagAddresses;
struct SymbolDesc {
uint64_t Addr;
@@ -85,7 +87,8 @@ private:
std::vector<std::pair<SymbolDesc, StringRef>> Objects;
SymbolizableObjectFile(const object::ObjectFile *Obj,
- std::unique_ptr<DIContext> DICtx);
+ std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses);
};
} // end namespace symbolize
diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp
index 6a619f8f2f37..be79d9e637c1 100644
--- a/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -35,19 +35,6 @@
#include <cassert>
#include <cstring>
-#if defined(_MSC_VER)
-#include <Windows.h>
-
-// This must be included after windows.h.
-#include <DbgHelp.h>
-#pragma comment(lib, "dbghelp.lib")
-
-// Windows.h conflicts with our COFF header definitions.
-#ifdef IMAGE_FILE_MACHINE_I386
-#undef IMAGE_FILE_MACHINE_I386
-#endif
-#endif
-
namespace llvm {
namespace symbolize {
@@ -205,7 +192,7 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
MemoryBuffer::getFileOrSTDIN(Path);
if (!MB)
return false;
- return CRCHash == llvm::crc32(0, MB.get()->getBuffer());
+ return CRCHash == llvm::crc32(arrayRefFromStringRef(MB.get()->getBuffer()));
}
bool findDebugBinary(const std::string &OrigPath,
@@ -259,7 +246,11 @@ bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName,
return false;
for (const SectionRef &Section : Obj->sections()) {
StringRef Name;
- Section.getName(Name);
+ if (Expected<StringRef> NameOrErr = Section.getName())
+ Name = *NameOrErr;
+ else
+ consumeError(NameOrErr.takeError());
+
Name = Name.substr(Name.find_first_not_of("._"));
if (Name == "gnu_debuglink") {
Expected<StringRef> ContentsOrErr = Section.getContents();
@@ -268,7 +259,7 @@ bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName,
return false;
}
DataExtractor DE(*ContentsOrErr, Obj->isLittleEndian(), 0);
- uint32_t Offset = 0;
+ uint64_t Offset = 0;
if (const char *DebugNameStr = DE.getCStr(&Offset)) {
// 4-byte align the offset.
Offset = (Offset + 3) & ~0x3;
@@ -397,7 +388,7 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path,
return I->second.get();
Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
- UB->getObjectForArch(ArchName);
+ UB->getMachOObjectForArch(ArchName);
if (!ObjOrErr) {
ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
std::unique_ptr<ObjectFile>());
@@ -418,8 +409,8 @@ Expected<SymbolizableModule *>
LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
std::unique_ptr<DIContext> Context,
StringRef ModuleName) {
- auto InfoOrErr =
- SymbolizableObjectFile::create(Obj, std::move(Context));
+ auto InfoOrErr = SymbolizableObjectFile::create(Obj, std::move(Context),
+ Opts.UntagAddresses);
std::unique_ptr<SymbolizableModule> SymMod;
if (InfoOrErr)
SymMod = std::move(*InfoOrErr);
@@ -530,21 +521,20 @@ LLVMSymbolizer::DemangleName(const std::string &Name,
return Result;
}
-#if defined(_MSC_VER)
if (!Name.empty() && Name.front() == '?') {
// Only do MSVC C++ demangling on symbols starting with '?'.
- char DemangledName[1024] = {0};
- DWORD result = ::UnDecorateSymbolName(
- Name.c_str(), DemangledName, 1023,
- UNDNAME_NO_ACCESS_SPECIFIERS | // Strip public, private, protected
- UNDNAME_NO_ALLOCATION_LANGUAGE | // Strip __thiscall, __stdcall, etc
- UNDNAME_NO_THROW_SIGNATURES | // Strip throw() specifications
- UNDNAME_NO_MEMBER_TYPE | // Strip virtual, static, etc specifiers
- UNDNAME_NO_MS_KEYWORDS | // Strip all MS extension keywords
- UNDNAME_NO_FUNCTION_RETURNS); // Strip function return types
- return (result == 0) ? Name : std::string(DemangledName);
+ int status = 0;
+ char *DemangledName = microsoftDemangle(
+ Name.c_str(), nullptr, nullptr, &status,
+ MSDemangleFlags(MSDF_NoAccessSpecifier | MSDF_NoCallingConvention |
+ MSDF_NoMemberType | MSDF_NoReturnType));
+ if (status != 0)
+ return Name;
+ std::string Result = DemangledName;
+ free(DemangledName);
+ return Result;
}
-#endif
+
if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module())
return std::string(demanglePE32ExternCFunc(Name));
return Name;