diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/DebugInfo | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Notes
Diffstat (limited to 'lib/DebugInfo')
175 files changed, 2556 insertions, 1625 deletions
diff --git a/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp b/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp index 8828671d9be9..86a6f9eebfa2 100644 --- a/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp +++ b/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp @@ -1,9 +1,8 @@ //===- AppendingTypeTableBuilder.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 // //===----------------------------------------------------------------------===// @@ -50,13 +49,8 @@ Optional<TypeIndex> AppendingTypeTableBuilder::getNext(TypeIndex Prev) { return Prev; } -CVType AppendingTypeTableBuilder::getType(TypeIndex Index) { - CVType Type; - Type.RecordData = SeenRecords[Index.toArrayIndex()]; - const RecordPrefix *P = - reinterpret_cast<const RecordPrefix *>(Type.RecordData.data()); - Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind)); - return Type; +CVType AppendingTypeTableBuilder::getType(TypeIndex Index){ + return CVType(SeenRecords[Index.toArrayIndex()]); } StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) { diff --git a/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp index cbcaa5692828..48b9b0496ffe 100644 --- a/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp +++ b/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp @@ -1,9 +1,8 @@ //===- CVSymbolVisitor.cpp --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -21,7 +20,7 @@ CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks) template <typename T> static Error visitKnownRecord(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks) { - SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.Type); + SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.kind()); T KnownRecord(RK); if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord)) return EC; @@ -30,7 +29,7 @@ static Error visitKnownRecord(CVSymbol &Record, static Error finishVisitation(CVSymbol &Record, SymbolVisitorCallbacks &Callbacks) { - switch (Record.Type) { + switch (Record.kind()) { default: if (auto EC = Callbacks.visitUnknownSymbol(Record)) return EC; diff --git a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp index a4182a3b2fa1..ec4773d571c8 100644 --- a/lib/DebugInfo/CodeView/CVTypeVisitor.cpp +++ b/lib/DebugInfo/CodeView/CVTypeVisitor.cpp @@ -1,9 +1,8 @@ //===- CVTypeVisitor.cpp ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -23,7 +22,7 @@ using namespace llvm::codeview; template <typename T> static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) { - TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Type); + TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind()); T KnownRecord(RK); if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord)) return EC; @@ -97,7 +96,7 @@ CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks) : Callbacks(Callbacks) {} Error CVTypeVisitor::finishVisitation(CVType &Record) { - switch (Record.Type) { + switch (Record.kind()) { default: if (auto EC = Callbacks.visitUnknownType(Record)) return EC; @@ -210,6 +209,14 @@ 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; @@ -223,6 +230,13 @@ 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/CodeViewError.cpp b/lib/DebugInfo/CodeView/CodeViewError.cpp index 2a9753add311..69390c708f59 100644 --- a/lib/DebugInfo/CodeView/CodeViewError.cpp +++ b/lib/DebugInfo/CodeView/CodeViewError.cpp @@ -1,9 +1,8 @@ //===- CodeViewError.cpp - Error extensions for CodeView --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -14,6 +13,7 @@ using namespace llvm; using namespace llvm::codeview; +namespace { // FIXME: This class is only here to support the transition to llvm::Error. It // will be removed once this transition is complete. Clients should prefer to // deal with the Error value directly, rather than converting to error_code. @@ -39,6 +39,7 @@ public: llvm_unreachable("Unrecognized cv_error_code"); } }; +} // namespace static llvm::ManagedStatic<CodeViewErrorCategory> CodeViewErrCategory; const std::error_category &llvm::codeview::CVErrorCategory() { diff --git a/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp index 4fc14480578e..2f49474115a1 100644 --- a/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp +++ b/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp @@ -1,9 +1,8 @@ //===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -21,6 +20,7 @@ Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) { Limit.MaxLength = MaxLength; Limit.BeginOffset = getCurrentOffset(); Limits.push_back(Limit); + resetStreamedLen(); return Error::success(); } @@ -35,10 +35,29 @@ Error CodeViewRecordIO::endRecord() { // we don't know how big the record is until we're finished writing it, so // even though we don't commit the extraneous data, we still can't guarantee // we're at the end of the allocated data. + + if (isStreaming()) { + // For streaming mode, add padding to align with 4 byte boundaries for each + // record + uint32_t Align = getStreamedLen() % 4; + if (Align == 0) + return Error::success(); + + int PaddingBytes = 4 - Align; + while (PaddingBytes > 0) { + char Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes); + StringRef BytesSR = StringRef(&Pad, sizeof(Pad)); + Streamer->EmitBytes(BytesSR); + --PaddingBytes; + } + } return Error::success(); } uint32_t CodeViewRecordIO::maxFieldLength() const { + if (isStreaming()) + return 0; + assert(!Limits.empty() && "Not in a record!"); // The max length of the next field is the minimum of all lengths that would @@ -78,8 +97,13 @@ Error CodeViewRecordIO::skipPadding() { return Reader->skip(BytesToAdvance); } -Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) { - if (isWriting()) { +Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes, + const Twine &Comment) { + if (isStreaming()) { + emitComment(Comment); + Streamer->EmitBinaryData(toStringRef(Bytes)); + incrStreamedLen(Bytes.size()); + } else if (isWriting()) { if (auto EC = Writer->writeBytes(Bytes)) return EC; } else { @@ -89,9 +113,10 @@ Error CodeViewRecordIO::mapByteVectorTail(ArrayRef<uint8_t> &Bytes) { return Error::success(); } -Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) { +Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes, + const Twine &Comment) { ArrayRef<uint8_t> BytesRef(Bytes); - if (auto EC = mapByteVectorTail(BytesRef)) + if (auto EC = mapByteVectorTail(BytesRef, Comment)) return EC; if (!isWriting()) Bytes.assign(BytesRef.begin(), BytesRef.end()); @@ -99,22 +124,31 @@ Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes) { return Error::success(); } -Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd) { - if (isWriting()) { +Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) { + if (isStreaming()) { + emitComment(Comment); + Streamer->EmitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex())); + incrStreamedLen(sizeof(TypeInd.getIndex())); + } else if (isWriting()) { if (auto EC = Writer->writeInteger(TypeInd.getIndex())) return EC; - return Error::success(); + } else { + uint32_t I; + if (auto EC = Reader->readInteger(I)) + return EC; + TypeInd.setIndex(I); } - - uint32_t I; - if (auto EC = Reader->readInteger(I)) - return EC; - TypeInd.setIndex(I); return Error::success(); } -Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { - if (isWriting()) { +Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value, + const Twine &Comment) { + if (isStreaming()) { + if (Value >= 0) + emitEncodedUnsignedInteger(static_cast<uint64_t>(Value), Comment); + else + emitEncodedSignedInteger(Value, Comment); + } else if (isWriting()) { if (Value >= 0) { if (auto EC = writeEncodedUnsignedInteger(static_cast<uint64_t>(Value))) return EC; @@ -132,8 +166,11 @@ Error CodeViewRecordIO::mapEncodedInteger(int64_t &Value) { return Error::success(); } -Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { - if (isWriting()) { +Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value, + const Twine &Comment) { + if (isStreaming()) + emitEncodedUnsignedInteger(Value, Comment); + else if (isWriting()) { if (auto EC = writeEncodedUnsignedInteger(Value)) return EC; } else { @@ -145,18 +182,28 @@ Error CodeViewRecordIO::mapEncodedInteger(uint64_t &Value) { return Error::success(); } -Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value) { - if (isWriting()) { +Error CodeViewRecordIO::mapEncodedInteger(APSInt &Value, const Twine &Comment) { + if (isStreaming()) { + if (Value.isSigned()) + emitEncodedSignedInteger(Value.getSExtValue(), Comment); + else + emitEncodedUnsignedInteger(Value.getZExtValue(), Comment); + } else if (isWriting()) { if (Value.isSigned()) return writeEncodedSignedInteger(Value.getSExtValue()); return writeEncodedUnsignedInteger(Value.getZExtValue()); - } - - return consume(*Reader, Value); + } else + return consume(*Reader, Value); + return Error::success(); } -Error CodeViewRecordIO::mapStringZ(StringRef &Value) { - if (isWriting()) { +Error CodeViewRecordIO::mapStringZ(StringRef &Value, const Twine &Comment) { + if (isStreaming()) { + auto NullTerminatedString = StringRef(Value.data(), Value.size() + 1); + emitComment(Comment); + Streamer->EmitBytes(NullTerminatedString); + incrStreamedLen(NullTerminatedString.size()); + } else if (isWriting()) { // Truncate if we attempt to write too much. StringRef S = Value.take_front(maxFieldLength() - 1); if (auto EC = Writer->writeCString(S)) @@ -168,8 +215,18 @@ Error CodeViewRecordIO::mapStringZ(StringRef &Value) { return Error::success(); } -Error CodeViewRecordIO::mapGuid(GUID &Guid) { +Error CodeViewRecordIO::mapGuid(GUID &Guid, const Twine &Comment) { constexpr uint32_t GuidSize = 16; + + if (isStreaming()) { + StringRef GuidSR = + StringRef((reinterpret_cast<const char *>(&Guid)), GuidSize); + emitComment(Comment); + Streamer->EmitBytes(GuidSR); + incrStreamedLen(GuidSize); + return Error::success(); + } + if (maxFieldLength() < GuidSize) return make_error<CodeViewError>(cv_error_code::insufficient_buffer); @@ -185,13 +242,17 @@ Error CodeViewRecordIO::mapGuid(GUID &Guid) { return Error::success(); } -Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) { - if (isWriting()) { +Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value, + const Twine &Comment) { + + if (!isReading()) { + emitComment(Comment); for (auto V : Value) { if (auto EC = mapStringZ(V)) return EC; } - if (auto EC = Writer->writeInteger<uint8_t>(0)) + uint8_t FinalZero = 0; + if (auto EC = mapInteger(FinalZero)) return EC; } else { StringRef S; @@ -206,6 +267,56 @@ Error CodeViewRecordIO::mapStringZVectorZ(std::vector<StringRef> &Value) { return Error::success(); } +void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value, + const Twine &Comment) { + assert(Value < 0 && "Encoded integer is not signed!"); + if (Value >= std::numeric_limits<int8_t>::min()) { + Streamer->EmitIntValue(LF_CHAR, 2); + emitComment(Comment); + Streamer->EmitIntValue(Value, 1); + incrStreamedLen(3); + } else if (Value >= std::numeric_limits<int16_t>::min()) { + Streamer->EmitIntValue(LF_SHORT, 2); + emitComment(Comment); + Streamer->EmitIntValue(Value, 2); + incrStreamedLen(4); + } else if (Value >= std::numeric_limits<int32_t>::min()) { + Streamer->EmitIntValue(LF_LONG, 2); + emitComment(Comment); + Streamer->EmitIntValue(Value, 4); + incrStreamedLen(6); + } else { + Streamer->EmitIntValue(LF_QUADWORD, 2); + emitComment(Comment); + Streamer->EmitIntValue(Value, 4); + incrStreamedLen(6); + } +} + +void CodeViewRecordIO::emitEncodedUnsignedInteger(const uint64_t &Value, + const Twine &Comment) { + if (Value < LF_NUMERIC) { + emitComment(Comment); + Streamer->EmitIntValue(Value, 2); + incrStreamedLen(2); + } else if (Value <= std::numeric_limits<uint16_t>::max()) { + Streamer->EmitIntValue(LF_USHORT, 2); + emitComment(Comment); + Streamer->EmitIntValue(Value, 2); + incrStreamedLen(4); + } else if (Value <= std::numeric_limits<uint32_t>::max()) { + Streamer->EmitIntValue(LF_ULONG, 2); + emitComment(Comment); + Streamer->EmitIntValue(Value, 4); + incrStreamedLen(6); + } else { + Streamer->EmitIntValue(LF_UQUADWORD, 2); + emitComment(Comment); + Streamer->EmitIntValue(Value, 8); + incrStreamedLen(6); + } +} + Error CodeViewRecordIO::writeEncodedSignedInteger(const int64_t &Value) { assert(Value < 0 && "Encoded integer is not signed!"); if (Value >= std::numeric_limits<int8_t>::min()) { diff --git a/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp b/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp index f180fc6990fc..799cffb7116e 100644 --- a/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp +++ b/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp @@ -66,14 +66,11 @@ void ContinuationRecordBuilder::begin(ContinuationRecordKind RecordKind) { InjectedSegmentBytes = ArrayRef<uint8_t>(FLIB, FLIB + sizeof(SegmentInjection)); - CVType Type; - Type.Type = getTypeLeafKind(RecordKind); + // Seed the first record with an appropriate record prefix. + RecordPrefix Prefix(getTypeLeafKind(RecordKind)); + CVType Type(&Prefix, sizeof(Prefix)); cantFail(Mapping.visitTypeBegin(Type)); - // Seed the first trecord with an appropriate record prefix. - RecordPrefix Prefix; - Prefix.RecordLen = 0; - Prefix.RecordKind = Type.Type; cantFail(SegmentWriter.writeObject(Prefix)); } @@ -156,14 +153,9 @@ CVType ContinuationRecordBuilder::createSegmentRecord( MutableArrayRef<uint8_t> Data = Buffer.data(); Data = Data.slice(OffBegin, OffEnd - OffBegin); - CVType Type; - Type.Type = getTypeLeafKind(*Kind); - Type.RecordData = Data; - // Write the length to the RecordPrefix, making sure it does not include // sizeof(RecordPrefix.Length) RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(Data.data()); - assert(Prefix->RecordKind == Type.Type); Prefix->RecordLen = Data.size() - sizeof(RecordPrefix::RecordLen); if (RefersTo.hasValue()) { @@ -175,12 +167,12 @@ CVType ContinuationRecordBuilder::createSegmentRecord( CR->IndexRef = RefersTo->getIndex(); } - return Type; + return CVType(Data); } std::vector<CVType> ContinuationRecordBuilder::end(TypeIndex Index) { - CVType Type; - Type.Type = getTypeLeafKind(*Kind); + RecordPrefix Prefix(getTypeLeafKind(*Kind)); + CVType Type(&Prefix, sizeof(Prefix)); cantFail(Mapping.visitTypeEnd(Type)); // We're now done, and we have a series of segments each beginning at an diff --git a/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp b/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp index 0f155a95d607..3d28bac00c44 100644 --- a/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugChecksumsSubsection.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp b/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp index cef27787cfd1..b23410409f88 100644 --- a/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugCrossExSubsection.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp b/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp index 4001741f560a..dbadafd3aaf3 100644 --- a/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugCrossImpSubsection.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp index 5881bf177a55..be8c32d5b294 100644 --- a/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugFrameDataSubsection.cpp -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp b/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp index 077c103a615b..48ec7e4ecdd6 100644 --- a/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugInlineeLinesSubsection.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp b/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp index 57ad40819fbc..ea16c0a6c671 100644 --- a/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugLinesSubsection.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp b/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp index 9b251f5931b3..63342749918d 100644 --- a/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugStringTableSubsection.cpp - CodeView String Table -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugSubsection.cpp b/lib/DebugInfo/CodeView/DebugSubsection.cpp index 67b428bfa713..3f93463fe6d6 100644 --- a/lib/DebugInfo/CodeView/DebugSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugSubsection.cpp -----------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp b/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp index 55f343c11e7f..0f704f286ee9 100644 --- a/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp +++ b/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp @@ -1,9 +1,8 @@ //===- DebugSubsectionRecord.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp b/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp index 9b824333369b..7968b6a2d757 100644 --- a/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp +++ b/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp @@ -1,9 +1,8 @@ //===- DebugSubsectionVisitor.cpp -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp b/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp index 60fbf9d747b2..52328967357b 100644 --- a/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp @@ -1,9 +1,8 @@ //===- DebugSymbolRVASubsection.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp b/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp index dc8ba8c929ae..c833103663e4 100644 --- a/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp +++ b/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp @@ -1,9 +1,8 @@ //===- DebugSymbolsSubsection.cpp -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -31,4 +30,4 @@ Error DebugSymbolsSubsection::commit(BinaryStreamWriter &Writer) const { void DebugSymbolsSubsection::addSymbol(CVSymbol Symbol) { Records.push_back(Symbol); Length += Symbol.length(); -}
\ No newline at end of file +} diff --git a/lib/DebugInfo/CodeView/EnumTables.cpp b/lib/DebugInfo/CodeView/EnumTables.cpp index ef4e42f79ebc..54e68ae4ea9f 100644 --- a/lib/DebugInfo/CodeView/EnumTables.cpp +++ b/lib/DebugInfo/CodeView/EnumTables.cpp @@ -1,9 +1,8 @@ //===- EnumTables.cpp - Enum to string conversion tables ------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -32,10 +31,20 @@ static const EnumEntry<TypeLeafKind> TypeLeafNames[] = { #undef CV_TYPE }; -static const EnumEntry<uint16_t> RegisterNames[] = { +static const EnumEntry<uint16_t> RegisterNames_X86[] = { +#define CV_REGISTERS_X86 +#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name), +#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" +#undef CV_REGISTER +#undef CV_REGISTERS_X86 +}; + +static const EnumEntry<uint16_t> RegisterNames_ARM64[] = { +#define CV_REGISTERS_ARM64 #define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name), #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" #undef CV_REGISTER +#undef CV_REGISTERS_ARM64 }; static const EnumEntry<uint32_t> PublicSymFlagNames[] = { @@ -87,6 +96,7 @@ static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = { CV_ENUM_ENT(SourceLanguage, ILAsm), CV_ENUM_ENT(SourceLanguage, Java), CV_ENUM_ENT(SourceLanguage, JScript), CV_ENUM_ENT(SourceLanguage, MSIL), CV_ENUM_ENT(SourceLanguage, HLSL), CV_ENUM_ENT(SourceLanguage, D), + CV_ENUM_ENT(SourceLanguage, Swift), }; static const EnumEntry<uint32_t> CompileSym2FlagNames[] = { @@ -171,6 +181,7 @@ static const EnumEntry<unsigned> CPUTypeNames[] = { CV_ENUM_CLASS_ENT(CPUType, ARM_XMAC), CV_ENUM_CLASS_ENT(CPUType, ARM_WMMX), CV_ENUM_CLASS_ENT(CPUType, ARM7), + CV_ENUM_CLASS_ENT(CPUType, ARM64), CV_ENUM_CLASS_ENT(CPUType, Omni), CV_ENUM_CLASS_ENT(CPUType, Ia64), CV_ENUM_CLASS_ENT(CPUType, Ia64_2), @@ -300,8 +311,11 @@ ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() { return makeArrayRef(TypeLeafNames); } -ArrayRef<EnumEntry<uint16_t>> getRegisterNames() { - return makeArrayRef(RegisterNames); +ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu) { + if (Cpu == CPUType::ARM64) { + return makeArrayRef(RegisterNames_ARM64); + } + return makeArrayRef(RegisterNames_X86); } ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames() { diff --git a/lib/DebugInfo/CodeView/Formatters.cpp b/lib/DebugInfo/CodeView/Formatters.cpp index b8d89c76da3b..a7a8c7ff82bf 100644 --- a/lib/DebugInfo/CodeView/Formatters.cpp +++ b/lib/DebugInfo/CodeView/Formatters.cpp @@ -1,9 +1,8 @@ //===- Formatters.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp b/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp index e76f9e12f0af..a7ad1d045f04 100644 --- a/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp +++ b/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp @@ -1,9 +1,8 @@ //===- GlobalTypeTableBuilder.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 // //===----------------------------------------------------------------------===// @@ -53,14 +52,7 @@ Optional<TypeIndex> GlobalTypeTableBuilder::getNext(TypeIndex Prev) { } CVType GlobalTypeTableBuilder::getType(TypeIndex Index) { - CVType Type; - Type.RecordData = SeenRecords[Index.toArrayIndex()]; - if (!Type.RecordData.empty()) { - assert(Type.RecordData.size() >= sizeof(RecordPrefix)); - const RecordPrefix *P = - reinterpret_cast<const RecordPrefix *>(Type.RecordData.data()); - Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind)); - } + CVType Type(SeenRecords[Index.toArrayIndex()]); return Type; } diff --git a/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp index ddcad8c631d7..dc1253b7a39f 100644 --- a/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp +++ b/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp @@ -1,9 +1,8 @@ //===- LazyRandomTypeCollection.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/Line.cpp b/lib/DebugInfo/CodeView/Line.cpp index 4cb766b5fd26..53adc8cac511 100644 --- a/lib/DebugInfo/CodeView/Line.cpp +++ b/lib/DebugInfo/CodeView/Line.cpp @@ -1,9 +1,8 @@ //===-- Line.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp b/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp index 8aee4aa2e2ae..4d7cd468f3ee 100644 --- a/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp +++ b/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp @@ -1,9 +1,8 @@ //===- MergingTypeTableBuilder.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 // //===----------------------------------------------------------------------===// @@ -53,11 +52,7 @@ Optional<TypeIndex> MergingTypeTableBuilder::getNext(TypeIndex Prev) { } CVType MergingTypeTableBuilder::getType(TypeIndex Index) { - CVType Type; - Type.RecordData = SeenRecords[Index.toArrayIndex()]; - const RecordPrefix *P = - reinterpret_cast<const RecordPrefix *>(Type.RecordData.data()); - Type.Type = static_cast<TypeLeafKind>(uint16_t(P->RecordKind)); + CVType Type(SeenRecords[Index.toArrayIndex()]); return Type; } diff --git a/lib/DebugInfo/CodeView/RecordName.cpp b/lib/DebugInfo/CodeView/RecordName.cpp index d868ae237a44..cfaad1581159 100644 --- a/lib/DebugInfo/CodeView/RecordName.cpp +++ b/lib/DebugInfo/CodeView/RecordName.cpp @@ -1,9 +1,8 @@ //===- RecordName.cpp ----------------------------------------- *- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/RecordSerialization.cpp b/lib/DebugInfo/CodeView/RecordSerialization.cpp index bff9a619a846..e7f032f9c670 100644 --- a/lib/DebugInfo/CodeView/RecordSerialization.cpp +++ b/lib/DebugInfo/CodeView/RecordSerialization.cpp @@ -1,9 +1,8 @@ //===-- RecordSerialization.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 // //===----------------------------------------------------------------------===// // diff --git a/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp b/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp index d28b7c3c2d83..654c40a7470d 100644 --- a/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp +++ b/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp @@ -3,13 +3,6 @@ using namespace llvm; using namespace llvm::codeview; -static void writeRecordPrefix(BinaryStreamWriter &Writer, TypeLeafKind Kind) { - RecordPrefix Prefix; - Prefix.RecordKind = Kind; - Prefix.RecordLen = 0; - cantFail(Writer.writeObject(Prefix)); -} - static void addPadding(BinaryStreamWriter &Writer) { uint32_t Align = Writer.getOffset() % 4; if (Align == 0) @@ -32,10 +25,12 @@ ArrayRef<uint8_t> SimpleTypeSerializer::serialize(T &Record) { BinaryStreamWriter Writer(ScratchBuffer, support::little); TypeRecordMapping Mapping(Writer); - CVType CVT; - CVT.Type = static_cast<TypeLeafKind>(Record.getKind()); + // Write the record prefix first with a dummy length but real kind. + RecordPrefix DummyPrefix(uint16_t(Record.getKind())); + cantFail(Writer.writeObject(DummyPrefix)); - writeRecordPrefix(Writer, CVT.Type); + RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(ScratchBuffer.data()); + CVType CVT(Prefix, sizeof(RecordPrefix)); cantFail(Mapping.visitTypeBegin(CVT)); cantFail(Mapping.visitKnownRecord(CVT, Record)); @@ -43,8 +38,7 @@ ArrayRef<uint8_t> SimpleTypeSerializer::serialize(T &Record) { addPadding(Writer); - RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(ScratchBuffer.data()); - + // Update the size and kind after serialization. Prefix->RecordKind = CVT.kind(); Prefix->RecordLen = Writer.getOffset() - sizeof(uint16_t); diff --git a/lib/DebugInfo/CodeView/StringsAndChecksums.cpp b/lib/DebugInfo/CodeView/StringsAndChecksums.cpp index 85d9dbb8c7df..9e204eec8604 100644 --- a/lib/DebugInfo/CodeView/StringsAndChecksums.cpp +++ b/lib/DebugInfo/CodeView/StringsAndChecksums.cpp @@ -1,9 +1,8 @@ //===- StringsAndChecksums.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/SymbolDumper.cpp b/lib/DebugInfo/CodeView/SymbolDumper.cpp index 04e0bab745d3..27cb7e35234b 100644 --- a/lib/DebugInfo/CodeView/SymbolDumper.cpp +++ b/lib/DebugInfo/CodeView/SymbolDumper.cpp @@ -1,9 +1,8 @@ //===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -102,10 +101,10 @@ void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) { } Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) { - W.startLine() << getSymbolKindName(CVR.Type); + W.startLine() << getSymbolKindName(CVR.kind()); W.getOStream() << " {\n"; W.indent(); - W.printEnum("Kind", unsigned(CVR.Type), getSymbolTypeNames()); + W.printEnum("Kind", unsigned(CVR.kind()), getSymbolTypeNames()); return Error::success(); } @@ -326,7 +325,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) { W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printBoolean("HasSpilledUDTMember", DefRangeRegisterRel.hasSpilledUDTMember()); W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent()); @@ -340,7 +339,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) { W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName); printLocalVariableAddrRange(DefRangeRegister.Range, DefRangeRegister.getRelocationOffset()); @@ -351,7 +350,7 @@ Error CVSymbolDumperImpl::visitKnownRecord( Error CVSymbolDumperImpl::visitKnownRecord( CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) { W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName); W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent); printLocalVariableAddrRange(DefRangeSubfieldRegister.Range, @@ -404,7 +403,8 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, FrameCookie.getRelocationOffset(), FrameCookie.CodeOffset, &LinkageName); } - W.printEnum("Register", uint16_t(FrameCookie.Register), getRegisterNames()); + W.printEnum("Register", uint16_t(FrameCookie.Register), + getRegisterNames(CompilationCPUType)); W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind), getFrameCookieKindNames()); W.printHex("Flags", FrameCookie.Flags); @@ -425,10 +425,10 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, getFrameProcSymFlagNames()); W.printEnum("LocalFramePtrReg", uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); W.printEnum("ParamFramePtrReg", uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)), - getRegisterNames()); + getRegisterNames(CompilationCPUType)); return Error::success(); } @@ -506,7 +506,8 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, RegisterSym &Register) { printTypeIndex("Type", Register.Index); - W.printEnum("Seg", uint16_t(Register.Register), getRegisterNames()); + W.printEnum("Seg", uint16_t(Register.Register), + getRegisterNames(CompilationCPUType)); W.printString("Name", Register.Name); return Error::success(); } @@ -600,7 +601,8 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, RegRelativeSym &RegRel) { W.printHex("Offset", RegRel.Offset); printTypeIndex("Type", RegRel.Type); - W.printEnum("Register", uint16_t(RegRel.Register), getRegisterNames()); + W.printEnum("Register", uint16_t(RegRel.Register), + getRegisterNames(CompilationCPUType)); W.printString("VarName", RegRel.Name); return Error::success(); } @@ -631,6 +633,18 @@ Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, return Error::success(); } +Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, + AnnotationSym &Annot) { + W.printHex("Offset", Annot.CodeOffset); + W.printHex("Segment", Annot.Segment); + + ListScope S(W, "Strings"); + for (StringRef Str : Annot.Strings) + W.printString(Str); + + return Error::success(); +} + Error CVSymbolDumperImpl::visitUnknownSymbol(CVSymbol &CVR) { W.printNumber("Length", CVR.length()); return Error::success(); diff --git a/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp b/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp index 01746138ad1f..51a5a9e9243e 100644 --- a/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp +++ b/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp @@ -1,9 +1,8 @@ //===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp index 2af8205cebc3..70889839ef48 100644 --- a/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp +++ b/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp @@ -1,9 +1,8 @@ //===- SymbolRecordMapping.cpp -----------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -472,6 +471,18 @@ Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, return Error::success(); } +Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, + AnnotationSym &Annot) { + + error(IO.mapInteger(Annot.CodeOffset)); + error(IO.mapInteger(Annot.Segment)); + error(IO.mapVectorN<uint16_t>( + Annot.Strings, + [](CodeViewRecordIO &IO, StringRef &S) { return IO.mapStringZ(S); })); + + return Error::success(); +} + RegisterId codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg, CPUType CPU) { assert(unsigned(EncodedReg) < 4); diff --git a/lib/DebugInfo/CodeView/SymbolSerializer.cpp b/lib/DebugInfo/CodeView/SymbolSerializer.cpp index 0071ecc85685..de9bb42b1798 100644 --- a/lib/DebugInfo/CodeView/SymbolSerializer.cpp +++ b/lib/DebugInfo/CodeView/SymbolSerializer.cpp @@ -1,9 +1,8 @@ //===- SymbolSerializer.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp index f5d3bea43a14..d5fea5ee5e29 100644 --- a/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp +++ b/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp @@ -1,9 +1,8 @@ //===-- TypeDumpVisitor.cpp - CodeView type info dumper ----------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -172,11 +171,11 @@ Error TypeDumpVisitor::visitTypeBegin(CVType &Record) { } Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) { - W->startLine() << getLeafTypeName(Record.Type); + W->startLine() << getLeafTypeName(Record.kind()); W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")"; W->getOStream() << " {\n"; W->indent(); - W->printEnum("TypeLeafKind", unsigned(Record.Type), + W->printEnum("TypeLeafKind", unsigned(Record.kind()), makeArrayRef(LeafTypeNames)); return Error::success(); } diff --git a/lib/DebugInfo/CodeView/TypeHashing.cpp b/lib/DebugInfo/CodeView/TypeHashing.cpp index 826faef35875..2dbc11a84f0b 100644 --- a/lib/DebugInfo/CodeView/TypeHashing.cpp +++ b/lib/DebugInfo/CodeView/TypeHashing.cpp @@ -1,9 +1,8 @@ //===- TypeHashing.cpp -------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -55,10 +54,16 @@ GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData, reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count); for (TypeIndex TI : Indices) { ArrayRef<uint8_t> BytesToHash; - if (TI.isSimple() || TI.isNoneType() || TI.toArrayIndex() >= Prev.size()) { + if (TI.isSimple() || TI.isNoneType()) { const uint8_t *IndexBytes = reinterpret_cast<const uint8_t *>(&TI); BytesToHash = makeArrayRef(IndexBytes, sizeof(TypeIndex)); } else { + if (TI.toArrayIndex() >= Prev.size() || + Prev[TI.toArrayIndex()].empty()) { + // There are references to yet-unhashed records. Suspend hashing for + // this record until all the other records are processed. + return {}; + } BytesToHash = Prev[TI.toArrayIndex()].Hash; } S.update(BytesToHash); diff --git a/lib/DebugInfo/CodeView/TypeIndex.cpp b/lib/DebugInfo/CodeView/TypeIndex.cpp index 332d67470da5..604d342448d3 100644 --- a/lib/DebugInfo/CodeView/TypeIndex.cpp +++ b/lib/DebugInfo/CodeView/TypeIndex.cpp @@ -1,9 +1,8 @@ //===-- TypeIndex.cpp - CodeView type index ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp index 839ab6f0a705..e84e1c9cea78 100644 --- a/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp +++ b/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp @@ -1,9 +1,8 @@ //===- TypeIndexDiscovery.cpp -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h" @@ -364,14 +363,16 @@ static bool discoverTypeIndices(ArrayRef<uint8_t> Content, SymbolKind Kind, // values. One idea is to define some structures representing these types // that would allow the use of offsetof(). switch (Kind) { - case SymbolKind::S_GPROC32: - case SymbolKind::S_LPROC32: case SymbolKind::S_GPROC32_ID: case SymbolKind::S_LPROC32_ID: case SymbolKind::S_LPROC32_DPC: case SymbolKind::S_LPROC32_DPC_ID: Refs.push_back({TiRefKind::IndexRef, 24, 1}); // LF_FUNC_ID break; + case SymbolKind::S_GPROC32: + case SymbolKind::S_LPROC32: + Refs.push_back({TiRefKind::TypeRef, 24, 1}); // Type + break; case SymbolKind::S_UDT: Refs.push_back({TiRefKind::TypeRef, 0, 1}); // UDT break; diff --git a/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp b/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp index 2a66474cf5b6..8e632f3be460 100644 --- a/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp +++ b/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp @@ -1,9 +1,8 @@ //===- TypeRecordHelpers.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp index 3203ff64d3b1..47928c2eef64 100644 --- a/lib/DebugInfo/CodeView/TypeRecordMapping.cpp +++ b/lib/DebugInfo/CodeView/TypeRecordMapping.cpp @@ -1,9 +1,8 @@ //===- TypeRecordMapping.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -22,19 +21,19 @@ struct MapOneMethodRecord { : IsFromOverloadList(IsFromOverloadList) {} Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const { - error(IO.mapInteger(Method.Attrs.Attrs)); + error(IO.mapInteger(Method.Attrs.Attrs, "AccessSpecifier")); if (IsFromOverloadList) { uint16_t Padding = 0; - error(IO.mapInteger(Padding)); + error(IO.mapInteger(Padding, "Padding")); } - error(IO.mapInteger(Method.Type)); + error(IO.mapInteger(Method.Type, "Type")); if (Method.isIntroducingVirtual()) { - error(IO.mapInteger(Method.VFTableOffset)); - } else if (!IO.isWriting()) + error(IO.mapInteger(Method.VFTableOffset, "VFTableOffset")); + } else if (IO.isReading()) Method.VFTableOffset = -1; if (!IsFromOverloadList) - error(IO.mapStringZ(Method.Name)); + error(IO.mapStringZ(Method.Name, "Name")); return Error::success(); } @@ -73,9 +72,12 @@ static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name, error(IO.mapStringZ(N)); } } else { - error(IO.mapStringZ(Name)); + // Reading & Streaming mode come after writing mode is executed for each + // record. Truncating large names are done during writing, so its not + // necessary to do it while reading or streaming. + error(IO.mapStringZ(Name, "Name")); if (HasUniqueName) - error(IO.mapStringZ(UniqueName)); + error(IO.mapStringZ(UniqueName, "LinkageName")); } return Error::success(); @@ -89,14 +91,18 @@ Error TypeRecordMapping::visitTypeBegin(CVType &CVR) { // split with continuation records. All other record types cannot be // longer than the maximum record length. Optional<uint32_t> MaxLen; - if (CVR.Type != TypeLeafKind::LF_FIELDLIST && - CVR.Type != TypeLeafKind::LF_METHODLIST) + if (CVR.kind() != TypeLeafKind::LF_FIELDLIST && + CVR.kind() != TypeLeafKind::LF_METHODLIST) MaxLen = MaxRecordLength - sizeof(RecordPrefix); error(IO.beginRecord(MaxLen)); - TypeKind = CVR.Type; + TypeKind = CVR.kind(); return Error::success(); } +Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) { + return visitTypeBegin(CVR); +} + Error TypeRecordMapping::visitTypeEnd(CVType &Record) { assert(TypeKind.hasValue() && "Not in a type mapping!"); assert(!MemberKind.hasValue() && "Still in a member mapping!"); @@ -127,7 +133,7 @@ Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) { assert(TypeKind.hasValue() && "Not in a type mapping!"); assert(MemberKind.hasValue() && "Not in a member mapping!"); - if (!IO.isWriting()) { + if (IO.isReading()) { if (auto EC = IO.skipPadding()) return EC; } @@ -138,33 +144,32 @@ Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) { } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) { - error(IO.mapInteger(Record.ModifiedType)); - error(IO.mapEnum(Record.Modifiers)); - + error(IO.mapInteger(Record.ModifiedType, "ModifiedType")); + error(IO.mapEnum(Record.Modifiers, "Modifiers")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ProcedureRecord &Record) { - error(IO.mapInteger(Record.ReturnType)); - error(IO.mapEnum(Record.CallConv)); - error(IO.mapEnum(Record.Options)); - error(IO.mapInteger(Record.ParameterCount)); - error(IO.mapInteger(Record.ArgumentList)); + error(IO.mapInteger(Record.ReturnType, "ReturnType")); + error(IO.mapEnum(Record.CallConv, "CallingConvention")); + error(IO.mapEnum(Record.Options, "FunctionOptions")); + error(IO.mapInteger(Record.ParameterCount, "NumParameters")); + error(IO.mapInteger(Record.ArgumentList, "ArgListType")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, MemberFunctionRecord &Record) { - error(IO.mapInteger(Record.ReturnType)); - error(IO.mapInteger(Record.ClassType)); - error(IO.mapInteger(Record.ThisType)); - error(IO.mapEnum(Record.CallConv)); - error(IO.mapEnum(Record.Options)); - error(IO.mapInteger(Record.ParameterCount)); - error(IO.mapInteger(Record.ArgumentList)); - error(IO.mapInteger(Record.ThisPointerAdjustment)); + 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.mapInteger(Record.ParameterCount, "NumParameters")); + error(IO.mapInteger(Record.ArgumentList, "ArgListType")); + error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment")); return Error::success(); } @@ -172,8 +177,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArgListRecord &Record) { error(IO.mapVectorN<uint32_t>( Record.ArgIndices, - [](CodeViewRecordIO &IO, TypeIndex &N) { return IO.mapInteger(N); })); - + [](CodeViewRecordIO &IO, TypeIndex &N) { + return IO.mapInteger(N, "Argument"); + }, + "NumArgs")); return Error::success(); } @@ -181,47 +188,50 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, StringListRecord &Record) { error(IO.mapVectorN<uint32_t>( Record.StringIndices, - [](CodeViewRecordIO &IO, TypeIndex &N) { return IO.mapInteger(N); })); + [](CodeViewRecordIO &IO, TypeIndex &N) { + return IO.mapInteger(N, "Strings"); + }, + "NumStrings")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) { - error(IO.mapInteger(Record.ReferentType)); - error(IO.mapInteger(Record.Attrs)); + error(IO.mapInteger(Record.ReferentType, "PointeeType")); + error(IO.mapInteger(Record.Attrs, "Attributes")); if (Record.isPointerToMember()) { - if (!IO.isWriting()) + if (IO.isReading()) Record.MemberInfo.emplace(); MemberPointerInfo &M = *Record.MemberInfo; - error(IO.mapInteger(M.ContainingType)); - error(IO.mapEnum(M.Representation)); + error(IO.mapInteger(M.ContainingType, "ClassType")); + error(IO.mapEnum(M.Representation, "Representation")); } return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArrayRecord &Record) { - error(IO.mapInteger(Record.ElementType)); - error(IO.mapInteger(Record.IndexType)); - error(IO.mapEncodedInteger(Record.Size)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapInteger(Record.ElementType, "ElementType")); + error(IO.mapInteger(Record.IndexType, "IndexType")); + error(IO.mapEncodedInteger(Record.Size, "SizeOf")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) { - assert((CVR.Type == TypeLeafKind::LF_STRUCTURE) || - (CVR.Type == TypeLeafKind::LF_CLASS) || - (CVR.Type == TypeLeafKind::LF_INTERFACE)); - - error(IO.mapInteger(Record.MemberCount)); - error(IO.mapEnum(Record.Options)); - error(IO.mapInteger(Record.FieldList)); - error(IO.mapInteger(Record.DerivationList)); - error(IO.mapInteger(Record.VTableShape)); - error(IO.mapEncodedInteger(Record.Size)); + assert((CVR.kind() == TypeLeafKind::LF_STRUCTURE) || + (CVR.kind() == TypeLeafKind::LF_CLASS) || + (CVR.kind() == TypeLeafKind::LF_INTERFACE)); + + error(IO.mapInteger(Record.MemberCount, "MemberCount")); + error(IO.mapEnum(Record.Options, "Properties")); + error(IO.mapInteger(Record.FieldList, "FieldList")); + error(IO.mapInteger(Record.DerivationList, "DerivedFrom")); + error(IO.mapInteger(Record.VTableShape, "VShape")); + error(IO.mapEncodedInteger(Record.Size, "SizeOf")); error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, Record.hasUniqueName())); @@ -229,10 +239,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ClassRecord &Record) { } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) { - error(IO.mapInteger(Record.MemberCount)); - error(IO.mapEnum(Record.Options)); - error(IO.mapInteger(Record.FieldList)); - error(IO.mapEncodedInteger(Record.Size)); + error(IO.mapInteger(Record.MemberCount, "MemberCount")); + error(IO.mapEnum(Record.Options, "Properties")); + error(IO.mapInteger(Record.FieldList, "FieldList")); + error(IO.mapEncodedInteger(Record.Size, "SizeOf")); error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, Record.hasUniqueName())); @@ -240,10 +250,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) { } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) { - error(IO.mapInteger(Record.MemberCount)); - error(IO.mapEnum(Record.Options)); - error(IO.mapInteger(Record.UnderlyingType)); - error(IO.mapInteger(Record.FieldList)); + error(IO.mapInteger(Record.MemberCount, "NumEnumerators")); + error(IO.mapEnum(Record.Options, "Properties")); + error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType")); + error(IO.mapInteger(Record.FieldList, "FieldListType")); error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName, Record.hasUniqueName())); @@ -251,9 +261,9 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) { } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BitFieldRecord &Record) { - error(IO.mapInteger(Record.Type)); - error(IO.mapInteger(Record.BitSize)); - error(IO.mapInteger(Record.BitOffset)); + error(IO.mapInteger(Record.Type, "Type")); + error(IO.mapInteger(Record.BitSize, "BitSize")); + error(IO.mapInteger(Record.BitOffset, "BitOffset")); return Error::success(); } @@ -261,10 +271,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BitFieldRecord &Record) { Error TypeRecordMapping::visitKnownRecord(CVType &CVR, VFTableShapeRecord &Record) { uint16_t Size; - if (IO.isWriting()) { + if (!IO.isReading()) { ArrayRef<VFTableSlotKind> Slots = Record.getSlots(); Size = Slots.size(); - error(IO.mapInteger(Size)); + error(IO.mapInteger(Size, "VFEntryCount")); for (size_t SlotIndex = 0; SlotIndex < Slots.size(); SlotIndex += 2) { uint8_t Byte = static_cast<uint8_t>(Slots[SlotIndex]) << 4; @@ -288,61 +298,64 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, VFTableRecord &Record) { - error(IO.mapInteger(Record.CompleteClass)); - error(IO.mapInteger(Record.OverriddenVFTable)); - error(IO.mapInteger(Record.VFPtrOffset)); + error(IO.mapInteger(Record.CompleteClass, "CompleteClass")); + error(IO.mapInteger(Record.OverriddenVFTable, "OverriddenVFTable")); + error(IO.mapInteger(Record.VFPtrOffset, "VFPtrOffset")); uint32_t NamesLen = 0; - if (IO.isWriting()) { + if (!IO.isReading()) { for (auto Name : Record.MethodNames) NamesLen += Name.size() + 1; } error(IO.mapInteger(NamesLen)); error(IO.mapVectorTail( Record.MethodNames, - [](CodeViewRecordIO &IO, StringRef &S) { return IO.mapStringZ(S); })); + [](CodeViewRecordIO &IO, StringRef &S) { + return IO.mapStringZ(S, "MethodName"); + }, + "VFTableName")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, StringIdRecord &Record) { - error(IO.mapInteger(Record.Id)); - error(IO.mapStringZ(Record.String)); + error(IO.mapInteger(Record.Id, "Id")); + error(IO.mapStringZ(Record.String, "StringData")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UdtSourceLineRecord &Record) { - error(IO.mapInteger(Record.UDT)); - error(IO.mapInteger(Record.SourceFile)); - error(IO.mapInteger(Record.LineNumber)); + error(IO.mapInteger(Record.UDT, "UDT")); + error(IO.mapInteger(Record.SourceFile, "SourceFile")); + error(IO.mapInteger(Record.LineNumber, "LineNumber")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UdtModSourceLineRecord &Record) { - error(IO.mapInteger(Record.UDT)); - error(IO.mapInteger(Record.SourceFile)); - error(IO.mapInteger(Record.LineNumber)); - error(IO.mapInteger(Record.Module)); + error(IO.mapInteger(Record.UDT, "UDT")); + error(IO.mapInteger(Record.SourceFile, "SourceFile")); + error(IO.mapInteger(Record.LineNumber, "LineNumber")); + error(IO.mapInteger(Record.Module, "Module")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, FuncIdRecord &Record) { - error(IO.mapInteger(Record.ParentScope)); - error(IO.mapInteger(Record.FunctionType)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapInteger(Record.ParentScope, "ParentScope")); + error(IO.mapInteger(Record.FunctionType, "FunctionType")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Record) { - error(IO.mapInteger(Record.ClassType)); - error(IO.mapInteger(Record.FunctionType)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapInteger(Record.ClassType, "ClassType")); + error(IO.mapInteger(Record.FunctionType, "FunctionType")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } @@ -351,7 +364,10 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BuildInfoRecord &Record) { error(IO.mapVectorN<uint16_t>( Record.ArgIndices, - [](CodeViewRecordIO &IO, TypeIndex &N) { return IO.mapInteger(N); })); + [](CodeViewRecordIO &IO, TypeIndex &N) { + return IO.mapInteger(N, "Argument"); + }, + "NumArgs")); return Error::success(); } @@ -360,7 +376,7 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, MethodOverloadListRecord &Record) { // TODO: Split the list into multiple records if it's longer than 64KB, using // a subrecord of TypeRecordKind::Index to chain the records together. - error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true))); + error(IO.mapVectorTail(Record.Methods, MapOneMethodRecord(true), "Method")); return Error::success(); } @@ -374,22 +390,22 @@ Error TypeRecordMapping::visitKnownRecord(CVType &CVR, Error TypeRecordMapping::visitKnownRecord(CVType &CVR, TypeServer2Record &Record) { - error(IO.mapGuid(Record.Guid)); - error(IO.mapInteger(Record.Age)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapGuid(Record.Guid, "Guid")); + error(IO.mapInteger(Record.Age, "Age")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, LabelRecord &Record) { - error(IO.mapEnum(Record.Mode)); + error(IO.mapEnum(Record.Mode, "Mode")); return Error::success(); } Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, BaseClassRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs)); - error(IO.mapInteger(Record.Type)); - error(IO.mapEncodedInteger(Record.Offset)); + error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + error(IO.mapInteger(Record.Type, "BaseType")); + error(IO.mapEncodedInteger(Record.Offset, "BaseOffset")); return Error::success(); } @@ -399,27 +415,27 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, error(IO.mapInteger(Record.Attrs.Attrs)); // FIXME: Handle full APInt such as __int128. - error(IO.mapEncodedInteger(Record.Value)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapEncodedInteger(Record.Value, "EnumValue")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, DataMemberRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs)); - error(IO.mapInteger(Record.Type)); - error(IO.mapEncodedInteger(Record.FieldOffset)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + error(IO.mapInteger(Record.Type, "Type")); + error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, OverloadedMethodRecord &Record) { - error(IO.mapInteger(Record.NumOverloads)); - error(IO.mapInteger(Record.MethodList)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapInteger(Record.NumOverloads, "MethodCount")); + error(IO.mapInteger(Record.MethodList, "MethodListIndex")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } @@ -434,9 +450,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, NestedTypeRecord &Record) { uint16_t Padding = 0; - error(IO.mapInteger(Padding)); - error(IO.mapInteger(Record.Type)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapInteger(Padding, "Padding")); + error(IO.mapInteger(Record.Type, "Type")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } @@ -444,9 +460,9 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, StaticDataMemberRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs)); - error(IO.mapInteger(Record.Type)); - error(IO.mapStringZ(Record.Name)); + error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + error(IO.mapInteger(Record.Type, "Type")); + error(IO.mapStringZ(Record.Name, "Name")); return Error::success(); } @@ -454,11 +470,11 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, VirtualBaseClassRecord &Record) { - error(IO.mapInteger(Record.Attrs.Attrs)); - error(IO.mapInteger(Record.BaseType)); - error(IO.mapInteger(Record.VBPtrType)); - error(IO.mapEncodedInteger(Record.VBPtrOffset)); - error(IO.mapEncodedInteger(Record.VTableIndex)); + error(IO.mapInteger(Record.Attrs.Attrs, "AccessSpecifier")); + error(IO.mapInteger(Record.BaseType, "BaseType")); + error(IO.mapInteger(Record.VBPtrType, "VBPtrType")); + error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset")); + error(IO.mapEncodedInteger(Record.VTableIndex, "VBTableIndex")); return Error::success(); } @@ -466,8 +482,8 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, VFPtrRecord &Record) { uint16_t Padding = 0; - error(IO.mapInteger(Padding)); - error(IO.mapInteger(Record.Type)); + error(IO.mapInteger(Padding, "Padding")); + error(IO.mapInteger(Record.Type, "Type")); return Error::success(); } @@ -475,23 +491,23 @@ Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR, ListContinuationRecord &Record) { uint16_t Padding = 0; - error(IO.mapInteger(Padding)); - error(IO.mapInteger(Record.ContinuationIndex)); + error(IO.mapInteger(Padding, "Padding")); + error(IO.mapInteger(Record.ContinuationIndex, "ContinuationIndex")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PrecompRecord &Precomp) { - error(IO.mapInteger(Precomp.StartTypeIndex)); - error(IO.mapInteger(Precomp.TypesCount)); - error(IO.mapInteger(Precomp.Signature)); - error(IO.mapStringZ(Precomp.PrecompFilePath)); + error(IO.mapInteger(Precomp.StartTypeIndex, "StartIndex")); + error(IO.mapInteger(Precomp.TypesCount, "Count")); + error(IO.mapInteger(Precomp.Signature, "Signature")); + error(IO.mapStringZ(Precomp.PrecompFilePath, "PrecompFile")); return Error::success(); } Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EndPrecompRecord &EndPrecomp) { - error(IO.mapInteger(EndPrecomp.Signature)); + error(IO.mapInteger(EndPrecomp.Signature, "Signature")); return Error::success(); } diff --git a/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/lib/DebugInfo/CodeView/TypeStreamMerger.cpp index bae11ce6a6a1..aba0e96d606e 100644 --- a/lib/DebugInfo/CodeView/TypeStreamMerger.cpp +++ b/lib/DebugInfo/CodeView/TypeStreamMerger.cpp @@ -1,9 +1,8 @@ //===-- TypeStreamMerger.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/CodeView/TypeTableCollection.cpp b/lib/DebugInfo/CodeView/TypeTableCollection.cpp index cf951baa5111..e13068b5b1eb 100644 --- a/lib/DebugInfo/CodeView/TypeTableCollection.cpp +++ b/lib/DebugInfo/CodeView/TypeTableCollection.cpp @@ -1,9 +1,8 @@ //===- TypeTableCollection.cpp -------------------------------- *- C++ --*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -37,11 +36,7 @@ Optional<TypeIndex> TypeTableCollection::getNext(TypeIndex Prev) { CVType TypeTableCollection::getType(TypeIndex Index) { assert(Index.toArrayIndex() < Records.size()); - ArrayRef<uint8_t> Bytes = Records[Index.toArrayIndex()]; - const RecordPrefix *Prefix = - reinterpret_cast<const RecordPrefix *>(Bytes.data()); - TypeLeafKind Kind = static_cast<TypeLeafKind>(uint16_t(Prefix->RecordKind)); - return CVType(Kind, Bytes); + return CVType(Records[Index.toArrayIndex()]); } StringRef TypeTableCollection::getTypeName(TypeIndex Index) { diff --git a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp index f49ab40fad9a..f4dd79937608 100644 --- a/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp @@ -1,9 +1,8 @@ //===- DWARFAbbreviationDeclaration.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 // //===----------------------------------------------------------------------===// @@ -164,11 +163,11 @@ Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue( for (const auto &Spec : AttributeSpecs) { if (*MatchAttrIndex == AttrIndex) { // We have arrived at the attribute to extract, extract if from Offset. + if (Spec.isImplicitConst()) + return DWARFFormValue::createFromSValue(Spec.Form, + Spec.getImplicitConstValue()); + DWARFFormValue FormValue(Spec.Form); - if (Spec.isImplicitConst()) { - FormValue.setSValue(Spec.getImplicitConstValue()); - return FormValue; - } if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U)) return FormValue; } diff --git a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp index 54daf34ff253..0721efb40f6a 100644 --- a/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ b/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -1,9 +1,8 @@ //===- DWARFAcceleratorTable.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 // //===----------------------------------------------------------------------===// @@ -42,7 +41,7 @@ static Atom formatAtom(unsigned Atom) { return {Atom}; } DWARFAcceleratorTable::~DWARFAcceleratorTable() = default; -llvm::Error AppleAcceleratorTable::extract() { +Error AppleAcceleratorTable::extract() { uint32_t Offset = 0; // Check that we can at least read the header. @@ -377,7 +376,7 @@ void DWARFDebugNames::Header::dump(ScopedPrinter &W) const { W.startLine() << "Augmentation: '" << AugmentationString << "'\n"; } -llvm::Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS, +Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS, uint32_t *Offset) { // Check that we can read the fixed-size part. if (!AS.isValidOffset(*Offset + sizeof(HeaderPOD) - 1)) @@ -519,6 +518,7 @@ Error DWARFDebugNames::NameIndex::extract() { "Duplicate abbreviation code."); } } + DWARFDebugNames::Entry::Entry(const NameIndex &NameIdx, const Abbrev &Abbr) : NameIdx(&NameIdx), Abbr(&Abbr) { // This merely creates form values. It is up to the caller @@ -585,13 +585,14 @@ uint32_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const { uint32_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const { assert(TU < Hdr.LocalTypeUnitCount); - uint32_t Offset = CUsBase + Hdr.CompUnitCount * 4; + uint32_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 = CUsBase + (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) * 4; + uint32_t Offset = + CUsBase + 4 * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU; return Section.AccelSection.getU64(&Offset); } @@ -754,11 +755,11 @@ LLVM_DUMP_METHOD void DWARFDebugNames::NameIndex::dump(ScopedPrinter &W) const { dumpName(W, NTE, None); } -llvm::Error DWARFDebugNames::extract() { +Error DWARFDebugNames::extract() { uint32_t Offset = 0; while (AccelSection.isValidOffset(Offset)) { NameIndex Next(*this, Offset); - if (llvm::Error E = Next.extract()) + if (Error E = Next.extract()) return E; Offset = Next.getNextUnitOffset(); NameIndices.push_back(std::move(Next)); diff --git a/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/lib/DebugInfo/DWARF/DWARFAddressRange.cpp index 86c8d19c02f4..ef6da08d34aa 100644 --- a/lib/DebugInfo/DWARF/DWARFAddressRange.cpp +++ b/lib/DebugInfo/DWARF/DWARFAddressRange.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugAranges.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp index 00a23b3898fa..74cce42466dd 100644 --- a/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp @@ -1,9 +1,8 @@ //===-- DWARFCompileUnit.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARF/DWARFContext.cpp b/lib/DebugInfo/DWARF/DWARFContext.cpp index e6620ee3dd1d..5ede9bf59619 100644 --- a/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -1,9 +1,8 @@ //===- DWARFContext.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 // //===----------------------------------------------------------------------===// @@ -37,11 +36,12 @@ #include "llvm/Object/Decompressor.h" #include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/Object/RelocVisitor.h" +#include "llvm/Object/RelocationResolver.h" #include "llvm/Support/Casting.h" #include "llvm/Support/DataExtractor.h" #include "llvm/Support/Error.h" #include "llvm/Support/Format.h" +#include "llvm/Support/LEB128.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/TargetRegistry.h" @@ -102,7 +102,8 @@ static ContributionCollection collectContributionData(DWARFContext::unit_iterator_range Units) { ContributionCollection Contributions; for (const auto &U : Units) - Contributions.push_back(U->getStringOffsetsTableContribution()); + if (const auto &C = U->getStringOffsetsTableContribution()) + Contributions.push_back(C); // Sort the contributions so that any invalid ones are placed at // the start of the contributions vector. This way they are reported // first. @@ -158,9 +159,9 @@ static void dumpDWARFv5StringOffsetsSection( // Detect overlapping contributions. if (Offset > ContributionHeader) { - OS << "error: overlapping contributions to string offsets table in " - "section ." - << SectionName << ".\n"; + WithColor::error() + << "overlapping contributions to string offsets table in section ." + << SectionName << ".\n"; return; } // Report a gap in the table. @@ -269,11 +270,11 @@ static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData, } // Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5). -static void -dumpRnglistsSection(raw_ostream &OS, DWARFDataExtractor &rnglistData, - llvm::function_ref<Optional<SectionedAddress>(uint32_t)> - LookupPooledAddress, - DIDumpOptions DumpOpts) { +static void dumpRnglistsSection( + raw_ostream &OS, DWARFDataExtractor &rnglistData, + llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)> + LookupPooledAddress, + DIDumpOptions DumpOpts) { uint32_t Offset = 0; while (rnglistData.isValidOffset(Offset)) { llvm::DWARFDebugRnglistTable Rnglists; @@ -926,6 +927,9 @@ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) { DWARFDie DIE = Worklist.back(); Worklist.pop_back(); + if (!DIE.isValid()) + continue; + if (DIE.getTag() == DW_TAG_lexical_block && DIE.addressRangeContainsAddress(Address)) { Result.BlockDIE = DIE; @@ -939,6 +943,8 @@ DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) { return Result; } +/// TODO: change input parameter from "uint64_t Address" +/// into "SectionedAddress Address" static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, uint64_t Address, FunctionNameKind Kind, @@ -967,36 +973,155 @@ static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU, return FoundResult; } -DILineInfo DWARFContext::getLineInfoForAddress(uint64_t Address, +static Optional<uint64_t> getTypeSize(DWARFDie Type, uint64_t PointerSize) { + if (auto SizeAttr = Type.find(DW_AT_byte_size)) + if (Optional<uint64_t> Size = SizeAttr->getAsUnsignedConstant()) + return Size; + + switch (Type.getTag()) { + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: + return PointerSize; + case DW_TAG_ptr_to_member_type: { + if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type)) + if (BaseType.getTag() == DW_TAG_subroutine_type) + return 2 * PointerSize; + return PointerSize; + } + case DW_TAG_const_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + case DW_TAG_typedef: { + if (DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type)) + return getTypeSize(BaseType, PointerSize); + break; + } + case DW_TAG_array_type: { + DWARFDie BaseType = Type.getAttributeValueAsReferencedDie(DW_AT_type); + if (!BaseType) + return Optional<uint64_t>(); + Optional<uint64_t> BaseSize = getTypeSize(BaseType, PointerSize); + if (!BaseSize) + return Optional<uint64_t>(); + uint64_t Size = *BaseSize; + for (DWARFDie Child : Type) { + if (Child.getTag() != DW_TAG_subrange_type) + continue; + + if (auto ElemCountAttr = Child.find(DW_AT_count)) + if (Optional<uint64_t> ElemCount = + ElemCountAttr->getAsUnsignedConstant()) + Size *= *ElemCount; + if (auto UpperBoundAttr = Child.find(DW_AT_upper_bound)) + if (Optional<int64_t> UpperBound = + UpperBoundAttr->getAsSignedConstant()) { + int64_t LowerBound = 0; + if (auto LowerBoundAttr = Child.find(DW_AT_lower_bound)) + LowerBound = LowerBoundAttr->getAsSignedConstant().getValueOr(0); + Size *= *UpperBound - LowerBound + 1; + } + } + return Size; + } + default: + break; + } + return Optional<uint64_t>(); +} + +void DWARFContext::addLocalsForDie(DWARFCompileUnit *CU, DWARFDie Subprogram, + DWARFDie Die, std::vector<DILocal> &Result) { + if (Die.getTag() == DW_TAG_variable || + Die.getTag() == DW_TAG_formal_parameter) { + DILocal Local; + if (auto NameAttr = Subprogram.find(DW_AT_name)) + if (Optional<const char *> Name = NameAttr->getAsCString()) + Local.FunctionName = *Name; + if (auto LocationAttr = Die.find(DW_AT_location)) + if (Optional<ArrayRef<uint8_t>> Location = LocationAttr->getAsBlock()) + if (!Location->empty() && (*Location)[0] == DW_OP_fbreg) + Local.FrameOffset = + decodeSLEB128(Location->data() + 1, nullptr, Location->end()); + if (auto TagOffsetAttr = Die.find(DW_AT_LLVM_tag_offset)) + Local.TagOffset = TagOffsetAttr->getAsUnsignedConstant(); + + if (auto Origin = + Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) + Die = Origin; + if (auto NameAttr = Die.find(DW_AT_name)) + if (Optional<const char *> Name = NameAttr->getAsCString()) + Local.Name = *Name; + if (auto Type = Die.getAttributeValueAsReferencedDie(DW_AT_type)) + Local.Size = getTypeSize(Type, getCUAddrSize()); + if (auto DeclFileAttr = Die.find(DW_AT_decl_file)) { + if (const auto *LT = CU->getContext().getLineTableForUnit(CU)) + LT->getFileNameByIndex( + DeclFileAttr->getAsUnsignedConstant().getValue(), + CU->getCompilationDir(), + DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, + Local.DeclFile); + } + if (auto DeclLineAttr = Die.find(DW_AT_decl_line)) + Local.DeclLine = DeclLineAttr->getAsUnsignedConstant().getValue(); + + Result.push_back(Local); + return; + } + + if (Die.getTag() == DW_TAG_inlined_subroutine) + if (auto Origin = + Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) + Subprogram = Origin; + + for (auto Child : Die) + addLocalsForDie(CU, Subprogram, Child, Result); +} + +std::vector<DILocal> +DWARFContext::getLocalsForAddress(object::SectionedAddress Address) { + std::vector<DILocal> Result; + DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); + if (!CU) + return Result; + + DWARFDie Subprogram = CU->getSubroutineForAddress(Address.Address); + if (Subprogram.isValid()) + addLocalsForDie(CU, Subprogram, Subprogram, Result); + return Result; +} + +DILineInfo DWARFContext::getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Spec) { DILineInfo Result; - DWARFCompileUnit *CU = getCompileUnitForAddress(Address); + DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); if (!CU) return Result; - getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, - Result.FunctionName, - Result.StartLine); + + getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, + Result.FunctionName, Result.StartLine); if (Spec.FLIKind != FileLineInfoKind::None) { - if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) - LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), - Spec.FLIKind, Result); + if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) { + LineTable->getFileLineInfoForAddress( + {Address.Address, Address.SectionIndex}, CU->getCompilationDir(), + Spec.FLIKind, Result); + } } return Result; } -DILineInfoTable -DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, - DILineInfoSpecifier Spec) { +DILineInfoTable DWARFContext::getLineInfoForAddressRange( + object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) { DILineInfoTable Lines; - DWARFCompileUnit *CU = getCompileUnitForAddress(Address); + DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); if (!CU) return Lines; std::string FunctionName = "<invalid>"; uint32_t StartLine = 0; - getFunctionNameAndStartLineForAddress(CU, Address, Spec.FNKind, FunctionName, - StartLine); + getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, + FunctionName, StartLine); // If the Specifier says we don't need FileLineInfo, just // return the top-most function at the starting address. @@ -1004,7 +1129,7 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, DILineInfo Result; Result.FunctionName = FunctionName; Result.StartLine = StartLine; - Lines.push_back(std::make_pair(Address, Result)); + Lines.push_back(std::make_pair(Address.Address, Result)); return Lines; } @@ -1012,8 +1137,10 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, // Get the index of row we're looking for in the line table. std::vector<uint32_t> RowVector; - if (!LineTable->lookupAddressRange(Address, Size, RowVector)) + if (!LineTable->lookupAddressRange({Address.Address, Address.SectionIndex}, + Size, RowVector)) { return Lines; + } for (uint32_t RowIndex : RowVector) { // Take file number and line/column from the row. @@ -1025,33 +1152,33 @@ DWARFContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, Result.Line = Row.Line; Result.Column = Row.Column; Result.StartLine = StartLine; - Lines.push_back(std::make_pair(Row.Address, Result)); + Lines.push_back(std::make_pair(Row.Address.Address, Result)); } return Lines; } DIInliningInfo -DWARFContext::getInliningInfoForAddress(uint64_t Address, +DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Spec) { DIInliningInfo InliningInfo; - DWARFCompileUnit *CU = getCompileUnitForAddress(Address); + DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address); if (!CU) return InliningInfo; const DWARFLineTable *LineTable = nullptr; SmallVector<DWARFDie, 4> InlinedChain; - CU->getInlinedChainForAddress(Address, InlinedChain); + CU->getInlinedChainForAddress(Address.Address, InlinedChain); if (InlinedChain.size() == 0) { // If there is no DIE for address (e.g. it is in unavailable .dwo file), // try to at least get file/line info from symbol table. if (Spec.FLIKind != FileLineInfoKind::None) { DILineInfo Frame; LineTable = getLineTableForUnit(CU); - if (LineTable && - LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), - Spec.FLIKind, Frame)) + if (LineTable && LineTable->getFileLineInfoForAddress( + {Address.Address, Address.SectionIndex}, + CU->getCompilationDir(), Spec.FLIKind, Frame)) InliningInfo.addFrame(Frame); } return InliningInfo; @@ -1073,8 +1200,9 @@ DWARFContext::getInliningInfoForAddress(uint64_t Address, LineTable = getLineTableForUnit(CU); // For the topmost routine, get file/line info from line table. if (LineTable) - LineTable->getFileLineInfoForAddress(Address, CU->getCompilationDir(), - Spec.FLIKind, Frame); + LineTable->getFileLineInfoForAddress( + {Address.Address, Address.SectionIndex}, CU->getCompilationDir(), + Spec.FLIKind, Frame); } else { // Otherwise, use call file, call line and call column from // previous DIE in inlined chain. @@ -1402,8 +1530,14 @@ public: // 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. - if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) - Section.getContents(Data); + if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) { + Expected<StringRef> E = Section.getContents(); + if (E) + Data = *E; + else + // maybeDecompress below will error. + consumeError(E.takeError()); + } if (auto Err = maybeDecompress(Section, Name, Data)) { ErrorPolicy EP = HandleError(createError( @@ -1495,6 +1629,9 @@ public: // Symbol to [address, section index] cache mapping. std::map<SymbolRef, SymInfo> AddrCache; + bool (*Supports)(uint64_t); + RelocationResolver Resolver; + std::tie(Supports, Resolver) = getRelocationResolver(Obj); for (const RelocationRef &Reloc : Section.relocations()) { // FIXME: it's not clear how to correctly handle scattered // relocations. @@ -1509,9 +1646,31 @@ public: continue; } - object::RelocVisitor V(Obj); - uint64_t Val = V.visit(Reloc.getType(), Reloc, SymInfoOrErr->Address); - if (V.error()) { + // Check if Resolver can handle this relocation type early so as not to + // handle invalid cases in DWARFDataExtractor. + // + // TODO Don't store Resolver in every RelocAddrEntry. + if (Supports && Supports(Reloc.getType())) { + auto I = Map->try_emplace( + Reloc.getOffset(), + RelocAddrEntry{SymInfoOrErr->SectionIndex, Reloc, + SymInfoOrErr->Address, + Optional<object::RelocationRef>(), 0, Resolver}); + // If we didn't successfully insert that's because we already had a + // relocation for that offset. Store it as a second relocation in the + // same RelocAddrEntry instead. + if (!I.second) { + RelocAddrEntry &entry = I.first->getSecond(); + if (entry.Reloc2) { + ErrorPolicy EP = HandleError(createError( + "At most two relocations per offset are supported")); + if (EP == ErrorPolicy::Halt) + return; + } + entry.Reloc2 = Reloc; + entry.SymbolValue2 = SymInfoOrErr->Address; + } + } else { SmallString<32> Type; Reloc.getTypeName(Type); ErrorPolicy EP = HandleError( @@ -1519,10 +1678,7 @@ public: errorCodeToError(object_error::parse_failed))); if (EP == ErrorPolicy::Halt) return; - continue; } - RelocAddrEntry Rel = {SymInfoOrErr->SectionIndex, Val}; - Map->insert({Reloc.getOffset(), Rel}); } } diff --git a/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp index 03e317461396..b9adf8cb1d99 100644 --- a/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp +++ b/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp @@ -1,9 +1,8 @@ //===- DWARFDataExtractor.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 // //===----------------------------------------------------------------------===// @@ -16,15 +15,19 @@ using namespace llvm; uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off, uint64_t *SecNdx) const { if (SecNdx) - *SecNdx = -1ULL; + *SecNdx = object::SectionedAddress::UndefSection; if (!Section) return getUnsigned(Off, Size); - Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off); - if (!Rel) - return getUnsigned(Off, Size); + Optional<RelocAddrEntry> E = Obj->find(*Section, *Off); + uint64_t A = getUnsigned(Off, Size); + if (!E) + return A; if (SecNdx) - *SecNdx = Rel->SectionIndex; - return getUnsigned(Off, Size) + Rel->Value; + *SecNdx = E->SectionIndex; + uint64_t R = E->Resolver(E->Reloc, E->SymbolValue, A); + if (E->Reloc2) + R = E->Resolver(*E->Reloc2, E->SymbolValue2, R); + return R; } Optional<uint64_t> diff --git a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp index 4830c36a8ee7..31b324e5eb27 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugAbbrev.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 // //===----------------------------------------------------------------------===// @@ -84,12 +83,12 @@ void DWARFDebugAbbrev::parse() const { if (!Data) return; uint32_t Offset = 0; - DWARFAbbreviationDeclarationSet AbbrDecls; auto I = AbbrDeclSets.begin(); while (Data->isValidOffset(Offset)) { while (I != AbbrDeclSets.end() && I->first < Offset) ++I; uint32_t CUAbbrOffset = Offset; + DWARFAbbreviationDeclarationSet AbbrDecls; if (!AbbrDecls.extract(*Data, &Offset)) break; AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls))); diff --git a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp index 22759bfac26c..58626539bba4 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugAddr.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 // //===----------------------------------------------------------------------===// @@ -148,28 +147,13 @@ void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { HeaderData.Length, HeaderData.Version, HeaderData.AddrSize, HeaderData.SegSize); - static const char *Fmt32 = "0x%8.8" PRIx64; - static const char *Fmt64 = "0x%16.16" PRIx64; - std::string AddrFmt = "\n"; - std::string AddrFmtVerbose = " => "; - if (HeaderData.AddrSize == 4) { - AddrFmt.append(Fmt32); - AddrFmtVerbose.append(Fmt32); - } - else { - AddrFmt.append(Fmt64); - AddrFmtVerbose.append(Fmt64); - } - if (Addrs.size() > 0) { - OS << "Addrs: ["; - for (uint64_t Addr : Addrs) { - OS << format(AddrFmt.c_str(), Addr); - if (DumpOpts.Verbose) - OS << format(AddrFmtVerbose.c_str(), - Addr + HeaderOffset + sizeof(HeaderData)); - } - OS << "\n]\n"; + const char *AddrFmt = (HeaderData.AddrSize == 4) ? "0x%8.8" PRIx64 "\n" + : "0x%16.16" PRIx64 "\n"; + OS << "Addrs: [\n"; + for (uint64_t Addr : Addrs) + OS << format(AddrFmt, Addr); + OS << "]\n"; } } diff --git a/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp index b9ef6905912a..6551b61accb8 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugArangeSet.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp index e8c5dec821b4..6460c9feeab8 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugAranges.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 // //===----------------------------------------------------------------------===// @@ -115,20 +114,9 @@ void DWARFDebugAranges::construct() { } uint32_t DWARFDebugAranges::findAddress(uint64_t Address) const { - if (!Aranges.empty()) { - Range range(Address); - RangeCollIterator begin = Aranges.begin(); - RangeCollIterator end = Aranges.end(); - RangeCollIterator pos = - std::lower_bound(begin, end, range); - - if (pos != end && pos->containsAddress(Address)) { - return pos->CUOffset; - } else if (pos != begin) { - --pos; - if (pos->containsAddress(Address)) - return pos->CUOffset; - } - } + RangeCollIterator It = + partition_point(Aranges, [=](Range R) { return R.HighPC() <= Address; }); + if (It != Aranges.end() && It->LowPC <= Address) + return It->CUOffset; return -1U; } diff --git a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp index ba55ffc28174..b3f23366f2a2 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -267,7 +266,7 @@ void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI, case OT_Expression: assert(Instr.Expression && "missing DWARFExpression object"); OS << " "; - Instr.Expression->print(OS, MRI, IsEH); + Instr.Expression->print(OS, MRI, nullptr, IsEH); break; } } @@ -301,7 +300,7 @@ void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { OS << format(" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor); OS << format(" Return address column: %d\n", (int32_t)ReturnAddressRegister); if (Personality) - OS << format(" Personality Address: %08x\n", *Personality); + OS << format(" Personality Address: %016" PRIx64 "\n", *Personality); if (!AugmentationData.empty()) { OS << " Augmentation data: "; for (uint8_t Byte : AugmentationData) @@ -320,7 +319,7 @@ void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const { (uint32_t)InitialLocation, (uint32_t)InitialLocation + (uint32_t)AddressRange); if (LSDAAddress) - OS << format(" LSDA Address: %08x\n", *LSDAAddress); + OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress); CFIs.dump(OS, MRI, IsEH); OS << "\n"; } @@ -533,10 +532,9 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) { } FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const { - auto It = - std::lower_bound(Entries.begin(), Entries.end(), Offset, - [](const std::unique_ptr<FrameEntry> &E, - uint64_t Offset) { return E->getOffset() < Offset; }); + auto It = partition_point(Entries, [=](const std::unique_ptr<FrameEntry> &E) { + return E->getOffset() < Offset; + }); if (It != Entries.end() && (*It)->getOffset() == Offset) return It->get(); return nullptr; diff --git a/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp index 976bc4651ae6..d8a755e90df4 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugInfoEntry.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index 1d621ff244f3..a1cb1e8582ed 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugLine.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 // //===----------------------------------------------------------------------===// @@ -67,6 +66,26 @@ void DWARFDebugLine::ContentTypeTracker::trackContentType( DWARFDebugLine::Prologue::Prologue() { clear(); } +bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex) const { + uint16_t DwarfVersion = getVersion(); + assert(DwarfVersion != 0 && + "line table prologue has no dwarf version information"); + if (DwarfVersion >= 5) + return FileIndex < FileNames.size(); + return FileIndex != 0 && FileIndex <= FileNames.size(); +} + +const llvm::DWARFDebugLine::FileNameEntry & +DWARFDebugLine::Prologue::getFileNameEntry(uint64_t Index) const { + uint16_t DwarfVersion = getVersion(); + assert(DwarfVersion != 0 && + "line table prologue has no dwarf version information"); + // In DWARF v5 the file names are 0-indexed. + if (DwarfVersion >= 5) + return FileNames[Index]; + return FileNames[Index - 1]; +} + void DWARFDebugLine::Prologue::clear() { TotalLength = PrologueLength = 0; SegSelectorSize = 0; @@ -145,8 +164,8 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, StringRef S = DebugLineData.getCStrRef(OffsetPtr); if (S.empty()) break; - DWARFFormValue Dir(dwarf::DW_FORM_string); - Dir.setPValue(S.data()); + DWARFFormValue Dir = + DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, S.data()); IncludeDirectories.push_back(Dir); } @@ -155,8 +174,8 @@ parseV2DirFileTables(const DWARFDataExtractor &DebugLineData, if (Name.empty()) break; DWARFDebugLine::FileNameEntry FileEntry; - FileEntry.Name.setForm(dwarf::DW_FORM_string); - FileEntry.Name.setPValue(Name.data()); + FileEntry.Name = + DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name.data()); FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr); FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr); FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); @@ -281,11 +300,11 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, const uint64_t PrologueOffset = *OffsetPtr; clear(); - TotalLength = DebugLineData.getU32(OffsetPtr); + TotalLength = DebugLineData.getRelocatedValue(4, OffsetPtr); if (TotalLength == UINT32_MAX) { FormParams.Format = dwarf::DWARF64; TotalLength = DebugLineData.getU64(OffsetPtr); - } else if (TotalLength >= 0xffffff00) { + } else if (TotalLength >= 0xfffffff0) { 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, @@ -306,7 +325,8 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, SegSelectorSize = DebugLineData.getU8(OffsetPtr); } - PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength()); + PrologueLength = + DebugLineData.getRelocatedValue(sizeofPrologueLength(), OffsetPtr); const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr; MinInstLength = DebugLineData.getU8(OffsetPtr); if (getVersion() >= 4) @@ -348,13 +368,15 @@ Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); } void DWARFDebugLine::Row::postAppend() { + Discriminator = 0; BasicBlock = false; PrologueEnd = false; EpilogueBegin = false; } void DWARFDebugLine::Row::reset(bool DefaultIsStmt) { - Address = 0; + Address.Address = 0; + Address.SectionIndex = object::SectionedAddress::UndefSection; Line = 1; Column = 0; File = 1; @@ -374,7 +396,7 @@ void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS) { } void DWARFDebugLine::Row::dump(raw_ostream &OS) const { - OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column) + OS << format("0x%16.16" PRIx64 " %6u %6u", Address.Address, Line, Column) << format(" %6u %3u %13u ", File, Isa, Discriminator) << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "") << (PrologueEnd ? " prologue_end" : "") @@ -387,6 +409,7 @@ DWARFDebugLine::Sequence::Sequence() { reset(); } void DWARFDebugLine::Sequence::reset() { LowPC = 0; HighPC = 0; + SectionIndex = object::SectionedAddress::UndefSection; FirstRowIndex = 0; LastRowIndex = 0; Empty = true; @@ -423,19 +446,20 @@ void DWARFDebugLine::ParsingState::resetRowAndSequence() { Sequence.reset(); } -void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) { +void DWARFDebugLine::ParsingState::appendRowToMatrix() { + unsigned RowNumber = LineTable->Rows.size(); if (Sequence.Empty) { // Record the beginning of instruction sequence. Sequence.Empty = false; - Sequence.LowPC = Row.Address; + Sequence.LowPC = Row.Address.Address; Sequence.FirstRowIndex = RowNumber; } - ++RowNumber; LineTable->appendRow(Row); if (Row.EndSequence) { // Record the end of instruction sequence. - Sequence.HighPC = Row.Address; - Sequence.LastRowIndex = RowNumber; + Sequence.HighPC = Row.Address.Address; + Sequence.LastRowIndex = RowNumber + 1; + Sequence.SectionIndex = Row.Address.SectionIndex; if (Sequence.isValid()) LineTable->appendSequence(Sequence); Sequence.reset(); @@ -538,7 +562,7 @@ Error DWARFDebugLine::LineTable::parse( // address is that of the byte after the last target machine instruction // of the sequence. State.Row.EndSequence = true; - State.appendRowToMatrix(*OffsetPtr); + State.appendRowToMatrix(); if (OS) { *OS << "\n"; OS->indent(12); @@ -566,9 +590,10 @@ Error DWARFDebugLine::LineTable::parse( ExtOffset, DebugLineData.getAddressSize(), Len - 1); } - State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr); + State.Row.Address.Address = DebugLineData.getRelocatedAddress( + OffsetPtr, &State.Row.Address.SectionIndex); if (OS) - *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address); + *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address.Address); break; case DW_LNE_define_file: @@ -595,8 +620,8 @@ Error DWARFDebugLine::LineTable::parse( { FileNameEntry FileEntry; const char *Name = DebugLineData.getCStr(OffsetPtr); - FileEntry.Name.setForm(dwarf::DW_FORM_string); - FileEntry.Name.setPValue(Name); + FileEntry.Name = + DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name); FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr); FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr); FileEntry.Length = DebugLineData.getULEB128(OffsetPtr); @@ -637,15 +662,14 @@ Error DWARFDebugLine::LineTable::parse( // Standard Opcodes case DW_LNS_copy: // Takes no arguments. Append a row to the matrix using the - // current values of the state-machine registers. Then set - // the basic_block register to false. - State.appendRowToMatrix(*OffsetPtr); + // current values of the state-machine registers. if (OS) { *OS << "\n"; OS->indent(12); State.Row.dump(*OS); *OS << "\n"; } + State.appendRowToMatrix(); break; case DW_LNS_advance_pc: @@ -655,7 +679,7 @@ Error DWARFDebugLine::LineTable::parse( { uint64_t AddrOffset = DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength; - State.Row.Address += AddrOffset; + State.Row.Address.Address += AddrOffset; if (OS) *OS << " (" << AddrOffset << ")"; } @@ -713,7 +737,7 @@ Error DWARFDebugLine::LineTable::parse( uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase; uint64_t AddrOffset = (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength; - State.Row.Address += AddrOffset; + State.Row.Address.Address += AddrOffset; if (OS) *OS << format(" (0x%16.16" PRIx64 ")", AddrOffset); @@ -731,11 +755,11 @@ Error DWARFDebugLine::LineTable::parse( // requires the use of DW_LNS_advance_pc. Such assemblers, however, // can use DW_LNS_fixed_advance_pc instead, sacrificing compression. { - uint16_t PCOffset = DebugLineData.getU16(OffsetPtr); - State.Row.Address += PCOffset; + uint16_t PCOffset = DebugLineData.getRelocatedValue(2, OffsetPtr); + State.Row.Address.Address += PCOffset; if (OS) *OS - << format(" (0x%16.16" PRIx64 ")", PCOffset); + << format(" (0x%4.4" PRIx16 ")", PCOffset); } break; @@ -815,18 +839,16 @@ Error DWARFDebugLine::LineTable::parse( int32_t LineOffset = Prologue.LineBase + (AdjustOpcode % Prologue.LineRange); State.Row.Line += LineOffset; - State.Row.Address += AddrOffset; + State.Row.Address.Address += AddrOffset; if (OS) { - *OS << "address += " << ((uint32_t)AdjustOpcode) - << ", line += " << LineOffset << "\n"; + *OS << "address += " << AddrOffset << ", line += " << LineOffset + << "\n"; OS->indent(12); State.Row.dump(*OS); } - State.appendRowToMatrix(*OffsetPtr); - // Reset discriminator to 0. - State.Row.Discriminator = 0; + State.appendRowToMatrix(); } if(OS) *OS << "\n"; @@ -839,7 +861,7 @@ Error DWARFDebugLine::LineTable::parse( // Sort all sequences so that address lookup will work faster. if (!Sequences.empty()) { - llvm::sort(Sequences, Sequence::orderByLowPC); + llvm::sort(Sequences, Sequence::orderByHighPC); // Note: actually, instruction address ranges of sequences should not // overlap (in shared objects and executables). If they do, the address // lookup would still work, though, but result would be ambiguous. @@ -851,74 +873,88 @@ Error DWARFDebugLine::LineTable::parse( return Error::success(); } -uint32_t -DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq, - uint64_t Address) const { +uint32_t DWARFDebugLine::LineTable::findRowInSeq( + const DWARFDebugLine::Sequence &Seq, + object::SectionedAddress Address) const { if (!Seq.containsPC(Address)) return UnknownRowIndex; - // Search for instruction address in the rows describing the sequence. - // Rows are stored in a vector, so we may use arithmetical operations with - // iterators. + assert(Seq.SectionIndex == Address.SectionIndex); + // In some cases, e.g. first instruction in a function, the compiler generates + // two entries, both with the same address. We want the last one. + // + // In general we want a non-empty range: the last row whose address is less + // than or equal to Address. This can be computed as upper_bound - 1. DWARFDebugLine::Row Row; Row.Address = Address; RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex; RowIter LastRow = Rows.begin() + Seq.LastRowIndex; - LineTable::RowIter RowPos = std::lower_bound( - FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress); - if (RowPos == LastRow) { - return Seq.LastRowIndex - 1; - } - uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow); - if (RowPos->Address > Address) { - if (RowPos == FirstRow) - return UnknownRowIndex; - else - Index--; - } - return Index; + assert(FirstRow->Address.Address <= Row.Address.Address && + Row.Address.Address < LastRow[-1].Address.Address); + RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1, Row, + DWARFDebugLine::Row::orderByAddress) - + 1; + assert(Seq.SectionIndex == RowPos->Address.SectionIndex); + return RowPos - Rows.begin(); } -uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const { - if (Sequences.empty()) - return UnknownRowIndex; +uint32_t DWARFDebugLine::LineTable::lookupAddress( + object::SectionedAddress Address) const { + + // Search for relocatable addresses + uint32_t Result = lookupAddressImpl(Address); + + if (Result != UnknownRowIndex || + Address.SectionIndex == object::SectionedAddress::UndefSection) + return Result; + + // Search for absolute addresses + Address.SectionIndex = object::SectionedAddress::UndefSection; + return lookupAddressImpl(Address); +} + +uint32_t DWARFDebugLine::LineTable::lookupAddressImpl( + object::SectionedAddress Address) const { // First, find an instruction sequence containing the given address. DWARFDebugLine::Sequence Sequence; - Sequence.LowPC = Address; - SequenceIter FirstSeq = Sequences.begin(); - SequenceIter LastSeq = Sequences.end(); - SequenceIter SeqPos = std::lower_bound( - FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC); - DWARFDebugLine::Sequence FoundSeq; - if (SeqPos == LastSeq) { - FoundSeq = Sequences.back(); - } else if (SeqPos->LowPC == Address) { - FoundSeq = *SeqPos; - } else { - if (SeqPos == FirstSeq) - return UnknownRowIndex; - FoundSeq = *(SeqPos - 1); - } - return findRowInSeq(FoundSeq, Address); + Sequence.SectionIndex = Address.SectionIndex; + Sequence.HighPC = Address.Address; + SequenceIter It = llvm::upper_bound(Sequences, Sequence, + DWARFDebugLine::Sequence::orderByHighPC); + if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex) + return UnknownRowIndex; + return findRowInSeq(*It, Address); } bool DWARFDebugLine::LineTable::lookupAddressRange( - uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const { + object::SectionedAddress Address, uint64_t Size, + std::vector<uint32_t> &Result) const { + + // Search for relocatable addresses + if (lookupAddressRangeImpl(Address, Size, Result)) + return true; + + if (Address.SectionIndex == object::SectionedAddress::UndefSection) + return false; + + // Search for absolute addresses + Address.SectionIndex = object::SectionedAddress::UndefSection; + return lookupAddressRangeImpl(Address, Size, Result); +} + +bool DWARFDebugLine::LineTable::lookupAddressRangeImpl( + object::SectionedAddress Address, uint64_t Size, + std::vector<uint32_t> &Result) const { if (Sequences.empty()) return false; - uint64_t EndAddr = Address + Size; + uint64_t EndAddr = Address.Address + Size; // First, find an instruction sequence containing the given address. DWARFDebugLine::Sequence Sequence; - Sequence.LowPC = Address; - SequenceIter FirstSeq = Sequences.begin(); + Sequence.SectionIndex = Address.SectionIndex; + Sequence.HighPC = Address.Address; SequenceIter LastSeq = Sequences.end(); - SequenceIter SeqPos = std::lower_bound( - FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC); - if (SeqPos == LastSeq || SeqPos->LowPC != Address) { - if (SeqPos == FirstSeq) - return false; - SeqPos--; - } - if (!SeqPos->containsPC(Address)) + SequenceIter SeqPos = llvm::upper_bound( + Sequences, Sequence, DWARFDebugLine::Sequence::orderByHighPC); + if (SeqPos == LastSeq || !SeqPos->containsPC(Address)) return false; SequenceIter StartPos = SeqPos; @@ -935,7 +971,8 @@ bool DWARFDebugLine::LineTable::lookupAddressRange( FirstRowIndex = findRowInSeq(CurSeq, Address); // Figure out the last row in the range. - uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1); + uint32_t LastRowIndex = + findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex}); if (LastRowIndex == UnknownRowIndex) LastRowIndex = CurSeq.LastRowIndex - 1; @@ -952,15 +989,11 @@ bool DWARFDebugLine::LineTable::lookupAddressRange( return true; } -bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const { - return FileIndex != 0 && FileIndex <= Prologue.FileNames.size(); -} - Optional<StringRef> DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex, FileLineInfoKind Kind) const { - if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) + if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex)) return None; - const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; + const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex); if (Optional<const char *> source = Entry.Source.getAsCString()) return StringRef(*source); return None; @@ -974,13 +1007,13 @@ static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) { sys::path::is_absolute(Path, sys::path::Style::windows); } -bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, - const char *CompDir, - FileLineInfoKind Kind, - std::string &Result) const { +bool DWARFDebugLine::Prologue::getFileNameByIndex(uint64_t FileIndex, + StringRef CompDir, + FileLineInfoKind Kind, + std::string &Result) const { if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex)) return false; - const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1]; + const FileNameEntry &Entry = getFileNameEntry(FileIndex); StringRef FileName = Entry.Name.getAsCString().getValue(); if (Kind != FileLineInfoKind::AbsoluteFilePath || isPathAbsoluteOnWindowsOrPosix(FileName)) { @@ -989,21 +1022,22 @@ bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, } SmallString<16> FilePath; - uint64_t IncludeDirIndex = Entry.DirIdx; StringRef IncludeDir; // Be defensive about the contents of Entry. - if (IncludeDirIndex > 0 && - IncludeDirIndex <= Prologue.IncludeDirectories.size()) - IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1] - .getAsCString() - .getValue(); - - // We may still need to append compilation directory of compile unit. - // 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 && Kind == FileLineInfoKind::AbsoluteFilePath && - !isPathAbsoluteOnWindowsOrPosix(IncludeDir)) - sys::path::append(FilePath, CompDir); + if (getVersion() >= 5) { + if (Entry.DirIdx < IncludeDirectories.size()) + IncludeDir = IncludeDirectories[Entry.DirIdx].getAsCString().getValue(); + } else { + if (0 < Entry.DirIdx && Entry.DirIdx <= IncludeDirectories.size()) + IncludeDir = + IncludeDirectories[Entry.DirIdx - 1].getAsCString().getValue(); + + // We may still need to append compilation directory of compile unit. + // 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 skips empty strings. sys::path::append(FilePath, IncludeDir, FileName); @@ -1012,8 +1046,8 @@ bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex, } bool DWARFDebugLine::LineTable::getFileLineInfoForAddress( - uint64_t Address, const char *CompDir, FileLineInfoKind Kind, - DILineInfo &Result) const { + object::SectionedAddress Address, const char *CompDir, + FileLineInfoKind Kind, DILineInfo &Result) const { // Get the index of row we're looking for in the line table. uint32_t RowIndex = lookupAddress(Address); if (RowIndex == -1U) @@ -1058,7 +1092,7 @@ DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data, } bool DWARFDebugLine::Prologue::totalLengthIsValid() const { - return TotalLength == 0xffffffff || TotalLength < 0xffffff00; + return TotalLength == 0xffffffff || TotalLength < 0xfffffff0; } DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext( diff --git a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp index f8b5ff6ec8fb..6d8f4bee77c4 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugLoc.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 // //===----------------------------------------------------------------------===// @@ -31,15 +30,16 @@ using namespace llvm; // non-LLVM tools. static void dumpExpression(raw_ostream &OS, ArrayRef<char> Data, bool IsLittleEndian, unsigned AddressSize, - const MCRegisterInfo *MRI) { + const MCRegisterInfo *MRI, DWARFUnit *U) { DWARFDataExtractor Extractor(StringRef(Data.data(), Data.size()), IsLittleEndian, AddressSize); - DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI); + DWARFExpression(Extractor, dwarf::DWARF_VERSION, AddressSize).print(OS, MRI, U); } void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian, unsigned AddressSize, const MCRegisterInfo *MRI, + DWARFUnit *U, uint64_t BaseAddress, unsigned Indent) const { for (const Entry &E : Entries) { @@ -51,15 +51,14 @@ void DWARFDebugLoc::LocationList::dump(raw_ostream &OS, bool IsLittleEndian, BaseAddress + E.End); OS << ": "; - dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI); + dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U); } } DWARFDebugLoc::LocationList const * DWARFDebugLoc::getLocationListAtOffset(uint64_t Offset) const { - auto It = std::lower_bound( - Locations.begin(), Locations.end(), Offset, - [](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; }); + auto It = partition_point( + Locations, [=](const LocationList &L) { return L.Offset < Offset; }); if (It != Locations.end() && It->Offset == Offset) return &(*It); return nullptr; @@ -69,7 +68,7 @@ void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI, Optional<uint64_t> Offset) const { auto DumpLocationList = [&](const LocationList &L) { OS << format("0x%8.8x: ", L.Offset); - L.dump(OS, IsLittleEndian, AddressSize, MRI, 0, 12); + L.dump(OS, IsLittleEndian, AddressSize, MRI, nullptr, 0, 12); OS << "\n\n"; }; @@ -184,7 +183,8 @@ DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset, } if (Kind != dwarf::DW_LLE_base_address) { - unsigned Bytes = Data.getU16(Offset); + unsigned Bytes = + Version >= 5 ? Data.getULEB128(Offset) : Data.getU16(Offset); // A single location description describing the location of the object... StringRef str = Data.getData().substr(*Offset, Bytes); *Offset += Bytes; @@ -212,9 +212,8 @@ void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) { DWARFDebugLoclists::LocationList const * DWARFDebugLoclists::getLocationListAtOffset(uint64_t Offset) const { - auto It = std::lower_bound( - Locations.begin(), Locations.end(), Offset, - [](const LocationList &L, uint64_t Offset) { return L.Offset < Offset; }); + auto It = partition_point( + Locations, [=](const LocationList &L) { return L.Offset < Offset; }); if (It != Locations.end() && It->Offset == Offset) return &(*It); return nullptr; @@ -224,6 +223,7 @@ 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) { @@ -253,7 +253,7 @@ void DWARFDebugLoclists::LocationList::dump(raw_ostream &OS, uint64_t BaseAddr, llvm_unreachable("unreachable locations list kind"); } - dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI); + dumpExpression(OS, E.Loc, IsLittleEndian, AddressSize, MRI, U); } } @@ -262,7 +262,7 @@ void DWARFDebugLoclists::dump(raw_ostream &OS, uint64_t BaseAddr, Optional<uint64_t> Offset) const { auto DumpLocationList = [&](const LocationList &L) { OS << format("0x%8.8x: ", L.Offset); - L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, /*Indent=*/12); + L.dump(OS, BaseAddr, IsLittleEndian, AddressSize, MRI, nullptr, /*Indent=*/12); OS << "\n\n"; }; diff --git a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp index 6d789c3027a5..3317a778cc70 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugMacro.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp index abd1ad59a9c1..963ec64f5e91 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugPubTable.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp index dfb913000a46..d8df81a0aa0b 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugRangesList.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 // //===----------------------------------------------------------------------===// @@ -69,7 +68,7 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const { } DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges( - llvm::Optional<SectionedAddress> BaseAddr) const { + llvm::Optional<object::SectionedAddress> BaseAddr) const { DWARFAddressRangesVector Res; for (const RangeListEntry &RLE : Entries) { if (RLE.isBaseAddressSelectionEntry(AddressSize)) { diff --git a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp index 60c6eb30857f..5ac3326f6681 100644 --- a/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp +++ b/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp @@ -1,9 +1,8 @@ //===- DWARFDebugRnglists.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 // //===----------------------------------------------------------------------===// @@ -113,9 +112,8 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint32_t End, return Error::success(); } -DWARFAddressRangesVector -DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr, - DWARFUnit &U) const { +DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges( + llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const { DWARFAddressRangesVector Res; for (const RangeListEntry &RLE : Entries) { if (RLE.EntryKind == dwarf::DW_RLE_end_of_list) @@ -175,7 +173,7 @@ DWARFDebugRnglist::getAbsoluteRanges(llvm::Optional<SectionedAddress> BaseAddr, void RangeListEntry::dump( raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength, uint64_t &CurrentBase, DIDumpOptions DumpOpts, - llvm::function_ref<Optional<SectionedAddress>(uint32_t)> + llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)> LookupPooledAddress) const { auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry, uint8_t AddrSize, DIDumpOptions DumpOpts) { @@ -203,7 +201,6 @@ void RangeListEntry::dump( case dwarf::DW_RLE_end_of_list: OS << (DumpOpts.Verbose ? "" : "<End of list>"); break; - // case dwarf::DW_RLE_base_addressx: case dwarf::DW_RLE_base_addressx: { if (auto SA = LookupPooledAddress(Value0)) CurrentBase = SA->Address; @@ -240,7 +237,7 @@ void RangeListEntry::dump( Start = SA->Address; DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts); break; - } break; + } default: llvm_unreachable("Unsupported range list encoding"); } diff --git a/lib/DebugInfo/DWARF/DWARFDie.cpp b/lib/DebugInfo/DWARF/DWARFDie.cpp index 81ef0c8c7aec..d638dc4239f4 100644 --- a/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -1,9 +1,8 @@ //===- DWARFDie.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 // //===----------------------------------------------------------------------===// @@ -87,7 +86,7 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()), Ctx.isLittleEndian(), 0); DWARFExpression(Data, U->getVersion(), U->getAddressByteSize()) - .print(OS, MRI); + .print(OS, MRI, U); return; } @@ -101,10 +100,10 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, auto LL = DebugLoc.parseOneLocationList(Data, &Offset); if (LL) { uint64_t BaseAddr = 0; - if (Optional<SectionedAddress> BA = U->getBaseAddress()) + if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) BaseAddr = BA->Address; - LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, BaseAddr, - Indent); + LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, U, + BaseAddr, Indent); } else OS << "error extracting location list."; return; @@ -126,12 +125,12 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue, Data, &Offset, UseLocLists ? U->getVersion() : 4); uint64_t BaseAddr = 0; - if (Optional<SectionedAddress> BA = U->getBaseAddress()) + if (Optional<object::SectionedAddress> BA = U->getBaseAddress()) BaseAddr = BA->Address; if (LL) LL->dump(OS, BaseAddr, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, - Indent); + U, Indent); else OS << "error extracting location list."; } @@ -279,11 +278,7 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, OS << formatv(" [{0}]", Form); DWARFUnit *U = Die.getDwarfUnit(); - DWARFFormValue formValue(Form); - - if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, - U->getFormParams(), U)) - return; + DWARFFormValue FormValue = DWARFFormValue::createFromUnit(Form, U, OffsetPtr); OS << "\t("; @@ -294,35 +289,33 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, Color = HighlightColor::String; if (const auto *LT = U->getContext().getLineTableForUnit(U)) if (LT->getFileNameByIndex( - formValue.getAsUnsignedConstant().getValue(), + FormValue.getAsUnsignedConstant().getValue(), U->getCompilationDir(), DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) { File = '"' + File + '"'; Name = File; } - } else if (Optional<uint64_t> Val = formValue.getAsUnsignedConstant()) + } else if (Optional<uint64_t> Val = FormValue.getAsUnsignedConstant()) Name = AttributeValueString(Attr, *Val); if (!Name.empty()) WithColor(OS, Color) << Name; else if (Attr == DW_AT_decl_line || Attr == DW_AT_call_line) - OS << *formValue.getAsUnsignedConstant(); + OS << *FormValue.getAsUnsignedConstant(); else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose && - formValue.getAsUnsignedConstant()) { + FormValue.getAsUnsignedConstant()) { if (DumpOpts.ShowAddresses) { // Print the actual address rather than the offset. uint64_t LowPC, HighPC, Index; if (Die.getLowAndHighPC(LowPC, HighPC, Index)) OS << format("0x%016" PRIx64, HighPC); else - formValue.dump(OS, DumpOpts); + FormValue.dump(OS, DumpOpts); } - } else if (Attr == DW_AT_location || Attr == DW_AT_frame_base || - Attr == DW_AT_data_member_location || - Attr == DW_AT_GNU_call_site_value) - dumpLocation(OS, formValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts); + } else if (DWARFAttribute::mayHaveLocationDescription(Attr)) + dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts); else - formValue.dump(OS, DumpOpts); + FormValue.dump(OS, DumpOpts); std::string Space = DumpOpts.ShowAddresses ? " " : ""; @@ -331,25 +324,25 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, // interesting. These attributes are handled below. if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) { if (const char *Name = - Die.getAttributeValueAsReferencedDie(formValue).getName( + Die.getAttributeValueAsReferencedDie(FormValue).getName( DINameKind::LinkageName)) OS << Space << "\"" << Name << '\"'; } else if (Attr == DW_AT_type) { OS << Space << "\""; - dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(formValue)); + dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(FormValue)); OS << '"'; } else if (Attr == DW_AT_APPLE_property_attribute) { - if (Optional<uint64_t> OptVal = formValue.getAsUnsignedConstant()) + if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant()) dumpApplePropertyAttribute(OS, *OptVal); } else if (Attr == DW_AT_ranges) { const DWARFObject &Obj = Die.getDwarfUnit()->getContext().getDWARFObj(); // For DW_FORM_rnglistx we need to dump the offset separately, since // we have only dumped the index so far. - if (formValue.getForm() == DW_FORM_rnglistx) + if (FormValue.getForm() == DW_FORM_rnglistx) if (auto RangeListOffset = - U->getRnglistOffset(*formValue.getAsSectionOffset())) { - DWARFFormValue FV(dwarf::DW_FORM_sec_offset); - FV.setUValue(*RangeListOffset); + U->getRnglistOffset(*FormValue.getAsSectionOffset())) { + DWARFFormValue FV = DWARFFormValue::createFromUValue( + dwarf::DW_FORM_sec_offset, *RangeListOffset); FV.dump(OS, DumpOpts); } if (auto RangesOrError = Die.getAddressRanges()) @@ -403,6 +396,7 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { // DWARF. This corresponds to following the DW_AT_abstract_origin and // DW_AT_specification just once. SmallSet<DWARFDie, 3> Seen; + Seen.insert(*this); while (!Worklist.empty()) { DWARFDie Die = Worklist.back(); @@ -411,19 +405,16 @@ DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const { if (!Die.isValid()) continue; - if (Seen.count(Die)) - continue; - - Seen.insert(Die); - if (auto Value = Die.find(Attrs)) return Value; if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin)) - Worklist.push_back(D); + if (Seen.insert(D).second) + Worklist.push_back(D); if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification)) - Worklist.push_back(D); + if (Seen.insert(D).second) + Worklist.push_back(D); } return None; @@ -438,9 +429,11 @@ DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const { DWARFDie DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const { - if (auto SpecRef = toReference(V)) { - if (auto SpecUnit = U->getUnitVector().getUnitForOffset(*SpecRef)) - return SpecUnit->getDIEForOffset(*SpecRef); + if (auto SpecRef = V.getAsRelativeReference()) { + if (SpecRef->Unit) + return SpecRef->Unit->getDIEForOffset(SpecRef->Unit->getOffset() + SpecRef->Offset); + if (auto SpecUnit = U->getUnitVector().getUnitForOffset(SpecRef->Offset)) + return SpecUnit->getDIEForOffset(SpecRef->Offset); } return DWARFDie(); } @@ -560,10 +553,12 @@ void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine, /// Helper to dump a DIE with all of its parents, but no siblings. static unsigned dumpParentChain(DWARFDie Die, raw_ostream &OS, unsigned Indent, - DIDumpOptions DumpOpts) { + DIDumpOptions DumpOpts, unsigned Depth = 0) { if (!Die) return Indent; - Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts); + if (DumpOpts.ParentRecurseDepth > 0 && Depth >= DumpOpts.ParentRecurseDepth) + return Indent; + Indent = dumpParentChain(Die.getParent(), OS, Indent, DumpOpts, Depth + 1); Die.dump(OS, Indent, DumpOpts); return Indent + 2; } @@ -611,8 +606,8 @@ void DWARFDie::dump(raw_ostream &OS, unsigned Indent, } DWARFDie child = getFirstChild(); - if (DumpOpts.ShowChildren && DumpOpts.RecurseDepth > 0 && child) { - DumpOpts.RecurseDepth--; + if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) { + DumpOpts.ChildRecurseDepth--; DIDumpOptions ChildDumpOpts = DumpOpts; ChildDumpOpts.ShowParents = false; while (child) { @@ -668,7 +663,7 @@ iterator_range<DWARFDie::attribute_iterator> DWARFDie::attributes() const { } DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End) - : Die(D), AttrValue(0), Index(0) { + : Die(D), Index(0) { auto AbbrDecl = Die.getAbbreviationDeclarationPtr(); assert(AbbrDecl && "Must have abbreviation declaration"); if (End) { @@ -690,18 +685,15 @@ void DWARFDie::attribute_iterator::updateForIndex( AttrValue.Attr = AbbrDecl.getAttrByIndex(Index); // Add the previous byte size of any previous attribute value. AttrValue.Offset += AttrValue.ByteSize; - AttrValue.Value.setForm(AbbrDecl.getFormByIndex(Index)); uint32_t ParseOffset = AttrValue.Offset; auto U = Die.getDwarfUnit(); assert(U && "Die must have valid DWARF unit"); - bool b = AttrValue.Value.extractValue(U->getDebugInfoExtractor(), - &ParseOffset, U->getFormParams(), U); - (void)b; - assert(b && "extractValue cannot fail on fully parsed DWARF"); + AttrValue.Value = DWARFFormValue::createFromUnit( + AbbrDecl.getFormByIndex(Index), U, &ParseOffset); AttrValue.ByteSize = ParseOffset - AttrValue.Offset; } else { assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only"); - AttrValue.clear(); + AttrValue = {}; } } @@ -710,3 +702,39 @@ DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() { updateForIndex(*AbbrDecl, Index + 1); return *this; } + +bool DWARFAttribute::mayHaveLocationDescription(dwarf::Attribute Attr) { + switch (Attr) { + // From the DWARF v5 specification. + case DW_AT_location: + case DW_AT_byte_size: + case DW_AT_bit_size: + case DW_AT_string_length: + case DW_AT_lower_bound: + case DW_AT_return_addr: + case DW_AT_bit_stride: + case DW_AT_upper_bound: + case DW_AT_count: + case DW_AT_data_member_location: + case DW_AT_frame_base: + case DW_AT_segment: + case DW_AT_static_link: + case DW_AT_use_location: + case DW_AT_vtable_elem_location: + case DW_AT_allocated: + case DW_AT_associated: + case DW_AT_byte_stride: + case DW_AT_rank: + case DW_AT_call_value: + case DW_AT_call_origin: + case DW_AT_call_target: + case DW_AT_call_target_clobbered: + case DW_AT_call_data_location: + case DW_AT_call_data_value: + // Extensions. + case DW_AT_GNU_call_site_value: + return true; + default: + return false; + } +} diff --git a/lib/DebugInfo/DWARF/DWARFExpression.cpp b/lib/DebugInfo/DWARF/DWARFExpression.cpp index 2df4456053fb..470d4b5364b4 100644 --- a/lib/DebugInfo/DWARF/DWARFExpression.cpp +++ b/lib/DebugInfo/DWARF/DWARFExpression.cpp @@ -1,13 +1,13 @@ //===-- DWARFExpression.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/DWARF/DWARFExpression.h" +#include "llvm/DebugInfo/DWARF/DWARFUnit.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/Support/Format.h" @@ -97,6 +97,11 @@ static DescVector getDescriptions() { Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB); Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB); Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB); + Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB); + + Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef); + Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB); + return Descriptions; } @@ -152,17 +157,21 @@ bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version, case Operation::SizeAddr: if (AddressSize == 8) { Operands[Operand] = Data.getU64(&Offset); - } else { - assert(AddressSize == 4); + } else if (AddressSize == 4) { Operands[Operand] = Data.getU32(&Offset); + } else { + assert(AddressSize == 2); + Operands[Operand] = Data.getU16(&Offset); } break; case Operation::SizeRefAddr: if (getRefAddrSize(AddressSize, Version) == 8) { Operands[Operand] = Data.getU64(&Offset); - } else { - assert(getRefAddrSize(AddressSize, Version) == 4); + } else if (getRefAddrSize(AddressSize, Version) == 4) { Operands[Operand] = Data.getU32(&Offset); + } else { + assert(getRefAddrSize(AddressSize, Version) == 2); + Operands[Operand] = Data.getU16(&Offset); } break; case Operation::SizeLEB: @@ -171,6 +180,9 @@ bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version, else Operands[Operand] = Data.getULEB128(&Offset); break; + case Operation::BaseTypeRef: + Operands[Operand] = Data.getULEB128(&Offset); + break; case Operation::SizeBlock: // We need a size, so this cannot be the first operand if (Operand == 0) @@ -182,6 +194,8 @@ bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version, default: llvm_unreachable("Unknown DWARFExpression Op size"); } + + OperandEndOffsets[Operand] = Offset; } EndOffset = Offset; @@ -222,6 +236,7 @@ static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode, bool DWARFExpression::Operation::print(raw_ostream &OS, const DWARFExpression *Expr, const MCRegisterInfo *RegInfo, + DWARFUnit *U, bool isEH) { if (Error) { OS << "<decoding error>"; @@ -245,14 +260,25 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, if (Size == Operation::SizeNA) break; - if (Size == Operation::SizeBlock) { + 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]); + if (auto Name = Die.find(dwarf::DW_AT_name)) + OS << " \"" << Name->getAsCString() << "\""; + } else { + OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", + Operands[Operand]); + } + } else if (Size == Operation::SizeBlock) { uint32_t Offset = Operands[Operand]; for (unsigned i = 0; i < Operands[Operand - 1]; ++i) OS << format(" 0x%02x", Expr->Data.getU8(&Offset)); } else { if (Signed) OS << format(" %+" PRId64, (int64_t)Operands[Operand]); - else + else if (Opcode != DW_OP_entry_value && + Opcode != DW_OP_GNU_entry_value) OS << format(" 0x%" PRIx64, Operands[Operand]); } } @@ -260,17 +286,60 @@ bool DWARFExpression::Operation::print(raw_ostream &OS, } void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo, - bool IsEH) const { + DWARFUnit *U, bool IsEH) const { + uint32_t EntryValExprSize = 0; for (auto &Op : *this) { - if (!Op.print(OS, this, RegInfo, IsEH)) { + if (!Op.print(OS, this, RegInfo, U, IsEH)) { uint32_t FailOffset = Op.getEndOffset(); while (FailOffset < Data.getData().size()) OS << format(" %02x", Data.getU8(&FailOffset)); return; } + + if (Op.getCode() == DW_OP_entry_value || + Op.getCode() == DW_OP_GNU_entry_value) { + OS << "("; + EntryValExprSize = Op.getRawOperand(0); + continue; + } + + if (EntryValExprSize) { + EntryValExprSize--; + if (EntryValExprSize == 0) + OS << ")"; + } + if (Op.getEndOffset() < Data.getData().size()) OS << ", "; } } +bool DWARFExpression::Operation::verify(DWARFUnit *U) { + + for (unsigned Operand = 0; Operand < 2; ++Operand) { + unsigned Size = Desc.Op[Operand]; + + if (Size == Operation::SizeNA) + break; + + if (Size == Operation::BaseTypeRef) { + auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]); + if (!Die || Die.getTag() != dwarf::DW_TAG_base_type) { + Error = true; + return false; + } + } + } + + return true; +} + +bool DWARFExpression::verify(DWARFUnit *U) { + for (auto &Op : *this) + if (!Op.verify(U)) + return false; + + return true; +} + } // namespace llvm diff --git a/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/lib/DebugInfo/DWARF/DWARFFormValue.cpp index 7719fea63120..290d35511cdb 100644 --- a/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -1,9 +1,8 @@ //===- DWARFFormValue.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 // //===----------------------------------------------------------------------===// @@ -78,6 +77,34 @@ static const DWARFFormValue::FormClass DWARF5FormClasses[] = { }; +DWARFFormValue DWARFFormValue::createFromSValue(dwarf::Form F, int64_t V) { + return DWARFFormValue(F, ValueType(V)); +} + +DWARFFormValue DWARFFormValue::createFromUValue(dwarf::Form F, uint64_t V) { + return DWARFFormValue(F, ValueType(V)); +} + +DWARFFormValue DWARFFormValue::createFromPValue(dwarf::Form F, const char *V) { + return DWARFFormValue(F, ValueType(V)); +} + +DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F, + ArrayRef<uint8_t> D) { + ValueType V; + V.uval = D.size(); + V.data = D.data(); + return DWARFFormValue(F, V); +} + +DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U, + uint32_t *OffsetPtr) { + DWARFFormValue FormValue(F); + FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, + U->getFormParams(), U); + return FormValue; +} + bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData, uint32_t *OffsetPtr, const dwarf::FormParams Params) { @@ -193,13 +220,17 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { default: break; } - // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section offset. - // Don't check for DWARF version here, as some producers may still do this - // by mistake. Also accept DW_FORM_[line_]strp since these are - // .debug_[line_]str section offsets. - return (Form == DW_FORM_data4 || Form == DW_FORM_data8 || - Form == DW_FORM_strp || Form == DW_FORM_line_strp) && - FC == FC_SectionOffset; + + if (FC == FC_SectionOffset) { + if (Form == DW_FORM_strp || Form == DW_FORM_line_strp) + return true; + // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section + // offset. If we don't have a DWARFUnit, default to the old behavior. + if (Form == DW_FORM_data4 || Form == DW_FORM_data8) + return !U || U->getVersion() <= 3; + } + + return false; } bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, @@ -268,7 +299,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, case DW_FORM_data8: case DW_FORM_ref8: case DW_FORM_ref_sup8: - Value.uval = Data.getU64(OffsetPtr); + Value.uval = Data.getRelocatedValue(8, OffsetPtr); break; case DW_FORM_data16: // Treat this like a 16-byte block. @@ -323,7 +354,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, StringRef Str = Data.getData().substr(*OffsetPtr, Value.uval); Value.data = nullptr; if (!Str.empty()) { - Value.data = reinterpret_cast<const uint8_t *>(Str.data()); + Value.data = Str.bytes_begin(); *OffsetPtr += Value.uval; } } @@ -333,7 +364,7 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS, DIDumpOptions DumpOpts, - SectionedAddress SA) const { + object::SectionedAddress SA) const { OS << format("0x%016" PRIx64, SA.Address); dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts, SA.SectionIndex); @@ -370,12 +401,14 @@ void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const { case DW_FORM_addrx3: case DW_FORM_addrx4: case DW_FORM_GNU_addr_index: { - Optional<SectionedAddress> A = U->getAddrOffsetSectionItem(UValue); + if (U == nullptr) { + OS << "<invalid dwarf unit>"; + break; + } + Optional<object::SectionedAddress> A = U->getAddrOffsetSectionItem(UValue); if (!A || DumpOpts.Verbose) AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue); - if (U == nullptr) - OS << "<invalid dwarf unit>"; - else if (A) + if (A) dumpSectionedAddress(AddrOS, DumpOpts, *A); else OS << "<no .debug_addr section>"; @@ -591,14 +624,15 @@ Optional<uint64_t> DWARFFormValue::getAsAddress() const { return SA->Address; return None; } -Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const { +Optional<object::SectionedAddress> +DWARFFormValue::getAsSectionedAddress() const { if (!isFormClass(FC_Address)) return None; if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx) { uint32_t Index = Value.uval; if (!U) return None; - Optional<SectionedAddress> SA = U->getAddrOffsetSectionItem(Index); + Optional<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index); if (!SA) return None; return SA; @@ -607,6 +641,12 @@ Optional<SectionedAddress> DWARFFormValue::getAsSectionedAddress() const { } Optional<uint64_t> DWARFFormValue::getAsReference() const { + if (auto R = getAsRelativeReference()) + return R->Unit ? R->Unit->getOffset() + R->Offset : R->Offset; + return None; +} + +Optional<DWARFFormValue::UnitOffset> DWARFFormValue::getAsRelativeReference() const { if (!isFormClass(FC_Reference)) return None; switch (Form) { @@ -617,11 +657,11 @@ Optional<uint64_t> DWARFFormValue::getAsReference() const { case DW_FORM_ref_udata: if (!U) return None; - return Value.uval + U->getOffset(); + return UnitOffset{const_cast<DWARFUnit*>(U), Value.uval}; case DW_FORM_ref_addr: case DW_FORM_ref_sig8: case DW_FORM_GNU_ref_alt: - return Value.uval; + return UnitOffset{nullptr, Value.uval}; default: return None; } diff --git a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp index 1abd931e3b8b..f5f975578082 100644 --- a/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp +++ b/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp @@ -1,9 +1,8 @@ //===- DWARFGdbIndex.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 // //===----------------------------------------------------------------------===// @@ -121,7 +120,7 @@ bool DWARFGdbIndex::parseImpl(DataExtractor Data) { return false; CuListOffset = Data.getU32(&Offset); - uint32_t CuTypesOffset = Data.getU32(&Offset); + TuListOffset = Data.getU32(&Offset); AddressAreaOffset = Data.getU32(&Offset); SymbolTableOffset = Data.getU32(&Offset); ConstantPoolOffset = Data.getU32(&Offset); @@ -129,7 +128,7 @@ bool DWARFGdbIndex::parseImpl(DataExtractor Data) { if (Offset != CuListOffset) return false; - uint32_t CuListSize = (CuTypesOffset - CuListOffset) / 16; + uint32_t CuListSize = (TuListOffset - CuListOffset) / 16; CuList.reserve(CuListSize); for (uint32_t i = 0; i < CuListSize; ++i) { uint64_t CuOffset = Data.getU64(&Offset); @@ -139,7 +138,7 @@ bool DWARFGdbIndex::parseImpl(DataExtractor Data) { // CU Types are no longer needed as DWARF skeleton type units never made it // into the standard. - uint32_t TuListSize = (AddressAreaOffset - CuTypesOffset) / 24; + uint32_t TuListSize = (AddressAreaOffset - TuListOffset) / 24; TuList.resize(TuListSize); for (uint32_t I = 0; I < TuListSize; ++I) { uint64_t CuOffset = Data.getU64(&Offset); diff --git a/lib/DebugInfo/DWARF/DWARFListTable.cpp b/lib/DebugInfo/DWARF/DWARFListTable.cpp index 462c036d73ad..e38e706227da 100644 --- a/lib/DebugInfo/DWARF/DWARFListTable.cpp +++ b/lib/DebugInfo/DWARF/DWARFListTable.cpp @@ -1,9 +1,8 @@ //===- DWARFListTable.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 // //===----------------------------------------------------------------------===// @@ -26,7 +25,7 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data, "%s table length at offset 0x%" PRIx32, SectionName.data(), *OffsetPtr); // TODO: Add support for DWARF64. - HeaderData.Length = Data.getU32(OffsetPtr); + 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, @@ -74,7 +73,7 @@ Error DWARFListTableHeader::extract(DWARFDataExtractor Data, SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount); Data.setAddressSize(HeaderData.AddrSize); for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) - Offsets.push_back(Data.getU32(OffsetPtr)); + Offsets.push_back(Data.getRelocatedValue(4, OffsetPtr)); return Error::success(); } diff --git a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp index 00be75e1a94d..844920ba5b11 100644 --- a/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp @@ -1,9 +1,8 @@ //===- DWARFTypeUnit.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/DWARF/DWARFUnit.cpp b/lib/DebugInfo/DWARF/DWARFUnit.cpp index 80234665bdeb..b74acf60c747 100644 --- a/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -1,9 +1,8 @@ //===- DWARFUnit.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 // //===----------------------------------------------------------------------===// @@ -198,7 +197,7 @@ DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const { getAddressByteSize()); } -Optional<SectionedAddress> +Optional<object::SectionedAddress> DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const { if (IsDWO) { auto R = Context.info_section_units(); @@ -242,17 +241,21 @@ bool DWARFUnitHeader::extract(DWARFContext &Context, IndexEntry = Entry; if (!IndexEntry && Index) IndexEntry = Index->getFromOffset(*offset_ptr); - Length = debug_info.getU32(offset_ptr); - // FIXME: Support DWARF64. - unsigned SizeOfLength = 4; + Length = debug_info.getRelocatedValue(4, offset_ptr); FormParams.Format = DWARF32; + unsigned SizeOfLength = 4; + if (Length == 0xffffffff) { + Length = debug_info.getU64(offset_ptr); + FormParams.Format = DWARF64; + SizeOfLength = 8; + } FormParams.Version = debug_info.getU16(offset_ptr); if (FormParams.Version >= 5) { UnitType = debug_info.getU8(offset_ptr); FormParams.AddrSize = debug_info.getU8(offset_ptr); - AbbrOffset = debug_info.getU32(offset_ptr); + AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr); } else { - AbbrOffset = debug_info.getRelocatedValue(4, offset_ptr); + AbbrOffset = debug_info.getRelocatedValue(FormParams.getDwarfOffsetByteSize(), offset_ptr); FormParams.AddrSize = debug_info.getU8(offset_ptr); // Fake a unit type based on the section type. This isn't perfect, // but distinguishing compile and type units is generally enough. @@ -432,12 +435,17 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) { // which may differ from the unit's format. DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection, isLittleEndian, 0); - if (IsDWO) - StringOffsetsTableContribution = - determineStringOffsetsTableContributionDWO(DA); - else if (getVersion() >= 5) - StringOffsetsTableContribution = - determineStringOffsetsTableContribution(DA); + 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; + } + } // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to // describe address ranges. @@ -634,7 +642,7 @@ DWARFUnit::getInlinedChainForAddress(uint64_t Address, // First, find the subroutine that contains the given address (the leaf // of inlined chain). DWARFDie SubroutineDIE = - (DWO ? DWO.get() : this)->getSubroutineForAddress(Address); + (DWO ? *DWO : *this).getSubroutineForAddress(Address); if (!SubroutineDIE) return; @@ -745,7 +753,7 @@ const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const { return Abbrevs; } -llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() { +llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() { if (BaseAddr) return BaseAddr; @@ -755,7 +763,7 @@ llvm::Optional<SectionedAddress> DWARFUnit::getBaseAddress() { return BaseAddr; } -Optional<StrOffsetsContributionDescriptor> +Expected<StrOffsetsContributionDescriptor> StrOffsetsContributionDescriptor::validateContributionSize( DWARFDataExtractor &DA) { uint8_t EntrySize = getDwarfOffsetByteSize(); @@ -766,58 +774,94 @@ StrOffsetsContributionDescriptor::validateContributionSize( if (ValidationSize >= Size) if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize)) return *this; - return None; + return createStringError(errc::invalid_argument, "length exceeds section size"); } // Look for a DWARF64-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. -static Optional<StrOffsetsContributionDescriptor> +static Expected<StrOffsetsContributionDescriptor> parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 16)) - return None; + return createStringError(errc::invalid_argument, "section offset exceeds section size"); if (DA.getU32(&Offset) != 0xffffffff) - return None; + return createStringError(errc::invalid_argument, "32 bit contribution referenced from a 64 bit unit"); uint64_t Size = DA.getU64(&Offset); uint8_t Version = DA.getU16(&Offset); (void)DA.getU16(&Offset); // padding // The encoded length includes the 2-byte version field and the 2-byte // padding, so we need to subtract them out when we populate the descriptor. - return {{Offset, Size - 4, Version, DWARF64}}; + return StrOffsetsContributionDescriptor(Offset, Size - 4, Version, DWARF64); } // Look for a DWARF32-formatted contribution to the string offsets table // starting at a given offset and record it in a descriptor. -static Optional<StrOffsetsContributionDescriptor> +static Expected<StrOffsetsContributionDescriptor> parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint32_t Offset) { if (!DA.isValidOffsetForDataOfSize(Offset, 8)) - return None; + return createStringError(errc::invalid_argument, "section offset exceeds section size"); + uint32_t ContributionSize = DA.getU32(&Offset); if (ContributionSize >= 0xfffffff0) - return None; + return createStringError(errc::invalid_argument, "invalid length"); + uint8_t Version = DA.getU16(&Offset); (void)DA.getU16(&Offset); // padding // The encoded length includes the 2-byte version field and the 2-byte // padding, so we need to subtract them out when we populate the descriptor. - return {{Offset, ContributionSize - 4, Version, DWARF32}}; + return StrOffsetsContributionDescriptor(Offset, ContributionSize - 4, Version, + DWARF32); +} + +static Expected<StrOffsetsContributionDescriptor> +parseDWARFStringOffsetsTableHeader(DWARFDataExtractor &DA, + llvm::dwarf::DwarfFormat Format, + uint64_t Offset) { + StrOffsetsContributionDescriptor Desc; + switch (Format) { + 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); + if (!DescOrError) + return DescOrError.takeError(); + Desc = *DescOrError; + break; + } + 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); + if (!DescOrError) + return DescOrError.takeError(); + Desc = *DescOrError; + break; + } + } + return Desc.validateContributionSize(DA); } -Optional<StrOffsetsContributionDescriptor> +Expected<Optional<StrOffsetsContributionDescriptor>> DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) { - auto Offset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base), 0); - Optional<StrOffsetsContributionDescriptor> Descriptor; - // Attempt to find a DWARF64 contribution 16 bytes before the base. - if (Offset >= 16) - Descriptor = - parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset - 16); - // Try to find a DWARF32 contribution 8 bytes before the base. - if (!Descriptor && Offset >= 8) - Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset - 8); - return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor; -} - -Optional<StrOffsetsContributionDescriptor> + uint64_t Offset; + if (IsDWO) { + Offset = 0; + if (DA.getData().data() == nullptr) + return None; + } else { + auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base)); + if (!OptOffset) + return None; + Offset = *OptOffset; + } + auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset); + if (!DescOrError) + return DescOrError.takeError(); + return *DescOrError; +} + +Expected<Optional<StrOffsetsContributionDescriptor>> DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { uint64_t Offset = 0; auto IndexEntry = Header.getIndexEntry(); @@ -826,19 +870,24 @@ DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) { if (C) Offset = C->Offset; if (getVersion() >= 5) { + if (DA.getData().data() == nullptr) + return None; + Offset += Header.getFormat() == dwarf::DwarfFormat::DWARF32 ? 8 : 16; // Look for a valid contribution at the given offset. - auto Descriptor = - parseDWARF64StringOffsetsTableHeader(DA, (uint32_t)Offset); - if (!Descriptor) - Descriptor = parseDWARF32StringOffsetsTableHeader(DA, (uint32_t)Offset); - return Descriptor ? Descriptor->validateContributionSize(DA) : Descriptor; + auto DescOrError = parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), Offset); + if (!DescOrError) + return DescOrError.takeError(); + return *DescOrError; } // Prior to DWARF v5, we derive the contribution size from the // index table (in a package file). In a .dwo file it is simply // the length of the string offsets section. if (!IndexEntry) - return {{0, StringOffsetSection.Data.size(), 4, DWARF32}}; + return { + Optional<StrOffsetsContributionDescriptor>( + {0, StringOffsetSection.Data.size(), 4, DWARF32})}; if (C) - return {{C->Offset, C->Length, 4, DWARF32}}; + return {Optional<StrOffsetsContributionDescriptor>( + {C->Offset, C->Length, 4, DWARF32})}; return None; } diff --git a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp index 84b6c4b81817..047c63461ccf 100644 --- a/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp +++ b/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp @@ -1,9 +1,8 @@ //===- DWARFUnitIndex.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 // //===----------------------------------------------------------------------===// @@ -173,10 +172,9 @@ DWARFUnitIndex::getFromOffset(uint32_t Offset) const { E2->Contributions[InfoColumn].Offset; }); } - auto I = - llvm::upper_bound(OffsetLookup, Offset, [&](uint32_t Offset, Entry *E2) { - return Offset < E2->Contributions[InfoColumn].Offset; - }); + auto I = partition_point(OffsetLookup, [&](Entry *E2) { + return E2->Contributions[InfoColumn].Offset <= Offset; + }); if (I == OffsetLookup.begin()) return nullptr; --I; diff --git a/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/lib/DebugInfo/DWARF/DWARFVerifier.cpp index f8370178b627..c2b3189514a8 100644 --- a/lib/DebugInfo/DWARF/DWARFVerifier.cpp +++ b/lib/DebugInfo/DWARF/DWARFVerifier.cpp @@ -1,9 +1,8 @@ //===- DWARFVerifier.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/DWARF/DWARFVerifier.h" @@ -61,55 +60,47 @@ DWARFVerifier::DieRangeInfo::insert(const DieRangeInfo &RI) { } bool DWARFVerifier::DieRangeInfo::contains(const DieRangeInfo &RHS) const { - // Both list of ranges are sorted so we can make this fast. - - if (Ranges.empty() || RHS.Ranges.empty()) - return false; - - // Since the ranges are sorted we can advance where we start searching with - // this object's ranges as we traverse RHS.Ranges. - auto End = Ranges.end(); - auto Iter = findRange(RHS.Ranges.front()); + auto I1 = Ranges.begin(), E1 = Ranges.end(); + auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end(); + if (I2 == E2) + return true; - // Now linearly walk the ranges in this object and see if they contain each - // ranges from RHS.Ranges. - for (const auto &R : RHS.Ranges) { - while (Iter != End) { - if (Iter->contains(R)) - break; - ++Iter; + DWARFAddressRange R = *I2; + while (I1 != E1) { + bool Covered = I1->LowPC <= R.LowPC; + if (R.LowPC == R.HighPC || (Covered && R.HighPC <= I1->HighPC)) { + if (++I2 == E2) + return true; + R = *I2; + continue; } - if (Iter == End) + if (!Covered) return false; + if (R.LowPC < I1->HighPC) + R.LowPC = I1->HighPC; + ++I1; } - return true; + return false; } bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const { - if (Ranges.empty() || RHS.Ranges.empty()) - return false; - - auto End = Ranges.end(); - auto Iter = findRange(RHS.Ranges.front()); - for (const auto &R : RHS.Ranges) { - if (Iter == End) - return false; - if (R.HighPC <= Iter->LowPC) - continue; - while (Iter != End) { - if (Iter->intersects(R)) - return true; - ++Iter; - } + auto I1 = Ranges.begin(), E1 = Ranges.end(); + auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end(); + while (I1 != E1 && I2 != E2) { + if (I1->intersects(*I2)) + return true; + if (I1->LowPC < I2->LowPC) + ++I1; + else + ++I2; } - return false; } bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, uint32_t *Offset, unsigned UnitIndex, uint8_t &UnitType, bool &isUnitDWARF64) { - uint32_t AbbrOffset, Length; + uint64_t AbbrOffset, Length; uint8_t AddrSize = 0; uint16_t Version; bool Success = true; @@ -123,22 +114,19 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, uint32_t OffsetStart = *Offset; Length = DebugInfoData.getU32(Offset); if (Length == UINT32_MAX) { + Length = DebugInfoData.getU64(Offset); isUnitDWARF64 = true; - OS << format( - "Unit[%d] is in 64-bit DWARF format; cannot verify from this point.\n", - UnitIndex); - return false; } Version = DebugInfoData.getU16(Offset); if (Version >= 5) { UnitType = DebugInfoData.getU8(Offset); AddrSize = DebugInfoData.getU8(Offset); - AbbrOffset = DebugInfoData.getU32(Offset); + AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset); ValidType = dwarf::isUnitType(UnitType); } else { UnitType = 0; - AbbrOffset = DebugInfoData.getU32(Offset); + AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset); AddrSize = DebugInfoData.getU8(Offset); } @@ -166,7 +154,7 @@ bool DWARFVerifier::verifyUnitHeader(const DWARFDataExtractor DebugInfoData, if (!ValidAddrSize) note() << "The address size is unsupported.\n"; } - *Offset = OffsetStart + Length + 4; + *Offset = OffsetStart + Length + (isUnitDWARF64 ? 12 : 4); return Success; } @@ -179,21 +167,11 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) { if (Die.getTag() == DW_TAG_null) continue; - bool HasTypeAttr = false; for (auto AttrValue : Die.attributes()) { NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue); NumUnitErrors += verifyDebugInfoForm(Die, AttrValue); - HasTypeAttr |= (AttrValue.Attr == DW_AT_type); } - if (!HasTypeAttr && (Die.getTag() == DW_TAG_formal_parameter || - Die.getTag() == DW_TAG_variable || - Die.getTag() == DW_TAG_array_type)) { - error() << "DIE with tag " << TagString(Die.getTag()) - << " is missing type attribute:\n"; - dump(Die) << '\n'; - NumUnitErrors++; - } NumUnitErrors += verifyDebugInfoCallSite(Die); } @@ -281,19 +259,12 @@ bool DWARFVerifier::handleDebugAbbrev() { OS << "Verifying .debug_abbrev...\n"; const DWARFObject &DObj = DCtx.getDWARFObj(); - bool noDebugAbbrev = DObj.getAbbrevSection().empty(); - bool noDebugAbbrevDWO = DObj.getAbbrevDWOSection().empty(); - - if (noDebugAbbrev && noDebugAbbrevDWO) { - return true; - } - unsigned NumErrors = 0; - if (!noDebugAbbrev) + if (!DObj.getAbbrevSection().empty()) NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrev()); - - if (!noDebugAbbrevDWO) + if (!DObj.getAbbrevDWOSection().empty()) NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrevDWO()); + return NumErrors == 0; } @@ -503,7 +474,7 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die, bool Error = llvm::any_of(Expression, [](DWARFExpression::Operation &Op) { return Op.isError(); }); - if (Error) + if (Error || !Expression.verify(U)) ReportError("DIE contains invalid DWARF expression:"); }; if (Optional<ArrayRef<uint8_t>> Expr = AttrValue.Value.getAsBlock()) { @@ -629,7 +600,7 @@ unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die, dump(Die) << '\n'; break; } - // Check that the index is within the bounds of the section. + // Check that the index is within the bounds of the section. unsigned ItemSize = DieCU->getDwarfStringOffsetsByteSize(); // Use a 64-bit type to calculate the offset to guard against overflow. uint64_t Offset = @@ -664,9 +635,9 @@ unsigned DWARFVerifier::verifyDebugInfoReferences() { // getting the DIE by offset and emitting an error OS << "Verifying .debug_info references...\n"; unsigned NumErrors = 0; - for (auto Pair : ReferenceToDIEOffsets) { - auto Die = DCtx.getDIEForOffset(Pair.first); - if (Die) + for (const std::pair<uint64_t, std::set<uint32_t>> &Pair : + ReferenceToDIEOffsets) { + if (DCtx.getDIEForOffset(Pair.first)) continue; ++NumErrors; error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first) @@ -731,7 +702,6 @@ void DWARFVerifier::verifyDebugLineRows() { continue; // Verify prologue. - uint32_t MaxFileIndex = LineTable->Prologue.FileNames.size(); uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size(); uint32_t FileIndex = 1; StringMap<uint16_t> FullPathMap; @@ -773,7 +743,7 @@ void DWARFVerifier::verifyDebugLineRows() { uint32_t RowIndex = 0; for (const auto &Row : LineTable->Rows) { // Verify row address. - if (Row.Address < PrevAddress) { + if (Row.Address.Address < PrevAddress) { ++NumDebugLineErrors; error() << ".debug_line[" << format("0x%08" PRIx64, @@ -789,13 +759,16 @@ void DWARFVerifier::verifyDebugLineRows() { } // Verify file index. - if (Row.File > MaxFileIndex) { + if (!LineTable->hasFileAtIndex(Row.File)) { ++NumDebugLineErrors; + bool isDWARF5 = LineTable->Prologue.getVersion() >= 5; error() << ".debug_line[" << format("0x%08" PRIx64, *toSectionOffset(Die.find(DW_AT_stmt_list))) << "][" << RowIndex << "] has invalid file index " << Row.File - << " (valid values are [1," << MaxFileIndex << "]):\n"; + << " (valid values are [" << (isDWARF5 ? "0," : "1,") + << LineTable->Prologue.FileNames.size() + << (isDWARF5 ? ")" : "]") << "):\n"; DWARFDebugLine::Row::dumpTableHeader(OS); Row.dump(OS); OS << '\n'; @@ -803,7 +776,7 @@ void DWARFVerifier::verifyDebugLineRows() { if (Row.EndSequence) PrevAddress = 0; else - PrevAddress = Row.Address; + PrevAddress = Row.Address.Address; ++RowIndex; } } diff --git a/lib/DebugInfo/GSYM/FunctionInfo.cpp b/lib/DebugInfo/GSYM/FunctionInfo.cpp new file mode 100644 index 000000000000..55c36a55b4be --- /dev/null +++ b/lib/DebugInfo/GSYM/FunctionInfo.cpp @@ -0,0 +1,22 @@ +//===- FunctionInfo.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/FunctionInfo.h" + +using namespace llvm; +using namespace gsym; + +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; + return OS; +} diff --git a/lib/DebugInfo/GSYM/InlineInfo.cpp b/lib/DebugInfo/GSYM/InlineInfo.cpp new file mode 100644 index 000000000000..781c1755241d --- /dev/null +++ b/lib/DebugInfo/GSYM/InlineInfo.cpp @@ -0,0 +1,59 @@ +//===- InlineInfo.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/FileEntry.h" +#include "llvm/DebugInfo/GSYM/InlineInfo.h" +#include <algorithm> +#include <inttypes.h> + +using namespace llvm; +using namespace gsym; + + +raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const InlineInfo &II) { + if (!II.isValid()) + return OS; + bool First = true; + for (auto Range : II.Ranges) { + if (First) + First = false; + else + OS << ' '; + OS << Range; + } + OS << " Name = " << HEX32(II.Name) << ", CallFile = " << II.CallFile + << ", CallLine = " << II.CallFile << '\n'; + for (const auto &Child : II.Children) + OS << Child; + return OS; +} + +static bool getInlineStackHelper(const InlineInfo &II, uint64_t Addr, + std::vector<const InlineInfo *> &InlineStack) { + if (II.Ranges.contains(Addr)) { + // If this is the top level that represents the concrete function, + // there will be no name and we shoud clear the inline stack. Otherwise + // we have found an inline call stack that we need to insert. + if (II.Name != 0) + InlineStack.insert(InlineStack.begin(), &II); + for (const auto &Child : II.Children) { + if (::getInlineStackHelper(Child, Addr, InlineStack)) + break; + } + return !InlineStack.empty(); + } + return false; +} + +llvm::Optional<InlineInfo::InlineArray> InlineInfo::getInlineStack(uint64_t Addr) const { + InlineArray Result; + if (getInlineStackHelper(*this, Addr, Result)) + return Result; + return llvm::None; +} diff --git a/lib/DebugInfo/GSYM/Range.cpp b/lib/DebugInfo/GSYM/Range.cpp new file mode 100644 index 000000000000..ca61984dacbd --- /dev/null +++ b/lib/DebugInfo/GSYM/Range.cpp @@ -0,0 +1,55 @@ +//===- Range.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/Range.h" +#include <algorithm> +#include <inttypes.h> + +using namespace llvm; +using namespace gsym; + + +void AddressRanges::insert(AddressRange Range) { + if (Range.size() == 0) + return; + + auto It = llvm::upper_bound(Ranges, Range); + auto It2 = It; + while (It2 != Ranges.end() && It2->Start < Range.End) + ++It2; + if (It != It2) { + Range.End = std::max(Range.End, It2[-1].End); + It = Ranges.erase(It, It2); + } + if (It != Ranges.begin() && Range.Start < It[-1].End) + It[-1].End = std::max(It[-1].End, Range.End); + else + Ranges.insert(It, Range); +} + +bool AddressRanges::contains(uint64_t Addr) const { + auto It = std::partition_point( + Ranges.begin(), Ranges.end(), + [=](const AddressRange &R) { return R.Start <= Addr; }); + return It != Ranges.begin() && Addr < It[-1].End; +} + +raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRange &R) { + return OS << '[' << HEX64(R.Start) << " - " << HEX64(R.End) << ")"; +} + +raw_ostream &llvm::gsym::operator<<(raw_ostream &OS, const AddressRanges &AR) { + size_t Size = AR.size(); + for (size_t I = 0; I < Size; ++I) { + if (I) + OS << ' '; + OS << AR[I]; + } + return OS; +} diff --git a/lib/DebugInfo/MSF/MSFBuilder.cpp b/lib/DebugInfo/MSF/MSFBuilder.cpp index 71609919558a..c6fe764ab7e0 100644 --- a/lib/DebugInfo/MSF/MSFBuilder.cpp +++ b/lib/DebugInfo/MSF/MSFBuilder.cpp @@ -1,9 +1,8 @@ //===- MSFBuilder.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/MSF/MSFCommon.cpp b/lib/DebugInfo/MSF/MSFCommon.cpp index d398304375ac..fb4f0700059c 100644 --- a/lib/DebugInfo/MSF/MSFCommon.cpp +++ b/lib/DebugInfo/MSF/MSFCommon.cpp @@ -1,9 +1,8 @@ //===- MSFCommon.cpp - Common types and functions for MSF files -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/MSF/MSFError.cpp b/lib/DebugInfo/MSF/MSFError.cpp index bfac6bebba3f..b368b802c564 100644 --- a/lib/DebugInfo/MSF/MSFError.cpp +++ b/lib/DebugInfo/MSF/MSFError.cpp @@ -1,9 +1,8 @@ //===- MSFError.cpp - Error extensions for MSF files ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -14,6 +13,7 @@ using namespace llvm; using namespace llvm::msf; +namespace { // FIXME: This class is only here to support the transition to llvm::Error. It // will be removed once this transition is complete. Clients should prefer to // deal with the Error value directly, rather than converting to error_code. @@ -39,6 +39,7 @@ public: llvm_unreachable("Unrecognized msf_error_code"); } }; +} // namespace static llvm::ManagedStatic<MSFErrorCategory> MSFCategory; const std::error_category &llvm::msf::MSFErrCategory() { return *MSFCategory; } diff --git a/lib/DebugInfo/MSF/MappedBlockStream.cpp b/lib/DebugInfo/MSF/MappedBlockStream.cpp index dec28eb30697..df925771f0d9 100644 --- a/lib/DebugInfo/MSF/MappedBlockStream.cpp +++ b/lib/DebugInfo/MSF/MappedBlockStream.cpp @@ -1,9 +1,8 @@ //===- MappedBlockStream.cpp - Reads stream data from an MSF file ---------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIADataStream.cpp b/lib/DebugInfo/PDB/DIA/DIADataStream.cpp index 6a10513fad97..8a806f298d0f 100644 --- a/lib/DebugInfo/PDB/DIA/DIADataStream.cpp +++ b/lib/DebugInfo/PDB/DIA/DIADataStream.cpp @@ -1,9 +1,8 @@ //===- DIADataStream.cpp - DIA implementation of IPDBDataStream -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp index d2451f13e6cb..e4cb4daf94b1 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumDebugStreams.cpp @@ -1,9 +1,8 @@ //==- DIAEnumDebugStreams.cpp - DIA Debug Stream Enumerator impl -*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp index f873f3525df5..8a181b448a27 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumFrameData.cpp @@ -1,9 +1,8 @@ //==- DIAEnumFrameData.cpp ---------------------------------------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp index 6c361b81e33d..7226ab2ba0a0 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumInjectedSources.cpp @@ -1,9 +1,8 @@ //==- DIAEnumSourceFiles.cpp - DIA Source File Enumerator impl ---*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp index 0820d9dc7c9f..6f1d7733fb2d 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumLineNumbers.cpp @@ -1,9 +1,8 @@ //==- DIAEnumLineNumbers.cpp - DIA Line Number Enumerator impl ---*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp index 90c857aa5713..4f9b232a024a 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumSectionContribs.cpp @@ -1,9 +1,8 @@ //==- DIAEnumSectionContribs.cpp ---------------------------------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp index 06595e7ec1c8..943e9e1b4d58 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumSourceFiles.cpp @@ -1,9 +1,8 @@ //==- DIAEnumSourceFiles.cpp - DIA Source File Enumerator impl ---*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp index 48bc32767e6c..5153596d52ae 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumSymbols.cpp @@ -1,9 +1,8 @@ //==- DIAEnumSymbols.cpp - DIA Symbol Enumerator impl ------------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp b/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp index 6fa096156d48..335b575d6542 100644 --- a/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAEnumTables.cpp @@ -1,9 +1,8 @@ //===- DIAEnumTables.cpp - DIA Table Enumerator Impl ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp b/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp index 533cce7923c0..7975156b1abd 100644 --- a/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAFrameData.cpp @@ -1,9 +1,8 @@ //===- DIAFrameData.cpp - DIA impl. of IPDBFrameData -------------- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp b/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp index 1d642f221d79..032b230b5faa 100644 --- a/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp +++ b/lib/DebugInfo/PDB/DIA/DIAInjectedSource.cpp @@ -1,9 +1,8 @@ //===- DIAInjectedSource.cpp - DIA impl for IPDBInjectedSource --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -42,11 +41,11 @@ std::string DIAInjectedSource::getVirtualFileName() const { &IDiaInjectedSource::get_virtualFilename); } -PDB_SourceCompression DIAInjectedSource::getCompression() const { +uint32_t DIAInjectedSource::getCompression() const { DWORD Compression = 0; if (S_OK != SourceFile->get_sourceCompression(&Compression)) return PDB_SourceCompression::None; - return static_cast<PDB_SourceCompression>(Compression); + return static_cast<uint32_t>(Compression); } std::string DIAInjectedSource::getCode() const { diff --git a/lib/DebugInfo/PDB/DIA/DIALineNumber.cpp b/lib/DebugInfo/PDB/DIA/DIALineNumber.cpp index b19be6b595ab..3af02ea36c7b 100644 --- a/lib/DebugInfo/PDB/DIA/DIALineNumber.cpp +++ b/lib/DebugInfo/PDB/DIA/DIALineNumber.cpp @@ -1,9 +1,8 @@ //===- DIALineNumber.cpp - DIA implementation of IPDBLineNumber -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp index cd4d00a13b18..a8ae076e1d6c 100644 --- a/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp +++ b/lib/DebugInfo/PDB/DIA/DIARawSymbol.cpp @@ -1,9 +1,8 @@ //===- DIARawSymbol.cpp - DIA implementation of IPDBRawSymbol ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp b/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp index 8e233ca15161..e2d928f2c4b2 100644 --- a/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp +++ b/lib/DebugInfo/PDB/DIA/DIASectionContrib.cpp @@ -1,9 +1,8 @@ //===- DIASectionContrib.cpp - DIA impl. of IPDBSectionContrib ---- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIASession.cpp b/lib/DebugInfo/PDB/DIA/DIASession.cpp index bd375e172ac0..4e0b8587c613 100644 --- a/lib/DebugInfo/PDB/DIA/DIASession.cpp +++ b/lib/DebugInfo/PDB/DIA/DIASession.cpp @@ -1,9 +1,8 @@ //===- DIASession.cpp - DIA implementation of IPDBSession -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "llvm/DebugInfo/PDB/DIA/DIASession.h" diff --git a/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp b/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp index d3e408166a87..21e757c3a060 100644 --- a/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp +++ b/lib/DebugInfo/PDB/DIA/DIASourceFile.cpp @@ -1,9 +1,8 @@ //===- DIASourceFile.cpp - DIA implementation of IPDBSourceFile -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/DIA/DIATable.cpp b/lib/DebugInfo/PDB/DIA/DIATable.cpp index 6017081b2cb6..33d74abd740e 100644 --- a/lib/DebugInfo/PDB/DIA/DIATable.cpp +++ b/lib/DebugInfo/PDB/DIA/DIATable.cpp @@ -1,9 +1,8 @@ //===- DIATable.cpp - DIA implementation of IPDBTable -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/GenericError.cpp b/lib/DebugInfo/PDB/GenericError.cpp index 256952073e88..70dc094c42ec 100644 --- a/lib/DebugInfo/PDB/GenericError.cpp +++ b/lib/DebugInfo/PDB/GenericError.cpp @@ -1,9 +1,8 @@ //===- Error.cpp - system_error extensions for PDB --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -14,6 +13,7 @@ using namespace llvm; using namespace llvm::pdb; +namespace { // FIXME: This class is only here to support the transition to llvm::Error. It // will be removed once this transition is complete. Clients should prefer to // deal with the Error value directly, rather than converting to error_code. @@ -40,6 +40,7 @@ public: llvm_unreachable("Unrecognized generic_error_code"); } }; +} // namespace static llvm::ManagedStatic<PDBErrorCategory> PDBCategory; const std::error_category &llvm::pdb::PDBErrCategory() { return *PDBCategory; } diff --git a/lib/DebugInfo/PDB/IPDBSourceFile.cpp b/lib/DebugInfo/PDB/IPDBSourceFile.cpp index 8cb1fbef51f4..113ee04bab95 100644 --- a/lib/DebugInfo/PDB/IPDBSourceFile.cpp +++ b/lib/DebugInfo/PDB/IPDBSourceFile.cpp @@ -1,9 +1,8 @@ //===- IPDBSourceFile.cpp - base interface for a PDB source file ----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp b/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp index 931ac7bb81db..5095efcdee3c 100644 --- a/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp +++ b/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp @@ -1,9 +1,8 @@ //===- DbiModuleDescriptor.cpp - PDB module information -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp index ab93efc839a9..20b6c6142547 100644 --- a/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp @@ -1,9 +1,8 @@ //===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -104,7 +103,6 @@ uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const { } void DbiModuleDescriptorBuilder::finalize() { - Layout.SC.Imod = Layout.Mod; Layout.FileNameOffs = 0; // TODO: Fix this Layout.Flags = 0; // TODO: Fix this Layout.C11Bytes = 0; @@ -117,12 +115,15 @@ void DbiModuleDescriptorBuilder::finalize() { // This value includes both the signature field as well as the record bytes // from the symbol stream. - Layout.SymBytes = SymbolByteSize + sizeof(uint32_t); + Layout.SymBytes = + Layout.ModDiStream == kInvalidStreamIndex ? 0 : getNextSymbolOffset(); } Error DbiModuleDescriptorBuilder::finalizeMsfLayout() { this->Layout.ModDiStream = kInvalidStreamIndex; uint32_t C13Size = calculateC13DebugInfoSize(); + if (!C13Size && !SymbolByteSize) + return Error::success(); auto ExpectedSN = MSF.addStream(calculateDiSymbolStreamSize(SymbolByteSize, C13Size)); if (!ExpectedSN) diff --git a/lib/DebugInfo/PDB/Native/DbiModuleList.cpp b/lib/DebugInfo/PDB/Native/DbiModuleList.cpp index eea70b229c67..5cf014e881cd 100644 --- a/lib/DebugInfo/PDB/Native/DbiModuleList.cpp +++ b/lib/DebugInfo/PDB/Native/DbiModuleList.cpp @@ -1,9 +1,8 @@ //===- DbiModuleList.cpp - PDB module information list --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/DbiStream.cpp b/lib/DebugInfo/PDB/Native/DbiStream.cpp index 60ac17b655a7..4eb16804171d 100644 --- a/lib/DebugInfo/PDB/Native/DbiStream.cpp +++ b/lib/DebugInfo/PDB/Native/DbiStream.cpp @@ -1,9 +1,8 @@ //===- DbiStream.cpp - PDB Dbi Stream (Stream 3) Access -------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -127,8 +126,10 @@ Error DbiStream::reload(PDBFile *Pdb) { return EC; if (auto EC = initializeSectionMapData()) return EC; - if (auto EC = initializeFpoRecords(Pdb)) + if (auto EC = initializeOldFpoRecords(Pdb)) return EC; + if (auto EC = initializeNewFpoRecords(Pdb)) + return EC; if (Reader.bytesRemaining() > 0) return make_error<RawError>(raw_error_code::corrupt_file, @@ -201,8 +202,16 @@ FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const { return SectionHeaders; } -FixedStreamArray<object::FpoData> DbiStream::getFpoRecords() { - return FpoRecords; +bool DbiStream::hasOldFpoRecords() const { return OldFpoStream != nullptr; } + +FixedStreamArray<object::FpoData> DbiStream::getOldFpoRecords() const { + return OldFpoRecords; +} + +bool DbiStream::hasNewFpoRecords() const { return NewFpoStream != nullptr; } + +const DebugFrameDataSubsectionRef &DbiStream::getNewFpoRecords() const { + return NewFpoRecords; } const DbiModuleList &DbiStream::modules() const { return Modules; } @@ -247,22 +256,15 @@ Error DbiStream::initializeSectionContributionData() { // Initializes this->SectionHeaders. Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) { - if (!Pdb) - return Error::success(); - - if (DbgStreams.size() == 0) - return Error::success(); + Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr); + if (auto EC = ExpectedStream.takeError()) + return EC; - uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::SectionHdr); - if (StreamNum == kInvalidStreamIndex) + auto &SHS = *ExpectedStream; + if (!SHS) return Error::success(); - if (StreamNum >= Pdb->getNumStreams()) - return make_error<RawError>(raw_error_code::no_stream); - - auto SHS = MappedBlockStream::createIndexedStream( - Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator()); - size_t StreamLen = SHS->getLength(); if (StreamLen % sizeof(object::coff_section)) return make_error<RawError>(raw_error_code::corrupt_file, @@ -279,39 +281,65 @@ Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) { } // Initializes this->Fpos. -Error DbiStream::initializeFpoRecords(PDBFile *Pdb) { - if (!Pdb) - return Error::success(); - - if (DbgStreams.size() == 0) - return Error::success(); - - uint32_t StreamNum = getDebugStreamIndex(DbgHeaderType::NewFPO); +Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) { + Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO); + if (auto EC = ExpectedStream.takeError()) + return EC; - // This means there is no FPO data. - if (StreamNum == kInvalidStreamIndex) + auto &FS = *ExpectedStream; + if (!FS) return Error::success(); - if (StreamNum >= Pdb->getNumStreams()) - return make_error<RawError>(raw_error_code::no_stream); - - auto FS = MappedBlockStream::createIndexedStream( - Pdb->getMsfLayout(), Pdb->getMsfBuffer(), StreamNum, Pdb->getAllocator()); - size_t StreamLen = FS->getLength(); if (StreamLen % sizeof(object::FpoData)) return make_error<RawError>(raw_error_code::corrupt_file, - "Corrupted New FPO stream."); + "Corrupted Old FPO stream."); size_t NumRecords = StreamLen / sizeof(object::FpoData); BinaryStreamReader Reader(*FS); - if (auto EC = Reader.readArray(FpoRecords, NumRecords)) + if (auto EC = Reader.readArray(OldFpoRecords, NumRecords)) return make_error<RawError>(raw_error_code::corrupt_file, - "Corrupted New FPO stream."); - FpoStream = std::move(FS); + "Corrupted Old FPO stream."); + OldFpoStream = std::move(FS); return Error::success(); } +Error DbiStream::initializeNewFpoRecords(PDBFile *Pdb) { + Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream = + createIndexedStreamForHeaderType(Pdb, DbgHeaderType::NewFPO); + if (auto EC = ExpectedStream.takeError()) + return EC; + + auto &FS = *ExpectedStream; + if (!FS) + return Error::success(); + + if (auto EC = NewFpoRecords.initialize(*FS)) + return EC; + + NewFpoStream = std::move(FS); + return Error::success(); +} + +Expected<std::unique_ptr<msf::MappedBlockStream>> +DbiStream::createIndexedStreamForHeaderType(PDBFile *Pdb, + DbgHeaderType Type) const { + if (!Pdb) + return nullptr; + + if (DbgStreams.empty()) + return nullptr; + + uint32_t StreamNum = getDebugStreamIndex(Type); + + // This means there is no such stream. + if (StreamNum == kInvalidStreamIndex) + return nullptr; + + return Pdb->safelyCreateIndexedStream(StreamNum); +} + BinarySubstreamRef DbiStream::getSectionContributionData() const { return SecContrSubstream; } diff --git a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp index 094216ea800a..b7ade0072ee5 100644 --- a/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp @@ -1,9 +1,8 @@ //===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/EnumTables.cpp b/lib/DebugInfo/PDB/Native/EnumTables.cpp index b3837dc72e5b..f5125393695b 100644 --- a/lib/DebugInfo/PDB/Native/EnumTables.cpp +++ b/lib/DebugInfo/PDB/Native/EnumTables.cpp @@ -1,9 +1,8 @@ //===- EnumTables.cpp - Enum to string conversion tables --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp index 57da7003da2b..8ed5b8b44c59 100644 --- a/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp @@ -1,9 +1,8 @@ //===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -31,14 +30,14 @@ using namespace llvm::pdb; using namespace llvm::codeview; struct llvm::pdb::GSIHashStreamBuilder { - struct UdtDenseMapInfo { + struct SymbolDenseMapInfo { static inline CVSymbol getEmptyKey() { static CVSymbol Empty; return Empty; } static inline CVSymbol getTombstoneKey() { - static CVSymbol Tombstone(static_cast<SymbolKind>(-1), - ArrayRef<uint8_t>()); + static CVSymbol Tombstone( + DenseMapInfo<ArrayRef<uint8_t>>::getTombstoneKey()); return Tombstone; } static unsigned getHashValue(const CVSymbol &Val) { @@ -51,7 +50,7 @@ struct llvm::pdb::GSIHashStreamBuilder { std::vector<CVSymbol> Records; uint32_t StreamIndex; - llvm::DenseSet<CVSymbol, UdtDenseMapInfo> UdtHashes; + llvm::DenseSet<CVSymbol, SymbolDenseMapInfo> SymbolHashes; std::vector<PSHashRecord> HashRecords; std::array<support::ulittle32_t, (IPHR_HASH + 32) / 32> HashBitmap; std::vector<support::ulittle32_t> HashBuckets; @@ -67,8 +66,8 @@ struct llvm::pdb::GSIHashStreamBuilder { CodeViewContainer::Pdb)); } void addSymbol(const CVSymbol &Symbol) { - if (Symbol.kind() == S_UDT) { - auto Iter = UdtHashes.insert(Symbol); + if (Symbol.kind() == S_UDT || Symbol.kind() == S_CONSTANT) { + auto Iter = SymbolHashes.insert(Symbol); if (!Iter.second) return; } @@ -263,8 +262,7 @@ static std::vector<ulittle32_t> computeAddrMap(ArrayRef<CVSymbol> Records) { SymOffsets.push_back(SymOffset); SymOffset += Sym.length(); } - std::stable_sort(PublicsByAddr.begin(), PublicsByAddr.end(), - comparePubSymByAddrAndName); + llvm::stable_sort(PublicsByAddr, comparePubSymByAddrAndName); // Fill in the symbol offsets in the appropriate order. std::vector<ulittle32_t> AddrMap; diff --git a/lib/DebugInfo/PDB/Native/GlobalsStream.cpp b/lib/DebugInfo/PDB/Native/GlobalsStream.cpp index e36319566821..f27d60f46815 100644 --- a/lib/DebugInfo/PDB/Native/GlobalsStream.cpp +++ b/lib/DebugInfo/PDB/Native/GlobalsStream.cpp @@ -1,9 +1,8 @@ //===- GlobalsStream.cpp - PDB Index of Symbols by Name ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/lib/DebugInfo/PDB/Native/Hash.cpp b/lib/DebugInfo/PDB/Native/Hash.cpp index 61188ece2dcb..b5c139ecbec0 100644 --- a/lib/DebugInfo/PDB/Native/Hash.cpp +++ b/lib/DebugInfo/PDB/Native/Hash.cpp @@ -1,9 +1,8 @@ //===- Hash.cpp - PDB Hash Functions --------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/HashTable.cpp b/lib/DebugInfo/PDB/Native/HashTable.cpp index cfabc9cd1ad8..dfdcdf1f4eaf 100644 --- a/lib/DebugInfo/PDB/Native/HashTable.cpp +++ b/lib/DebugInfo/PDB/Native/HashTable.cpp @@ -1,9 +1,8 @@ //===- HashTable.cpp - PDB Hash Table -------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/InfoStream.cpp b/lib/DebugInfo/PDB/Native/InfoStream.cpp index 973a520ffca9..f41bb32d69af 100644 --- a/lib/DebugInfo/PDB/Native/InfoStream.cpp +++ b/lib/DebugInfo/PDB/Native/InfoStream.cpp @@ -1,9 +1,8 @@ //===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp index 3b5a2accdba6..42daa7cae799 100644 --- a/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp @@ -1,9 +1,8 @@ //===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp b/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp new file mode 100644 index 000000000000..3f4101db7b93 --- /dev/null +++ b/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp @@ -0,0 +1,65 @@ +//===- InjectedSourceStream.cpp - PDB Headerblock Stream Access -----------===// +// +// 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/PDB/Native/InjectedSourceStream.h" + +#include "llvm/DebugInfo/MSF/MappedBlockStream.h" +#include "llvm/DebugInfo/PDB/Native/Hash.h" +#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" +#include "llvm/DebugInfo/PDB/Native/RawTypes.h" +#include "llvm/Support/BinaryStreamReader.h" +#include "llvm/Support/Endian.h" + +using namespace llvm; +using namespace llvm::msf; +using namespace llvm::support; +using namespace llvm::pdb; + +InjectedSourceStream::InjectedSourceStream( + std::unique_ptr<MappedBlockStream> Stream) + : Stream(std::move(Stream)) {} + +Error InjectedSourceStream::reload(const PDBStringTable &Strings) { + BinaryStreamReader Reader(*Stream); + + if (auto EC = Reader.readObject(Header)) + return EC; + + if (Header->Version != + static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Invalid headerblock header version"); + + if (auto EC = InjectedSourceTable.load(Reader)) + return EC; + + for (const auto& Entry : *this) { + if (Entry.second.Size != sizeof(SrcHeaderBlockEntry)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Invalid headerbock entry size"); + if (Entry.second.Version != + static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne)) + return make_error<RawError>(raw_error_code::corrupt_file, + "Invalid headerbock entry version"); + + // Check that all name references are valid. + auto Name = Strings.getStringForID(Entry.second.FileNI); + if (!Name) + return Name.takeError(); + auto ObjName = Strings.getStringForID(Entry.second.ObjNI); + if (!ObjName) + return ObjName.takeError(); + auto VName = Strings.getStringForID(Entry.second.VFileNI); + if (!VName) + return VName.takeError(); + } + + assert(Reader.bytesRemaining() == 0); + return Error::success(); +} diff --git a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp index 8c97f4a012f0..1445f0bd9e1b 100644 --- a/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp +++ b/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp @@ -1,9 +1,8 @@ //===- ModuleDebugStream.cpp - PDB Module Info Stream Access --------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -15,6 +14,7 @@ #include "llvm/DebugInfo/CodeView/SymbolRecord.h" #include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h" #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h" +#include "llvm/DebugInfo/PDB/Native/RawConstants.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" #include "llvm/Support/BinaryStreamReader.h" #include "llvm/Support/BinaryStreamRef.h" @@ -37,6 +37,17 @@ ModuleDebugStreamRef::~ModuleDebugStreamRef() = default; Error ModuleDebugStreamRef::reload() { BinaryStreamReader Reader(*Stream); + if (Mod.getModuleStreamIndex() != llvm::pdb::kInvalidStreamIndex) { + if (Error E = reloadSerialize(Reader)) + return E; + } + if (Reader.bytesRemaining() > 0) + return make_error<RawError>(raw_error_code::corrupt_file, + "Unexpected bytes in module stream."); + return Error::success(); +} + +Error ModuleDebugStreamRef::reloadSerialize(BinaryStreamReader &Reader) { uint32_t SymbolSize = Mod.getSymbolDebugInfoByteSize(); uint32_t C11Size = Mod.getC11LineInfoByteSize(); uint32_t C13Size = Mod.getC13LineInfoByteSize(); @@ -72,10 +83,6 @@ Error ModuleDebugStreamRef::reload() { return EC; if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize)) return EC; - if (Reader.bytesRemaining() > 0) - return make_error<RawError>(raw_error_code::corrupt_file, - "Unexpected bytes in module stream."); - return Error::success(); } diff --git a/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp index a4eaed90837d..4a88391494cd 100644 --- a/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp +++ b/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp @@ -1,9 +1,8 @@ //===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -35,6 +34,7 @@ uint16_t NamedStreamMapTraits::hashLookupKey(StringRef S) const { // Here, the type HASH is a typedef of unsigned short. // ** It is not a bug that we truncate the result of hashStringV1, in fact // it is a bug if we do not! ** + // See NMTNI::hash() in the reference implementation. return static_cast<uint16_t>(hashStringV1(S)); } @@ -46,8 +46,7 @@ uint32_t NamedStreamMapTraits::lookupKeyToStorageKey(StringRef S) { return NS->appendStringData(S); } -NamedStreamMap::NamedStreamMap() - : HashTraits(*this), OffsetIndexMap(1, HashTraits) {} +NamedStreamMap::NamedStreamMap() : HashTraits(*this), OffsetIndexMap(1) {} Error NamedStreamMap::load(BinaryStreamReader &Stream) { uint32_t StringBufferSize; @@ -99,7 +98,7 @@ uint32_t NamedStreamMap::hashString(uint32_t Offset) const { } bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const { - auto Iter = OffsetIndexMap.find_as(Stream); + auto Iter = OffsetIndexMap.find_as(Stream, HashTraits); if (Iter == OffsetIndexMap.end()) return false; StreamNo = (*Iter).second; @@ -123,5 +122,5 @@ uint32_t NamedStreamMap::appendStringData(StringRef S) { } void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) { - OffsetIndexMap.set_as(Stream, support::ulittle32_t(StreamNo)); + OffsetIndexMap.set_as(Stream, support::ulittle32_t(StreamNo), HashTraits); } diff --git a/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp index efa70b0e7bd8..39ae84acba20 100644 --- a/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp +++ b/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp @@ -1,9 +1,8 @@ //===- NativeCompilandSymbol.cpp - Native impl for compilands ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp b/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp index 6eece3df2db3..54646867bc5f 100644 --- a/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp +++ b/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp @@ -1,9 +1,8 @@ //==- NativeEnumGlobals.cpp - Native Global Enumerator impl ------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp b/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp new file mode 100644 index 000000000000..f17ff5bb01f2 --- /dev/null +++ b/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp @@ -0,0 +1,120 @@ +//==- NativeEnumInjectedSources.cpp - Native Injected Source Enumerator --*-==// +// +// 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/PDB/Native/NativeEnumInjectedSources.h" + +#include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/PDBFile.h" +#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" + +namespace llvm { +namespace pdb { + +namespace { + +Expected<std::string> readStreamData(BinaryStream &Stream, uint32_t Limit) { + uint32_t Offset = 0, DataLength = std::min(Limit, Stream.getLength()); + std::string Result; + Result.reserve(DataLength); + while (Offset < DataLength) { + ArrayRef<uint8_t> Data; + if (auto E = Stream.readLongestContiguousChunk(Offset, Data)) + return std::move(E); + Data = Data.take_front(DataLength - Offset); + Offset += Data.size(); + Result += toStringRef(Data); + } + return Result; +} + +class NativeInjectedSource final : public IPDBInjectedSource { + const SrcHeaderBlockEntry &Entry; + const PDBStringTable &Strings; + PDBFile &File; + +public: + NativeInjectedSource(const SrcHeaderBlockEntry &Entry, + PDBFile &File, const PDBStringTable &Strings) + : Entry(Entry), Strings(Strings), File(File) {} + + uint32_t getCrc32() const override { return Entry.CRC; } + 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; + } + + std::string getObjectFileName() const override { + auto ObjName = Strings.getStringForID(Entry.ObjNI); + assert(ObjName && "InjectedSourceStream should have rejected this"); + return *ObjName; + } + + std::string getVirtualFileName() const override { + auto VName = Strings.getStringForID(Entry.VFileNI); + assert(VName && "InjectedSourceStream should have rejected this"); + return *VName; + } + + 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(); + + // Find stream with that name and read its data. + // FIXME: Consider validating (or even loading) all this in + // InjectedSourceStream so that no error can happen here. + auto ExpectedFileStream = File.safelyCreateNamedStream(StreamName); + if (!ExpectedFileStream) { + consumeError(ExpectedFileStream.takeError()); + return "(failed to open data stream)"; + } + + auto Data = readStreamData(**ExpectedFileStream, Entry.FileSize); + if (!Data) { + consumeError(Data.takeError()); + return "(failed to read data)"; + } + return *Data; + } +}; + +} // namespace + +NativeEnumInjectedSources::NativeEnumInjectedSources( + PDBFile &File, const InjectedSourceStream &IJS, + const PDBStringTable &Strings) + : File(File), Stream(IJS), Strings(Strings), Cur(Stream.begin()) {} + +uint32_t NativeEnumInjectedSources::getChildCount() const { + return static_cast<uint32_t>(Stream.size()); +} + +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, + File, Strings); +} + +std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() { + if (Cur == Stream.end()) + return nullptr; + return make_unique<NativeInjectedSource>((Cur++)->second, File, Strings); +} + +void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); } + +} +} diff --git a/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp b/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp index 6e4d56443a07..c6621924b516 100644 --- a/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp +++ b/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp @@ -1,9 +1,8 @@ //==- NativeEnumModules.cpp - Native Symbol Enumerator impl ------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp index 288a9128147a..ac217df1ee48 100644 --- a/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp +++ b/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp @@ -1,9 +1,8 @@ //==- NativeEnumTypes.cpp - Native Type Enumerator impl ----------*- C++ -*-==// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp index 6dde5d08a500..3f393409129b 100644 --- a/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp +++ b/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp @@ -1,9 +1,8 @@ //===- NativeExeSymbol.cpp - native impl for PDBSymbolExe -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp index 62950cb3e52a..8e43cf24495a 100644 --- a/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp +++ b/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp @@ -1,9 +1,8 @@ //===- NativeRawSymbol.cpp - Native implementation of IPDBRawSymbol -------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeSession.cpp b/lib/DebugInfo/PDB/Native/NativeSession.cpp index 7807e312365c..8a49cb1c5963 100644 --- a/lib/DebugInfo/PDB/Native/NativeSession.cpp +++ b/lib/DebugInfo/PDB/Native/NativeSession.cpp @@ -1,9 +1,8 @@ //===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -14,6 +13,7 @@ #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h" +#include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h" #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h" #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h" #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h" @@ -192,7 +192,17 @@ std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const { std::unique_ptr<IPDBEnumInjectedSources> NativeSession::getInjectedSources() const { - return nullptr; + auto ISS = Pdb->getInjectedSourceStream(); + if (!ISS) { + consumeError(ISS.takeError()); + return nullptr; + } + auto Strings = Pdb->getStringTable(); + if (!Strings) { + consumeError(Strings.takeError()); + return nullptr; + } + return make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings); } std::unique_ptr<IPDBEnumSectionContribs> diff --git a/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp b/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp index 6ebb8cae3a65..704c1254afbf 100644 --- a/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp +++ b/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp @@ -1,9 +1,8 @@ //===- NativeSymbolEnumerator.cpp - info about enumerators ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp b/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp index a52561728a98..80d455ad66e9 100644 --- a/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp +++ b/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp @@ -1,9 +1,8 @@ //===- NativeTypeArray.cpp - info about arrays ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp b/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp index 7b0f13f3c075..a08663aa91ba 100644 --- a/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp +++ b/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp @@ -1,9 +1,8 @@ //===- NativeTypeBuiltin.cpp -------------------------------------- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp index 37176fe083b9..9f5e86281a23 100644 --- a/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp +++ b/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp @@ -1,9 +1,8 @@ //===- NativeTypeEnum.cpp - info about enum type ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp index a9590fffdb87..405303469c18 100644 --- a/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp +++ b/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp @@ -1,9 +1,8 @@ //===- NativeTypeFunctionSig.cpp - info about function signature -*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp b/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp index bd8ecb6c4007..32dcfc235954 100644 --- a/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp +++ b/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp @@ -1,9 +1,8 @@ //===- NativeTypePointer.cpp - info about pointer type ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp b/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp index 3abf91dcc6a3..be67846c0b24 100644 --- a/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp +++ b/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp @@ -1,9 +1,8 @@ //===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/PDBFile.cpp b/lib/DebugInfo/PDB/Native/PDBFile.cpp index a1f8786ff12f..983031dfcb78 100644 --- a/lib/DebugInfo/PDB/Native/PDBFile.cpp +++ b/lib/DebugInfo/PDB/Native/PDBFile.cpp @@ -1,9 +1,8 @@ //===- PDBFile.cpp - Low level interface to a PDB file ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -15,6 +14,7 @@ #include "llvm/DebugInfo/PDB/Native/DbiStream.h" #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h" #include "llvm/DebugInfo/PDB/Native/InfoStream.h" +#include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h" #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h" #include "llvm/DebugInfo/PDB/Native/PublicsStream.h" #include "llvm/DebugInfo/PDB/Native/RawError.h" @@ -234,7 +234,8 @@ ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const { return ContainerLayout.DirectoryBlocks; } -std::unique_ptr<MappedBlockStream> PDBFile::createIndexedStream(uint16_t SN) { +std::unique_ptr<MappedBlockStream> +PDBFile::createIndexedStream(uint16_t SN) const { if (SN == kInvalidStreamIndex) return nullptr; return MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer, SN, @@ -259,8 +260,8 @@ Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() { if (!DbiS) return DbiS.takeError(); - auto GlobalS = safelyCreateIndexedStream( - ContainerLayout, *Buffer, DbiS->getGlobalSymbolStreamIndex()); + auto GlobalS = + safelyCreateIndexedStream(DbiS->getGlobalSymbolStreamIndex()); if (!GlobalS) return GlobalS.takeError(); auto TempGlobals = llvm::make_unique<GlobalsStream>(std::move(*GlobalS)); @@ -273,7 +274,7 @@ Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() { Expected<InfoStream &> PDBFile::getPDBInfoStream() { if (!Info) { - auto InfoS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamPDB); + auto InfoS = safelyCreateIndexedStream(StreamPDB); if (!InfoS) return InfoS.takeError(); auto TempInfo = llvm::make_unique<InfoStream>(std::move(*InfoS)); @@ -286,7 +287,7 @@ Expected<InfoStream &> PDBFile::getPDBInfoStream() { Expected<DbiStream &> PDBFile::getPDBDbiStream() { if (!Dbi) { - auto DbiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamDBI); + auto DbiS = safelyCreateIndexedStream(StreamDBI); if (!DbiS) return DbiS.takeError(); auto TempDbi = llvm::make_unique<DbiStream>(std::move(*DbiS)); @@ -299,7 +300,7 @@ Expected<DbiStream &> PDBFile::getPDBDbiStream() { Expected<TpiStream &> PDBFile::getPDBTpiStream() { if (!Tpi) { - auto TpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamTPI); + auto TpiS = safelyCreateIndexedStream(StreamTPI); if (!TpiS) return TpiS.takeError(); auto TempTpi = llvm::make_unique<TpiStream>(*this, std::move(*TpiS)); @@ -315,7 +316,7 @@ Expected<TpiStream &> PDBFile::getPDBIpiStream() { if (!hasPDBIpiStream()) return make_error<RawError>(raw_error_code::no_stream); - auto IpiS = safelyCreateIndexedStream(ContainerLayout, *Buffer, StreamIPI); + auto IpiS = safelyCreateIndexedStream(StreamIPI); if (!IpiS) return IpiS.takeError(); auto TempIpi = llvm::make_unique<TpiStream>(*this, std::move(*IpiS)); @@ -332,8 +333,8 @@ Expected<PublicsStream &> PDBFile::getPDBPublicsStream() { if (!DbiS) return DbiS.takeError(); - auto PublicS = safelyCreateIndexedStream( - ContainerLayout, *Buffer, DbiS->getPublicSymbolStreamIndex()); + auto PublicS = + safelyCreateIndexedStream(DbiS->getPublicSymbolStreamIndex()); if (!PublicS) return PublicS.takeError(); auto TempPublics = llvm::make_unique<PublicsStream>(std::move(*PublicS)); @@ -351,8 +352,7 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() { return DbiS.takeError(); uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex(); - auto SymbolS = - safelyCreateIndexedStream(ContainerLayout, *Buffer, SymbolStreamNum); + auto SymbolS = safelyCreateIndexedStream(SymbolStreamNum); if (!SymbolS) return SymbolS.takeError(); @@ -366,17 +366,7 @@ Expected<SymbolStream &> PDBFile::getPDBSymbolStream() { Expected<PDBStringTable &> PDBFile::getStringTable() { if (!Strings) { - auto IS = getPDBInfoStream(); - if (!IS) - return IS.takeError(); - - Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names"); - if (!ExpectedNSI) - return ExpectedNSI.takeError(); - uint32_t NameStreamIndex = *ExpectedNSI; - - auto NS = - safelyCreateIndexedStream(ContainerLayout, *Buffer, NameStreamIndex); + auto NS = safelyCreateNamedStream("/names"); if (!NS) return NS.takeError(); @@ -391,6 +381,24 @@ Expected<PDBStringTable &> PDBFile::getStringTable() { return *Strings; } +Expected<InjectedSourceStream &> PDBFile::getInjectedSourceStream() { + if (!InjectedSources) { + auto IJS = safelyCreateNamedStream("/src/headerblock"); + if (!IJS) + return IJS.takeError(); + + auto Strings = getStringTable(); + if (!Strings) + return Strings.takeError(); + + auto IJ = llvm::make_unique<InjectedSourceStream>(std::move(*IJS)); + if (auto EC = IJ->reload(*Strings)) + return std::move(EC); + InjectedSources = std::move(IJ); + } + return *InjectedSources; +} + uint32_t PDBFile::getPointerSize() { auto DbiS = getPDBDbiStream(); if (!DbiS) @@ -459,16 +467,41 @@ bool PDBFile::hasPDBStringTable() { return true; } +bool PDBFile::hasPDBInjectedSourceStream() { + auto IS = getPDBInfoStream(); + if (!IS) + return false; + Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/src/headerblock"); + if (!ExpectedNSI) { + consumeError(ExpectedNSI.takeError()); + return false; + } + assert(*ExpectedNSI < getNumStreams()); + return true; +} + /// Wrapper around MappedBlockStream::createIndexedStream() that checks if a /// stream with that index actually exists. If it does not, the return value /// will have an MSFError with code msf_error_code::no_stream. Else, the return /// value will contain the stream returned by createIndexedStream(). Expected<std::unique_ptr<MappedBlockStream>> -PDBFile::safelyCreateIndexedStream(const MSFLayout &Layout, - BinaryStreamRef MsfData, - uint32_t StreamIndex) const { +PDBFile::safelyCreateIndexedStream(uint32_t StreamIndex) const { if (StreamIndex >= getNumStreams()) + // This rejects kInvalidStreamIndex with an error as well. return make_error<RawError>(raw_error_code::no_stream); - return MappedBlockStream::createIndexedStream(Layout, MsfData, StreamIndex, - Allocator); + return createIndexedStream(StreamIndex); +} + +Expected<std::unique_ptr<MappedBlockStream>> +PDBFile::safelyCreateNamedStream(StringRef Name) { + auto IS = getPDBInfoStream(); + if (!IS) + return IS.takeError(); + + Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex(Name); + if (!ExpectedNSI) + return ExpectedNSI.takeError(); + uint32_t NameStreamIndex = *ExpectedNSI; + + return safelyCreateIndexedStream(NameStreamIndex); } diff --git a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp index e0ceb7499ee5..8f5a048ea4b5 100644 --- a/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp @@ -1,9 +1,8 @@ //===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -35,7 +34,7 @@ using namespace llvm::support; PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator) : Allocator(Allocator), InjectedSourceHashTraits(Strings), - InjectedSourceTable(2, InjectedSourceHashTraits) {} + InjectedSourceTable(2) {} PDBFileBuilder::~PDBFileBuilder() {} @@ -190,7 +189,8 @@ Error PDBFileBuilder::finalizeMsfLayout() { static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne); Entry.CRC = CRC.getCRC(); StringRef VName = getStringTableBuilder().getStringForId(IS.VNameIndex); - InjectedSourceTable.set_as(VName, std::move(Entry)); + InjectedSourceTable.set_as(VName, std::move(Entry), + InjectedSourceHashTraits); } uint32_t SrcHeaderBlockSize = diff --git a/lib/DebugInfo/PDB/Native/PDBStringTable.cpp b/lib/DebugInfo/PDB/Native/PDBStringTable.cpp index afeea32043dd..2be1656e06bb 100644 --- a/lib/DebugInfo/PDB/Native/PDBStringTable.cpp +++ b/lib/DebugInfo/PDB/Native/PDBStringTable.cpp @@ -1,9 +1,8 @@ //===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp b/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp index d9dcabf3d958..f7f36901e4d4 100644 --- a/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp @@ -1,9 +1,8 @@ //===- PDBStringTableBuilder.cpp - PDB String Table -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -27,7 +26,13 @@ StringTableHashTraits::StringTableHashTraits(PDBStringTableBuilder &Table) : Table(&Table) {} uint32_t StringTableHashTraits::hashLookupKey(StringRef S) const { - return Table->getIdForString(S); + // The reference implementation doesn't include code for /src/headerblock + // handling, but it can only read natvis entries lld's PDB files if + // this hash function truncates the hash to 16 bit. + // PDB/include/misc.h in the reference implementation has a hashSz() function + // that returns an unsigned short, that seems what's being used for + // /src/headerblock. + return static_cast<uint16_t>(Table->getIdForString(S)); } StringRef StringTableHashTraits::storageKeyToLookupKey(uint32_t Offset) const { @@ -50,63 +55,75 @@ StringRef PDBStringTableBuilder::getStringForId(uint32_t Id) const { return Strings.getStringForId(Id); } -// This is a precomputed list of Buckets given the specified number of -// strings. Matching the reference algorithm exactly is not strictly -// necessary for correctness, but it helps when comparing LLD's PDBs with -// Microsoft's PDBs so as to eliminate superfluous differences. -static std::map<uint32_t, uint32_t> StringsToBuckets = { - {1, 2}, - {2, 4}, - {4, 7}, - {6, 11}, - {9, 17}, - {13, 26}, - {20, 40}, - {31, 61}, - {46, 92}, - {70, 139}, - {105, 209}, - {157, 314}, - {236, 472}, - {355, 709}, - {532, 1064}, - {799, 1597}, - {1198, 2396}, - {1798, 3595}, - {2697, 5393}, - {4045, 8090}, - {6068, 12136}, - {9103, 18205}, - {13654, 27308}, - {20482, 40963}, - {30723, 61445}, - {46084, 92168}, - {69127, 138253}, - {103690, 207380}, - {155536, 311071}, - {233304, 466607}, - {349956, 699911}, - {524934, 1049867}, - {787401, 1574801}, - {1181101, 2362202}, - {1771652, 3543304}, - {2657479, 5314957}, - {3986218, 7972436}, - {5979328, 11958655}, - {8968992, 17937983}, - {13453488, 26906975}, - {20180232, 40360463}, - {30270348, 60540695}, - {45405522, 90811043}, - {68108283, 136216565}, - {102162424, 204324848}, - {153243637, 306487273}, - {229865455, 459730910}, - {344798183, 689596366}, - {517197275, 1034394550}, - {775795913, 1551591826}}; - static uint32_t computeBucketCount(uint32_t NumStrings) { + // This is a precomputed list of Buckets given the specified number of + // strings. Matching the reference algorithm exactly is not strictly + // necessary for correctness, but it helps when comparing LLD's PDBs with + // Microsoft's PDBs so as to eliminate superfluous differences. + // The reference implementation does (in nmt.h, NMT::grow()): + // unsigned StringCount = 0; + // unsigned BucketCount = 1; + // fn insert() { + // ++StringCount; + // if (BucketCount * 3 / 4 < StringCount) + // BucketCount = BucketCount * 3 / 2 + 1; + // } + // This list contains all StringCount, BucketCount pairs where BucketCount was + // just incremented. It ends before the first BucketCount entry where + // BucketCount * 3 would overflow a 32-bit unsigned int. + static std::map<uint32_t, uint32_t> StringsToBuckets = { + {0, 1}, + {1, 2}, + {2, 4}, + {4, 7}, + {6, 11}, + {9, 17}, + {13, 26}, + {20, 40}, + {31, 61}, + {46, 92}, + {70, 139}, + {105, 209}, + {157, 314}, + {236, 472}, + {355, 709}, + {532, 1064}, + {799, 1597}, + {1198, 2396}, + {1798, 3595}, + {2697, 5393}, + {4045, 8090}, + {6068, 12136}, + {9103, 18205}, + {13654, 27308}, + {20482, 40963}, + {30723, 61445}, + {46084, 92168}, + {69127, 138253}, + {103690, 207380}, + {155536, 311071}, + {233304, 466607}, + {349956, 699911}, + {524934, 1049867}, + {787401, 1574801}, + {1181101, 2362202}, + {1771652, 3543304}, + {2657479, 5314957}, + {3986218, 7972436}, + {5979328, 11958655}, + {8968992, 17937983}, + {13453488, 26906975}, + {20180232, 40360463}, + {30270348, 60540695}, + {45405522, 90811043}, + {68108283, 136216565}, + {102162424, 204324848}, + {153243637, 306487273}, + {229865455, 459730910}, + {344798183, 689596366}, + {517197275, 1034394550}, + {775795913, 1551591826}, + {1163693870, 2327387740}}; auto Entry = StringsToBuckets.lower_bound(NumStrings); assert(Entry != StringsToBuckets.end()); return Entry->second; diff --git a/lib/DebugInfo/PDB/Native/PublicsStream.cpp b/lib/DebugInfo/PDB/Native/PublicsStream.cpp index f6466eb80464..a33bf03bf8fb 100644 --- a/lib/DebugInfo/PDB/Native/PublicsStream.cpp +++ b/lib/DebugInfo/PDB/Native/PublicsStream.cpp @@ -1,9 +1,8 @@ //===- PublicsStream.cpp - PDB Public Symbol Stream -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // diff --git a/lib/DebugInfo/PDB/Native/RawError.cpp b/lib/DebugInfo/PDB/Native/RawError.cpp index dec9797088f2..ed6cf0839675 100644 --- a/lib/DebugInfo/PDB/Native/RawError.cpp +++ b/lib/DebugInfo/PDB/Native/RawError.cpp @@ -5,6 +5,7 @@ using namespace llvm; using namespace llvm::pdb; +namespace { // FIXME: This class is only here to support the transition to llvm::Error. It // will be removed once this transition is complete. Clients should prefer to // deal with the Error value directly, rather than converting to error_code. @@ -44,6 +45,7 @@ public: llvm_unreachable("Unrecognized raw_error_code"); } }; +} // namespace static llvm::ManagedStatic<RawErrorCategory> RawCategory; const std::error_category &llvm::pdb::RawErrCategory() { return *RawCategory; } diff --git a/lib/DebugInfo/PDB/Native/SymbolStream.cpp b/lib/DebugInfo/PDB/Native/SymbolStream.cpp index 2d8d04ceca4d..003840b6e67e 100644 --- a/lib/DebugInfo/PDB/Native/SymbolStream.cpp +++ b/lib/DebugInfo/PDB/Native/SymbolStream.cpp @@ -1,9 +1,8 @@ //===- SymbolStream.cpp - PDB Symbol Stream Access ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/lib/DebugInfo/PDB/Native/TpiHashing.cpp index 18708826ffc7..b21b82bf76fd 100644 --- a/lib/DebugInfo/PDB/Native/TpiHashing.cpp +++ b/lib/DebugInfo/PDB/Native/TpiHashing.cpp @@ -1,9 +1,8 @@ //===- TpiHashing.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/Native/TpiStream.cpp b/lib/DebugInfo/PDB/Native/TpiStream.cpp index f234d446e6a0..8ee7f897b8bb 100644 --- a/lib/DebugInfo/PDB/Native/TpiStream.cpp +++ b/lib/DebugInfo/PDB/Native/TpiStream.cpp @@ -1,9 +1,8 @@ //===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ----------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -79,14 +78,13 @@ Error TpiStream::reload() { // Hash indices, hash values, etc come from the hash stream. if (Header->HashStreamIndex != kInvalidStreamIndex) { - if (Header->HashStreamIndex >= Pdb.getNumStreams()) + auto HS = Pdb.safelyCreateIndexedStream(Header->HashStreamIndex); + if (!HS) { + consumeError(HS.takeError()); return make_error<RawError>(raw_error_code::corrupt_file, "Invalid TPI hash stream index."); - - auto HS = MappedBlockStream::createIndexedStream( - Pdb.getMsfLayout(), Pdb.getMsfBuffer(), Header->HashStreamIndex, - Pdb.getAllocator()); - BinaryStreamReader HSR(*HS); + } + BinaryStreamReader HSR(**HS); // There should be a hash value for every type record, or no hashes at all. uint32_t NumHashValues = @@ -111,7 +109,7 @@ Error TpiStream::reload() { return EC; } - HashStream = std::move(HS); + HashStream = std::move(*HS); } Types = llvm::make_unique<LazyRandomTypeCollection>( diff --git a/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp index 8dd30018028e..6b308453c2de 100644 --- a/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp +++ b/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp @@ -1,9 +1,8 @@ //===- TpiStreamBuilder.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 // //===----------------------------------------------------------------------===// @@ -77,7 +76,7 @@ Error TpiStreamBuilder::finalize() { H->HashStreamIndex = HashStreamIndex; H->HashAuxStreamIndex = kInvalidStreamIndex; H->HashKeySize = sizeof(ulittle32_t); - H->NumHashBuckets = MinTpiHashBuckets; + H->NumHashBuckets = MaxTpiHashBuckets - 1; // Recall that hash values go into a completely different stream identified by // the `HashStreamIndex` field of the `TpiStreamHeader`. Therefore, the data @@ -130,7 +129,7 @@ Error TpiStreamBuilder::finalizeMsfLayout() { ulittle32_t *H = Allocator.Allocate<ulittle32_t>(TypeHashes.size()); MutableArrayRef<ulittle32_t> HashBuffer(H, TypeHashes.size()); for (uint32_t I = 0; I < TypeHashes.size(); ++I) { - HashBuffer[I] = TypeHashes[I] % MinTpiHashBuckets; + HashBuffer[I] = TypeHashes[I] % (MaxTpiHashBuckets - 1); } ArrayRef<uint8_t> Bytes( reinterpret_cast<const uint8_t *>(HashBuffer.data()), @@ -153,9 +152,12 @@ Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout, if (auto EC = Writer.writeObject(*Header)) return EC; - for (auto Rec : TypeRecords) + for (auto Rec : TypeRecords) { + assert(!Rec.empty()); // An empty record will not write anything, but it + // would shift all offsets from here on. if (auto EC = Writer.writeBytes(Rec)) return EC; + } if (HashStreamIndex != kInvalidStreamIndex) { auto HVS = WritableMappedBlockStream::createIndexedStream( diff --git a/lib/DebugInfo/PDB/PDB.cpp b/lib/DebugInfo/PDB/PDB.cpp index fc1ad8bcd7cd..e7b968cb7bea 100644 --- a/lib/DebugInfo/PDB/PDB.cpp +++ b/lib/DebugInfo/PDB/PDB.cpp @@ -1,9 +1,8 @@ //===- PDB.cpp - base header file for creating a PDB reader ---------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBContext.cpp b/lib/DebugInfo/PDB/PDBContext.cpp index df0feac2bc40..e452f1d4ced7 100644 --- a/lib/DebugInfo/PDB/PDBContext.cpp +++ b/lib/DebugInfo/PDB/PDBContext.cpp @@ -1,9 +1,8 @@ //===-- PDBContext.cpp ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===/ @@ -31,14 +30,14 @@ PDBContext::PDBContext(const COFFObjectFile &Object, void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){} -DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address, +DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier) { DILineInfo Result; - Result.FunctionName = getFunctionName(Address, Specifier.FNKind); + Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind); uint32_t Length = 1; std::unique_ptr<PDBSymbol> Symbol = - Session->findSymbolByAddress(Address, PDB_SymType::None); + Session->findSymbolByAddress(Address.Address, PDB_SymType::None); if (auto Func = dyn_cast_or_null<PDBSymbolFunc>(Symbol.get())) { Length = Func->getLength(); } else if (auto Data = dyn_cast_or_null<PDBSymbolData>(Symbol.get())) { @@ -47,7 +46,7 @@ DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address, // If we couldn't find a symbol, then just assume 1 byte, so that we get // only the line number of the first instruction. - auto LineNumbers = Session->findLineNumbersByAddress(Address, Length); + auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Length); if (!LineNumbers || LineNumbers->getChildCount() == 0) return Result; @@ -64,26 +63,27 @@ DILineInfo PDBContext::getLineInfoForAddress(uint64_t Address, } DILineInfoTable -PDBContext::getLineInfoForAddressRange(uint64_t Address, uint64_t Size, +PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address, + uint64_t Size, DILineInfoSpecifier Specifier) { if (Size == 0) return DILineInfoTable(); DILineInfoTable Table; - auto LineNumbers = Session->findLineNumbersByAddress(Address, Size); + auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size); if (!LineNumbers || LineNumbers->getChildCount() == 0) return Table; while (auto LineInfo = LineNumbers->getNext()) { - DILineInfo LineEntry = - getLineInfoForAddress(LineInfo->getVirtualAddress(), Specifier); + DILineInfo LineEntry = getLineInfoForAddress( + {LineInfo->getVirtualAddress(), Address.SectionIndex}, Specifier); Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry)); } return Table; } DIInliningInfo -PDBContext::getInliningInfoForAddress(uint64_t Address, +PDBContext::getInliningInfoForAddress(object::SectionedAddress Address, DILineInfoSpecifier Specifier) { DIInliningInfo InlineInfo; DILineInfo Frame = getLineInfoForAddress(Address, Specifier); @@ -91,6 +91,11 @@ PDBContext::getInliningInfoForAddress(uint64_t Address, return InlineInfo; } +std::vector<DILocal> +PDBContext::getLocalsForAddress(object::SectionedAddress Address) { + return std::vector<DILocal>(); +} + std::string PDBContext::getFunctionName(uint64_t Address, DINameKind NameKind) const { if (NameKind == DINameKind::None) diff --git a/lib/DebugInfo/PDB/PDBExtras.cpp b/lib/DebugInfo/PDB/PDBExtras.cpp index 0d8af232cd92..354a99476c4b 100644 --- a/lib/DebugInfo/PDB/PDBExtras.cpp +++ b/lib/DebugInfo/PDB/PDBExtras.cpp @@ -1,9 +1,8 @@ //===- PDBExtras.cpp - helper functions and classes for PDBs --------------===// // -// 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 // //===----------------------------------------------------------------------===// @@ -118,13 +117,37 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_DataKind &Data) { } raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, - const codeview::RegisterId &Reg) { - switch (Reg) { -#define CV_REGISTER(name, val) case codeview::RegisterId::name: OS << #name; return OS; + const llvm::codeview::CPURegister &CpuReg) { + if (CpuReg.Cpu == llvm::codeview::CPUType::ARM64) { + switch (CpuReg.Reg) { +#define CV_REGISTERS_ARM64 +#define CV_REGISTER(name, val) \ + case codeview::RegisterId::name: \ + OS << #name; \ + return OS; +#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" +#undef CV_REGISTER +#undef CV_REGISTERS_ARM64 + + default: + break; + } + } else { + switch (CpuReg.Reg) { +#define CV_REGISTERS_X86 +#define CV_REGISTER(name, val) \ + case codeview::RegisterId::name: \ + OS << #name; \ + return OS; #include "llvm/DebugInfo/CodeView/CodeViewRegisters.def" #undef CV_REGISTER +#undef CV_REGISTERS_X86 + + default: + break; + } } - OS << static_cast<int>(Reg); + OS << static_cast<int>(CpuReg.Reg); return OS; } @@ -193,6 +216,7 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_Lang &Lang) { CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, MSIL, OS) CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, HLSL, OS) CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, D, OS) + CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Swift, OS) } return OS; } @@ -296,14 +320,17 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, return OS; } -raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, - const PDB_SourceCompression &Compression) { +raw_ostream &llvm::pdb::dumpPDBSourceCompression(raw_ostream &OS, + uint32_t Compression) { switch (Compression) { CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, None, OS) CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, Huffman, OS) CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, LZ, OS) CASE_OUTPUT_ENUM_CLASS_STR(PDB_SourceCompression, RunLengthEncoded, "RLE", OS) + CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, DotNet, OS) + default: + OS << "Unknown (" << Compression << ")"; } return OS; } diff --git a/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp b/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp index 951909295d13..8eb3311b09e3 100644 --- a/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp +++ b/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp @@ -1,9 +1,8 @@ //===- PDBInterfaceAnchors.h - defines class anchor funcions ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // Class anchors are necessary per the LLVM Coding style guide, to ensure that diff --git a/lib/DebugInfo/PDB/PDBSymDumper.cpp b/lib/DebugInfo/PDB/PDBSymDumper.cpp index 2f819312e54e..0956a32f4a49 100644 --- a/lib/DebugInfo/PDB/PDBSymDumper.cpp +++ b/lib/DebugInfo/PDB/PDBSymDumper.cpp @@ -1,9 +1,8 @@ //===- PDBSymDumper.cpp - ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbol.cpp b/lib/DebugInfo/PDB/PDBSymbol.cpp index d492edafdafe..34c8ac41d45b 100644 --- a/lib/DebugInfo/PDB/PDBSymbol.cpp +++ b/lib/DebugInfo/PDB/PDBSymbol.cpp @@ -1,9 +1,8 @@ //===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp b/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp index cb1a9bee8024..0fa83efb7ae0 100644 --- a/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolAnnotation.cpp - --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolBlock.cpp b/lib/DebugInfo/PDB/PDBSymbolBlock.cpp index 13eec9734d02..9452282a8817 100644 --- a/lib/DebugInfo/PDB/PDBSymbolBlock.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolBlock.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolBlock.cpp - -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp b/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp index bbc5e6dd2a17..9b2883546305 100644 --- a/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolCompiland.cpp - compiland details ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// @@ -91,16 +90,16 @@ std::string PDBSymbolCompiland::getSourceFileFullPath() const { PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp; auto SrcFiles = Session.getSourceFilesForCompiland(*this); if (SrcFiles) { - bool LangC = (Lang == PDB_Lang::Cpp || Lang == PDB_Lang::C); while (auto File = SrcFiles->getNext()) { std::string FileName = File->getFileName(); auto file_extension = sys::path::extension(FileName); if (StringSwitch<bool>(file_extension.lower()) - .Case(".cpp", LangC) - .Case(".c", LangC) - .Case(".cc", LangC) - .Case(".cxx", LangC) + .Case(".cpp", Lang == PDB_Lang::Cpp) + .Case(".cc", Lang == PDB_Lang::Cpp) + .Case(".cxx", Lang == PDB_Lang::Cpp) + .Case(".c", Lang == PDB_Lang::C) .Case(".asm", Lang == PDB_Lang::Masm) + .Case(".swift", Lang == PDB_Lang::Swift) .Default(false)) return File->getFileName(); } diff --git a/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp b/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp index bdd8535a3ef3..0d86dfe1e632 100644 --- a/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolCompilandDetails.cpp - compiland details --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp b/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp index f88df2df6be4..61f119405fd9 100644 --- a/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolCompilandEnv.cpp - compiland env variables ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolCustom.cpp b/lib/DebugInfo/PDB/PDBSymbolCustom.cpp index 10a21806adb6..6c9a4aa76c3d 100644 --- a/lib/DebugInfo/PDB/PDBSymbolCustom.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolCustom.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolCustom.cpp - compiler-specific types ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolData.cpp b/lib/DebugInfo/PDB/PDBSymbolData.cpp index 7de94670bcb3..d2b82111ccd5 100644 --- a/lib/DebugInfo/PDB/PDBSymbolData.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolData.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolData.cpp - PDB data (e.g. variable) accessors ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolExe.cpp b/lib/DebugInfo/PDB/PDBSymbolExe.cpp index eb409412af59..c85756c43e47 100644 --- a/lib/DebugInfo/PDB/PDBSymbolExe.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolExe.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolExe.cpp - ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp index 75063cb3e7f8..7c3ba981fd6b 100644 --- a/lib/DebugInfo/PDB/PDBSymbolFunc.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolFunc.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp b/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp index af8aafa7be96..66433dc17b49 100644 --- a/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolFuncDebugEnd.cpp - ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp b/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp index 77b510873bea..fe32c93c0121 100644 --- a/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolFuncDebugStart.cpp - ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolLabel.cpp b/lib/DebugInfo/PDB/PDBSymbolLabel.cpp index c802b97925e6..1fffe69a0c83 100644 --- a/lib/DebugInfo/PDB/PDBSymbolLabel.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolLabel.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolLabel.cpp - -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp b/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp index a2dd2ab92dd9..08697683f641 100644 --- a/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolPublicSymbol.cpp - ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolThunk.cpp b/lib/DebugInfo/PDB/PDBSymbolThunk.cpp index d227e3a7a60c..6483858183e5 100644 --- a/lib/DebugInfo/PDB/PDBSymbolThunk.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolThunk.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolThunk.cpp - -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp index a2064d1ac1eb..a0d521abe43f 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeArray.cpp - ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp index f0376c05557f..08467059b5e1 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeBaseClass.cpp - -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp index a9f59e5f9d4d..a0dd9ef601c0 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeBuiltin.cpp - ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp index cfb347fbac55..6723894c90ea 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeCustom.cpp - --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp index 4eb48997635a..4a25a391f278 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp @@ -1,10 +1,9 @@ //===- PDBSymbolTypeDimension.cpp - --------------------------------*- C++ //-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp index 2e88d9eb284a..b9fdf6aec811 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeEnum.cpp - --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp index 00d2d51aa8a7..4ffea42cbb0a 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeFriend.cpp - --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp index 0399e110d592..683e93548fb1 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeFunctionArg.cpp - --------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp index c0564d3941dd..292320a6fe6d 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeFunctionSig.cpp - --------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp index 1faaf9c67a2c..e80e6c716572 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp @@ -1,9 +1,8 @@ //===- PDBSymboTypelManaged.cpp - ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp b/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp index cf5a369116a9..462fc315359b 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypePointer.cpp -----------------------------------*- C++ -===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp index 1838f1612b49..70749d9bf5f5 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeTypedef.cpp ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp index 2f5222f34fe4..d302c29a3bec 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeUDT.cpp - --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp index 0262f91e8336..4e2a45116d51 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeVTable.cpp - --------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp b/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp index 16c3a3606981..78957620e083 100644 --- a/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolTypeVTableShape.cpp - ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp b/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp index 7bcf9457a2b6..650d01183171 100644 --- a/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolUnknown.cpp - -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp b/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp index ecf2126f8802..74afbdb18086 100644 --- a/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp +++ b/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp @@ -1,9 +1,8 @@ //===- PDBSymbolUsingNamespace.cpp - ------------------- --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/PDB/UDTLayout.cpp b/lib/DebugInfo/PDB/UDTLayout.cpp index 5f4390bbaf12..acb1599480b0 100644 --- a/lib/DebugInfo/PDB/UDTLayout.cpp +++ b/lib/DebugInfo/PDB/UDTLayout.cpp @@ -1,9 +1,8 @@ //===- UDTLayout.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 // //===----------------------------------------------------------------------===// diff --git a/lib/DebugInfo/Symbolize/DIPrinter.cpp b/lib/DebugInfo/Symbolize/DIPrinter.cpp index c1e2536d6e20..b2bfef251485 100644 --- a/lib/DebugInfo/Symbolize/DIPrinter.cpp +++ b/lib/DebugInfo/Symbolize/DIPrinter.cpp @@ -1,9 +1,8 @@ //===- lib/DebugInfo/Symbolize/DIPrinter.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 // //===----------------------------------------------------------------------===// // @@ -19,6 +18,7 @@ #include "llvm/Support/Format.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cmath> @@ -78,8 +78,13 @@ void DIPrinter::print(const DILineInfo &Info, bool Inlined) { std::string Filename = Info.FileName; if (Filename == kDILineInfoBadString) Filename = kBadString; + else if (Basenames) + Filename = llvm::sys::path::filename(Filename); if (!Verbose) { - OS << Filename << ":" << Info.Line << ":" << Info.Column << "\n"; + OS << Filename << ":" << Info.Line; + if (Style == OutputStyle::LLVM) + OS << ":" << Info.Column; + OS << "\n"; printContext(Filename, Info.Line); return; } @@ -117,5 +122,28 @@ DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) { return *this; } +DIPrinter &DIPrinter::operator<<(const DILocal &Local) { + OS << Local.FunctionName << '\n'; + OS << Local.Name << '\n'; + if (Local.DeclFile.empty()) + OS << "??"; + else + OS << Local.DeclFile; + OS << ':' << Local.DeclLine << '\n'; + if (Local.FrameOffset) + OS << *Local.FrameOffset << ' '; + else + OS << "?? "; + if (Local.Size) + OS << *Local.Size << ' '; + else + OS << "?? "; + if (Local.TagOffset) + OS << *Local.TagOffset << '\n'; + else + OS << "??\n"; + return *this; +} + } // end namespace symbolize } // end namespace llvm diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp index 08be524ab464..2765bf44d504 100644 --- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp +++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp @@ -1,9 +1,8 @@ //===- SymbolizableObjectFile.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 // //===----------------------------------------------------------------------===// // @@ -43,8 +42,9 @@ getDILineInfoSpecifier(FunctionNameKind FNKind) { } ErrorOr<std::unique_ptr<SymbolizableObjectFile>> -SymbolizableObjectFile::create(object::ObjectFile *Obj, +SymbolizableObjectFile::create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx) { + assert(DICtx); std::unique_ptr<SymbolizableObjectFile> res( new SymbolizableObjectFile(Obj, std::move(DICtx))); std::unique_ptr<DataExtractor> OpdExtractor; @@ -54,13 +54,13 @@ SymbolizableObjectFile::create(object::ObjectFile *Obj, if (Obj->getArch() == Triple::ppc64) { for (section_iterator Section : Obj->sections()) { StringRef Name; - StringRef Data; if (auto EC = Section->getName(Name)) return EC; if (Name == ".opd") { - if (auto EC = Section->getContents(Data)) - return EC; - OpdExtractor.reset(new DataExtractor(Data, Obj->isLittleEndian(), + Expected<StringRef> E = Section->getContents(); + if (!E) + return errorToErrorCode(E.takeError()); + OpdExtractor.reset(new DataExtractor(*E, Obj->isLittleEndian(), Obj->getBytesInAddress())); OpdAddress = Section->getAddress(); break; @@ -79,10 +79,30 @@ SymbolizableObjectFile::create(object::ObjectFile *Obj, if (auto EC = res->addCoffExportSymbols(CoffObj)) return EC; } + + std::vector<std::pair<SymbolDesc, StringRef>> &Fs = res->Functions, + &Os = res->Objects; + auto Uniquify = [](std::vector<std::pair<SymbolDesc, StringRef>> &S) { + // Sort by (Addr,Size,Name). If several SymbolDescs share the same Addr, + // pick the one with the largest Size. This helps us avoid symbols with no + // size information (Size=0). + llvm::sort(S); + auto I = S.begin(), E = S.end(), J = S.begin(); + while (I != E) { + auto OI = I; + while (++I != E && OI->first.Addr == I->first.Addr) { + } + *J++ = I[-1]; + } + S.erase(J, S.end()); + }; + Uniquify(Fs); + Uniquify(Os); + return std::move(res); } -SymbolizableObjectFile::SymbolizableObjectFile(ObjectFile *Obj, +SymbolizableObjectFile::SymbolizableObjectFile(const ObjectFile *Obj, std::unique_ptr<DIContext> DICtx) : Module(Obj), DebugInfoContext(std::move(DICtx)) {} @@ -128,7 +148,7 @@ std::error_code SymbolizableObjectFile::addCoffExportSymbols( uint64_t SymbolStart = ImageBase + Export.Offset; uint64_t SymbolSize = NextOffset - Export.Offset; SymbolDesc SD = {SymbolStart, SymbolSize}; - Functions.insert(std::make_pair(SD, Export.Name)); + Functions.emplace_back(SD, Export.Name); } return std::error_code(); } @@ -137,6 +157,11 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol, uint64_t SymbolSize, DataExtractor *OpdExtractor, uint64_t OpdAddress) { + // Avoid adding symbols from an unknown/undefined section. + const ObjectFile *Obj = Symbol.getObject(); + Expected<section_iterator> Sec = Symbol.getSection(); + if (!Sec || (Obj && Obj->section_end() == *Sec)) + return std::error_code(); Expected<SymbolRef::Type> SymbolTypeOrErr = Symbol.getType(); if (!SymbolTypeOrErr) return errorToErrorCode(SymbolTypeOrErr.takeError()); @@ -170,7 +195,7 @@ std::error_code SymbolizableObjectFile::addSymbol(const SymbolRef &Symbol, // with same address size. Make sure we choose the correct one. auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects; SymbolDesc SD = { SymbolAddress, SymbolSize }; - M.insert(std::make_pair(SD, SymbolName)); + M.emplace_back(SD, SymbolName); return std::error_code(); } @@ -191,12 +216,10 @@ bool SymbolizableObjectFile::getNameFromSymbolTable(SymbolRef::Type Type, std::string &Name, uint64_t &Addr, uint64_t &Size) const { - const auto &SymbolMap = Type == SymbolRef::ST_Function ? Functions : Objects; - if (SymbolMap.empty()) - return false; - SymbolDesc SD = { Address, Address }; - auto SymbolIterator = SymbolMap.upper_bound(SD); - if (SymbolIterator == SymbolMap.begin()) + const auto &Symbols = Type == SymbolRef::ST_Function ? Functions : Objects; + std::pair<SymbolDesc, StringRef> SD{{Address, UINT64_C(-1)}, StringRef()}; + auto SymbolIterator = llvm::upper_bound(Symbols, SD); + if (SymbolIterator == Symbols.begin()) return false; --SymbolIterator; if (SymbolIterator->first.Size != 0 && @@ -218,19 +241,21 @@ bool SymbolizableObjectFile::shouldOverrideWithSymbolTable( isa<DWARFContext>(DebugInfoContext.get()); } -DILineInfo SymbolizableObjectFile::symbolizeCode(uint64_t ModuleOffset, - FunctionNameKind FNKind, - bool UseSymbolTable) const { - DILineInfo LineInfo; - if (DebugInfoContext) { - LineInfo = DebugInfoContext->getLineInfoForAddress( - ModuleOffset, getDILineInfoSpecifier(FNKind)); - } +DILineInfo +SymbolizableObjectFile::symbolizeCode(object::SectionedAddress ModuleOffset, + FunctionNameKind FNKind, + bool UseSymbolTable) const { + if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection) + ModuleOffset.SectionIndex = + getModuleSectionIndexForAddress(ModuleOffset.Address); + DILineInfo LineInfo = DebugInfoContext->getLineInfoForAddress( + ModuleOffset, getDILineInfoSpecifier(FNKind)); + // Override function name from symbol table if necessary. if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) { std::string FunctionName; uint64_t Start, Size; - if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, + if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address, FunctionName, Start, Size)) { LineInfo.FunctionName = FunctionName; } @@ -239,12 +264,14 @@ DILineInfo SymbolizableObjectFile::symbolizeCode(uint64_t ModuleOffset, } DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode( - uint64_t ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const { - DIInliningInfo InlinedContext; + object::SectionedAddress ModuleOffset, FunctionNameKind FNKind, + bool UseSymbolTable) const { + if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection) + ModuleOffset.SectionIndex = + getModuleSectionIndexForAddress(ModuleOffset.Address); + DIInliningInfo InlinedContext = DebugInfoContext->getInliningInfoForAddress( + ModuleOffset, getDILineInfoSpecifier(FNKind)); - if (DebugInfoContext) - InlinedContext = DebugInfoContext->getInliningInfoForAddress( - ModuleOffset, getDILineInfoSpecifier(FNKind)); // Make sure there is at least one frame in context. if (InlinedContext.getNumberOfFrames() == 0) InlinedContext.addFrame(DILineInfo()); @@ -253,7 +280,7 @@ DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode( if (shouldOverrideWithSymbolTable(FNKind, UseSymbolTable)) { std::string FunctionName; uint64_t Start, Size; - if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, + if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address, FunctionName, Start, Size)) { InlinedContext.getMutableFrame(InlinedContext.getNumberOfFrames() - 1) ->FunctionName = FunctionName; @@ -263,9 +290,34 @@ DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode( return InlinedContext; } -DIGlobal SymbolizableObjectFile::symbolizeData(uint64_t ModuleOffset) const { +DIGlobal SymbolizableObjectFile::symbolizeData( + object::SectionedAddress ModuleOffset) const { DIGlobal Res; - getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset, Res.Name, Res.Start, - Res.Size); + getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset.Address, Res.Name, + Res.Start, Res.Size); return Res; } + +std::vector<DILocal> SymbolizableObjectFile::symbolizeFrame( + object::SectionedAddress ModuleOffset) const { + if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection) + ModuleOffset.SectionIndex = + getModuleSectionIndexForAddress(ModuleOffset.Address); + return DebugInfoContext->getLocalsForAddress(ModuleOffset); +} + +/// Search for the first occurence of specified Address in ObjectFile. +uint64_t SymbolizableObjectFile::getModuleSectionIndexForAddress( + uint64_t Address) const { + + for (SectionRef Sec : Module->sections()) { + if (!Sec.isText() || Sec.isVirtual()) + continue; + + if (Address >= Sec.getAddress() && + Address < Sec.getAddress() + Sec.getSize()) + return Sec.getIndex(); + } + + return object::SectionedAddress::UndefSection; +} diff --git a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h index 216cca8de4f5..9cab94178c1b 100644 --- a/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h +++ b/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h @@ -1,9 +1,8 @@ //===- SymbolizableObjectFile.h ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -32,14 +31,17 @@ namespace symbolize { class SymbolizableObjectFile : public SymbolizableModule { public: static ErrorOr<std::unique_ptr<SymbolizableObjectFile>> - create(object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx); + create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx); - DILineInfo symbolizeCode(uint64_t ModuleOffset, FunctionNameKind FNKind, + DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset, + FunctionNameKind FNKind, bool UseSymbolTable) const override; - DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset, + DIInliningInfo symbolizeInlinedCode(object::SectionedAddress ModuleOffset, FunctionNameKind FNKind, bool UseSymbolTable) const override; - DIGlobal symbolizeData(uint64_t ModuleOffset) const override; + DIGlobal symbolizeData(object::SectionedAddress ModuleOffset) const override; + std::vector<DILocal> + symbolizeFrame(object::SectionedAddress ModuleOffset) const override; // Return true if this is a 32-bit x86 PE COFF module. bool isWin32Module() const override; @@ -63,7 +65,10 @@ private: uint64_t OpdAddress = 0); std::error_code addCoffExportSymbols(const object::COFFObjectFile *CoffObj); - object::ObjectFile *Module; + /// Search for the first occurence of specified Address in ObjectFile. + uint64_t getModuleSectionIndexForAddress(uint64_t Address) const; + + const object::ObjectFile *Module; std::unique_ptr<DIContext> DebugInfoContext; struct SymbolDesc { @@ -72,14 +77,14 @@ private: // the following symbol. uint64_t Size; - friend bool operator<(const SymbolDesc &s1, const SymbolDesc &s2) { - return s1.Addr < s2.Addr; + bool operator<(const SymbolDesc &RHS) const { + return Addr != RHS.Addr ? Addr < RHS.Addr : Size < RHS.Size; } }; - std::map<SymbolDesc, StringRef> Functions; - std::map<SymbolDesc, StringRef> Objects; + std::vector<std::pair<SymbolDesc, StringRef>> Functions; + std::vector<std::pair<SymbolDesc, StringRef>> Objects; - SymbolizableObjectFile(object::ObjectFile *Obj, + SymbolizableObjectFile(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx); }; diff --git a/lib/DebugInfo/Symbolize/Symbolize.cpp b/lib/DebugInfo/Symbolize/Symbolize.cpp index 59a85d6c3fcf..6a619f8f2f37 100644 --- a/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -1,9 +1,8 @@ //===-- LLVMSymbolize.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 // //===----------------------------------------------------------------------===// // @@ -17,7 +16,6 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/BinaryFormat/COFF.h" -#include "llvm/Config/config.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/PDB/PDB.h" #include "llvm/DebugInfo/PDB/PDBContext.h" @@ -25,6 +23,7 @@ #include "llvm/Object/COFF.h" #include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" +#include "llvm/Support/CRC.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" #include "llvm/Support/DataExtractor.h" @@ -34,7 +33,6 @@ #include "llvm/Support/Path.h" #include <algorithm> #include <cassert> -#include <cstdlib> #include <cstring> #if defined(_MSC_VER) @@ -54,14 +52,8 @@ namespace llvm { namespace symbolize { Expected<DILineInfo> -LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, - uint64_t ModuleOffset, StringRef DWPName) { - SymbolizableModule *Info; - if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName)) - Info = InfoOrErr.get(); - else - return InfoOrErr.takeError(); - +LLVMSymbolizer::symbolizeCodeCommon(SymbolizableModule *Info, + object::SectionedAddress ModuleOffset) { // A null module means an error has already been reported. Return an empty // result. if (!Info) @@ -70,7 +62,7 @@ LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, // If the user is giving us relative addresses, add the preferred base of the // object to the offset before we do the query. It's what DIContext expects. if (Opts.RelativeAddresses) - ModuleOffset += Info->getModulePreferredBase(); + ModuleOffset.Address += Info->getModulePreferredBase(); DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable); @@ -79,11 +71,37 @@ LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, return LineInfo; } +Expected<DILineInfo> +LLVMSymbolizer::symbolizeCode(const ObjectFile &Obj, + object::SectionedAddress ModuleOffset) { + StringRef ModuleName = Obj.getFileName(); + auto I = Modules.find(ModuleName); + if (I != Modules.end()) + return symbolizeCodeCommon(I->second.get(), ModuleOffset); + + std::unique_ptr<DIContext> Context = + DWARFContext::create(Obj, nullptr, DWARFContext::defaultErrorHandler); + Expected<SymbolizableModule *> InfoOrErr = + createModuleInfo(&Obj, std::move(Context), ModuleName); + if (!InfoOrErr) + return InfoOrErr.takeError(); + return symbolizeCodeCommon(*InfoOrErr, ModuleOffset); +} + +Expected<DILineInfo> +LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, + object::SectionedAddress ModuleOffset) { + Expected<SymbolizableModule *> InfoOrErr = getOrCreateModuleInfo(ModuleName); + if (!InfoOrErr) + return InfoOrErr.takeError(); + return symbolizeCodeCommon(*InfoOrErr, ModuleOffset); +} + Expected<DIInliningInfo> LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, - uint64_t ModuleOffset, StringRef DWPName) { + object::SectionedAddress ModuleOffset) { SymbolizableModule *Info; - if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName, DWPName)) + if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) Info = InfoOrErr.get(); else return InfoOrErr.takeError(); @@ -96,7 +114,7 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, // If the user is giving us relative addresses, add the preferred base of the // object to the offset before we do the query. It's what DIContext expects. if (Opts.RelativeAddresses) - ModuleOffset += Info->getModulePreferredBase(); + ModuleOffset.Address += Info->getModulePreferredBase(); DIInliningInfo InlinedContext = Info->symbolizeInlinedCode( ModuleOffset, Opts.PrintFunctions, Opts.UseSymbolTable); @@ -109,8 +127,9 @@ LLVMSymbolizer::symbolizeInlinedCode(const std::string &ModuleName, return InlinedContext; } -Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName, - uint64_t ModuleOffset) { +Expected<DIGlobal> +LLVMSymbolizer::symbolizeData(const std::string &ModuleName, + object::SectionedAddress ModuleOffset) { SymbolizableModule *Info; if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) Info = InfoOrErr.get(); @@ -126,7 +145,7 @@ Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName, // the object to the offset before we do the query. It's what DIContext // expects. if (Opts.RelativeAddresses) - ModuleOffset += Info->getModulePreferredBase(); + ModuleOffset.Address += Info->getModulePreferredBase(); DIGlobal Global = Info->symbolizeData(ModuleOffset); if (Opts.Demangle) @@ -134,6 +153,29 @@ Expected<DIGlobal> LLVMSymbolizer::symbolizeData(const std::string &ModuleName, return Global; } +Expected<std::vector<DILocal>> +LLVMSymbolizer::symbolizeFrame(const std::string &ModuleName, + object::SectionedAddress ModuleOffset) { + SymbolizableModule *Info; + if (auto InfoOrErr = getOrCreateModuleInfo(ModuleName)) + Info = InfoOrErr.get(); + else + return InfoOrErr.takeError(); + + // A null module means an error has already been reported. Return an empty + // result. + if (!Info) + return std::vector<DILocal>(); + + // If the user is giving us relative addresses, add the preferred base of + // the object to the offset before we do the query. It's what DIContext + // expects. + if (Opts.RelativeAddresses) + ModuleOffset.Address += Info->getModulePreferredBase(); + + return Info->symbolizeFrame(ModuleOffset); +} + void LLVMSymbolizer::flush() { ObjectForUBPathAndArch.clear(); BinaryForPath.clear(); @@ -163,42 +205,45 @@ bool checkFileCRC(StringRef Path, uint32_t CRCHash) { MemoryBuffer::getFileOrSTDIN(Path); if (!MB) return false; - return !zlib::isAvailable() || CRCHash == zlib::crc32(MB.get()->getBuffer()); + return CRCHash == llvm::crc32(0, MB.get()->getBuffer()); } bool findDebugBinary(const std::string &OrigPath, const std::string &DebuglinkName, uint32_t CRCHash, + const std::string &FallbackDebugPath, std::string &Result) { - std::string OrigRealPath = OrigPath; -#if defined(HAVE_REALPATH) - if (char *RP = realpath(OrigPath.c_str(), nullptr)) { - OrigRealPath = RP; - free(RP); - } -#endif - SmallString<16> OrigDir(OrigRealPath); + SmallString<16> OrigDir(OrigPath); llvm::sys::path::remove_filename(OrigDir); SmallString<16> DebugPath = OrigDir; - // Try /path/to/original_binary/debuglink_name + // Try relative/path/to/original_binary/debuglink_name llvm::sys::path::append(DebugPath, DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { Result = DebugPath.str(); return true; } - // Try /path/to/original_binary/.debug/debuglink_name + // Try relative/path/to/original_binary/.debug/debuglink_name DebugPath = OrigDir; llvm::sys::path::append(DebugPath, ".debug", DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { Result = DebugPath.str(); return true; } + // Make the path absolute so that lookups will go to + // "/usr/lib/debug/full/path/to/debug", not + // "/usr/lib/debug/to/debug" + llvm::sys::fs::make_absolute(OrigDir); + if (!FallbackDebugPath.empty()) { + // Try <FallbackDebugPath>/absolute/path/to/original_binary/debuglink_name + DebugPath = FallbackDebugPath; + } else { #if defined(__NetBSD__) - // Try /usr/libdata/debug/path/to/original_binary/debuglink_name - DebugPath = "/usr/libdata/debug"; + // Try /usr/libdata/debug/absolute/path/to/original_binary/debuglink_name + DebugPath = "/usr/libdata/debug"; #else - // Try /usr/lib/debug/path/to/original_binary/debuglink_name - DebugPath = "/usr/lib/debug"; + // Try /usr/lib/debug/absolute/path/to/original_binary/debuglink_name + DebugPath = "/usr/lib/debug"; #endif + } llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir), DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { @@ -217,9 +262,12 @@ bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName, Section.getName(Name); Name = Name.substr(Name.find_first_not_of("._")); if (Name == "gnu_debuglink") { - StringRef Data; - Section.getContents(Data); - DataExtractor DE(Data, Obj->isLittleEndian(), 0); + Expected<StringRef> ContentsOrErr = Section.getContents(); + if (!ContentsOrErr) { + consumeError(ContentsOrErr.takeError()); + return false; + } + DataExtractor DE(*ContentsOrErr, Obj->isLittleEndian(), 0); uint32_t Offset = 0; if (const char *DebugNameStr = DE.getCStr(&Offset)) { // 4-byte align the offset. @@ -284,7 +332,8 @@ ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path, std::string DebugBinaryPath; if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash)) return nullptr; - if (!findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath)) + if (!findDebugBinary(Path, DebuglinkName, CRCHash, Opts.FallbackDebugPath, + DebugBinaryPath)) return nullptr; auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName); if (!DbgObjOrErr) { @@ -298,15 +347,14 @@ ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path, Expected<LLVMSymbolizer::ObjectPair> LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, const std::string &ArchName) { - const auto &I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName)); - if (I != ObjectPairForPathArch.end()) { + auto I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName)); + if (I != ObjectPairForPathArch.end()) return I->second; - } auto ObjOrErr = getOrCreateObject(Path, ArchName); if (!ObjOrErr) { - ObjectPairForPathArch.insert(std::make_pair(std::make_pair(Path, ArchName), - ObjectPair(nullptr, nullptr))); + ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), + ObjectPair(nullptr, nullptr)); return ObjOrErr.takeError(); } @@ -321,46 +369,43 @@ LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path, if (!DbgObj) DbgObj = Obj; ObjectPair Res = std::make_pair(Obj, DbgObj); - ObjectPairForPathArch.insert( - std::make_pair(std::make_pair(Path, ArchName), Res)); + ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res); return Res; } Expected<ObjectFile *> LLVMSymbolizer::getOrCreateObject(const std::string &Path, const std::string &ArchName) { - const auto &I = BinaryForPath.find(Path); - Binary *Bin = nullptr; - if (I == BinaryForPath.end()) { + Binary *Bin; + auto Pair = BinaryForPath.emplace(Path, OwningBinary<Binary>()); + if (!Pair.second) { + Bin = Pair.first->second.getBinary(); + } else { Expected<OwningBinary<Binary>> BinOrErr = createBinary(Path); - if (!BinOrErr) { - BinaryForPath.insert(std::make_pair(Path, OwningBinary<Binary>())); + if (!BinOrErr) return BinOrErr.takeError(); - } - Bin = BinOrErr->getBinary(); - BinaryForPath.insert(std::make_pair(Path, std::move(BinOrErr.get()))); - } else { - Bin = I->second.getBinary(); + Pair.first->second = std::move(BinOrErr.get()); + Bin = Pair.first->second.getBinary(); } if (!Bin) return static_cast<ObjectFile *>(nullptr); if (MachOUniversalBinary *UB = dyn_cast_or_null<MachOUniversalBinary>(Bin)) { - const auto &I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName)); - if (I != ObjectForUBPathAndArch.end()) { + auto I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName)); + if (I != ObjectForUBPathAndArch.end()) return I->second.get(); - } + Expected<std::unique_ptr<ObjectFile>> ObjOrErr = UB->getObjectForArch(ArchName); if (!ObjOrErr) { - ObjectForUBPathAndArch.insert(std::make_pair( - std::make_pair(Path, ArchName), std::unique_ptr<ObjectFile>())); + ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName), + std::unique_ptr<ObjectFile>()); return ObjOrErr.takeError(); } ObjectFile *Res = ObjOrErr->get(); - ObjectForUBPathAndArch.insert(std::make_pair(std::make_pair(Path, ArchName), - std::move(ObjOrErr.get()))); + ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName), + std::move(ObjOrErr.get())); return Res; } if (Bin->isObject()) { @@ -370,12 +415,28 @@ LLVMSymbolizer::getOrCreateObject(const std::string &Path, } Expected<SymbolizableModule *> -LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName, - StringRef DWPName) { - const auto &I = Modules.find(ModuleName); - if (I != Modules.end()) { +LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj, + std::unique_ptr<DIContext> Context, + StringRef ModuleName) { + auto InfoOrErr = + SymbolizableObjectFile::create(Obj, std::move(Context)); + std::unique_ptr<SymbolizableModule> SymMod; + if (InfoOrErr) + SymMod = std::move(*InfoOrErr); + auto InsertResult = + Modules.insert(std::make_pair(ModuleName, std::move(SymMod))); + assert(InsertResult.second); + if (std::error_code EC = InfoOrErr.getError()) + return errorCodeToError(EC); + return InsertResult.first->second.get(); +} + +Expected<SymbolizableModule *> +LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { + auto I = Modules.find(ModuleName); + if (I != Modules.end()) return I->second.get(); - } + std::string BinaryName = ModuleName; std::string ArchName = Opts.DefaultArch; size_t ColonPos = ModuleName.find_last_of(':'); @@ -390,8 +451,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName, auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName); if (!ObjectsOrErr) { // Failed to find valid object file. - Modules.insert( - std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>())); + Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>()); return ObjectsOrErr.takeError(); } ObjectPair Objects = ObjectsOrErr.get(); @@ -408,8 +468,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName, std::unique_ptr<IPDBSession> Session; if (auto Err = loadDataForEXE(PDB_ReaderType::DIA, Objects.first->getFileName(), Session)) { - Modules.insert( - std::make_pair(ModuleName, std::unique_ptr<SymbolizableModule>())); + Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>()); // Return along the PDB filename to provide more context return createFileError(PDBFileName, std::move(Err)); } @@ -417,20 +476,10 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName, } } if (!Context) - Context = DWARFContext::create(*Objects.second, nullptr, - DWARFContext::defaultErrorHandler, DWPName); - assert(Context); - auto InfoOrErr = - SymbolizableObjectFile::create(Objects.first, std::move(Context)); - std::unique_ptr<SymbolizableModule> SymMod; - if (InfoOrErr) - SymMod = std::move(InfoOrErr.get()); - auto InsertResult = - Modules.insert(std::make_pair(ModuleName, std::move(SymMod))); - assert(InsertResult.second); - if (auto EC = InfoOrErr.getError()) - return errorCodeToError(EC); - return InsertResult.first->second.get(); + Context = + DWARFContext::create(*Objects.second, nullptr, + DWARFContext::defaultErrorHandler, Opts.DWPName); + return createModuleInfo(Objects.first, std::move(Context), ModuleName); } namespace { |