aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm12/lib/DebugInfo
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/llvm12/lib/DebugInfo
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/llvm12/lib/DebugInfo')
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp224
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp164
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/CVTypeVisitor.cpp548
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewError.cpp98
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp740
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp502
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp230
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp104
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp192
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp114
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp250
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp320
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp214
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsection.cpp30
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp188
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp188
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp70
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp66
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp1096
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/Formatters.cpp94
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp280
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp558
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/Line.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp304
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp668
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp306
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp134
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/StringsAndChecksums.cpp160
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolDumper.cpp1358
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp186
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp1116
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolSerializer.cpp118
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp1140
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeHashing.cpp160
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndex.cpp212
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp1044
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp104
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp1418
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp990
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeTableCollection.cpp130
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make114
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp430
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp1810
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp60
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp74
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp3884
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp254
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp276
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp348
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp338
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp252
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp1160
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp136
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp2902
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp798
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp470
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp236
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp190
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp378
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp1460
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp974
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp1440
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp394
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp208
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp38
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp98
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp1766
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp600
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp2994
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make90
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp754
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/MSF/MSFCommon.cpp164
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/MSF/MSFError.cpp94
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/MSF/MappedBlockStream.cpp842
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/GenericError.cpp96
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/IPDBSourceFile.cpp68
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp172
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp324
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleList.cpp558
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp766
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp894
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/EnumTables.cpp74
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp986
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GlobalsStream.cpp362
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/Hash.cpp168
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/HashTable.cpp142
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStream.cpp262
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp164
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp130
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp288
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp250
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp120
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp108
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp242
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp84
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp86
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp140
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp202
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp102
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp94
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp94
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp1468
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp770
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp92
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp248
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp132
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp92
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp762
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp398
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp386
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp58
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp438
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp70
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFile.cpp1016
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp712
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTable.cpp280
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp458
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PublicsStream.cpp202
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/RawError.cpp106
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp1112
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolStream.cpp90
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiHashing.cpp258
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStream.cpp492
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp336
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp100
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp244
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp784
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp74
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymDumper.cpp292
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp428
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp40
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolBlock.cpp38
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp218
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp58
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCustom.cpp48
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolData.cpp136
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolExe.cpp58
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFunc.cpp222
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolLabel.cpp36
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolThunk.cpp36
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp48
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp40
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp38
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp40
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp186
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp50
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp40
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp50
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp40
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp38
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp42
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp596
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make210
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp306
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp636
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h188
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp1264
-rw-r--r--contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make40
169 files changed, 32982 insertions, 32982 deletions
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp
index 4d8b15530b..6aaa8f581d 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/AppendingTypeTableBuilder.cpp
@@ -1,112 +1,112 @@
-//===- AppendingTypeTableBuilder.cpp --------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-TypeIndex AppendingTypeTableBuilder::nextTypeIndex() const {
- return TypeIndex::fromArrayIndex(SeenRecords.size());
-}
-
-AppendingTypeTableBuilder::AppendingTypeTableBuilder(BumpPtrAllocator &Storage)
- : RecordStorage(Storage) {}
-
-AppendingTypeTableBuilder::~AppendingTypeTableBuilder() = default;
-
-Optional<TypeIndex> AppendingTypeTableBuilder::getFirst() {
- if (empty())
- return None;
-
- return TypeIndex(TypeIndex::FirstNonSimpleIndex);
-}
-
-Optional<TypeIndex> AppendingTypeTableBuilder::getNext(TypeIndex Prev) {
- if (++Prev == nextTypeIndex())
- return None;
- return Prev;
-}
-
-CVType AppendingTypeTableBuilder::getType(TypeIndex Index){
- return CVType(SeenRecords[Index.toArrayIndex()]);
-}
-
-StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) {
- llvm_unreachable("Method not implemented");
-}
-
-bool AppendingTypeTableBuilder::contains(TypeIndex Index) {
- if (Index.isSimple() || Index.isNoneType())
- return false;
-
- return Index.toArrayIndex() < SeenRecords.size();
-}
-
-uint32_t AppendingTypeTableBuilder::size() { return SeenRecords.size(); }
-
-uint32_t AppendingTypeTableBuilder::capacity() { return SeenRecords.size(); }
-
-ArrayRef<ArrayRef<uint8_t>> AppendingTypeTableBuilder::records() const {
- return SeenRecords;
-}
-
-void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); }
-
-static ArrayRef<uint8_t> stabilize(BumpPtrAllocator &RecordStorage,
- ArrayRef<uint8_t> Record) {
- uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size());
- memcpy(Stable, Record.data(), Record.size());
- return ArrayRef<uint8_t>(Stable, Record.size());
-}
-
-TypeIndex
-AppendingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) {
- TypeIndex NewTI = nextTypeIndex();
- Record = stabilize(RecordStorage, Record);
- SeenRecords.push_back(Record);
- return NewTI;
-}
-
-TypeIndex
-AppendingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
- TypeIndex TI;
- auto Fragments = Builder.end(nextTypeIndex());
- assert(!Fragments.empty());
- for (auto C : Fragments)
- TI = insertRecordBytes(C.RecordData);
- return TI;
-}
-
-bool AppendingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
- bool Stabilize) {
- assert(Index.toArrayIndex() < SeenRecords.size() &&
- "This function cannot be used to insert records!");
-
- ArrayRef<uint8_t> Record = Data.data();
- if (Stabilize)
- Record = stabilize(RecordStorage, Record);
- SeenRecords[Index.toArrayIndex()] = Record;
- return true;
-}
+//===- AppendingTypeTableBuilder.cpp --------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/AppendingTypeTableBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+TypeIndex AppendingTypeTableBuilder::nextTypeIndex() const {
+ return TypeIndex::fromArrayIndex(SeenRecords.size());
+}
+
+AppendingTypeTableBuilder::AppendingTypeTableBuilder(BumpPtrAllocator &Storage)
+ : RecordStorage(Storage) {}
+
+AppendingTypeTableBuilder::~AppendingTypeTableBuilder() = default;
+
+Optional<TypeIndex> AppendingTypeTableBuilder::getFirst() {
+ if (empty())
+ return None;
+
+ return TypeIndex(TypeIndex::FirstNonSimpleIndex);
+}
+
+Optional<TypeIndex> AppendingTypeTableBuilder::getNext(TypeIndex Prev) {
+ if (++Prev == nextTypeIndex())
+ return None;
+ return Prev;
+}
+
+CVType AppendingTypeTableBuilder::getType(TypeIndex Index){
+ return CVType(SeenRecords[Index.toArrayIndex()]);
+}
+
+StringRef AppendingTypeTableBuilder::getTypeName(TypeIndex Index) {
+ llvm_unreachable("Method not implemented");
+}
+
+bool AppendingTypeTableBuilder::contains(TypeIndex Index) {
+ if (Index.isSimple() || Index.isNoneType())
+ return false;
+
+ return Index.toArrayIndex() < SeenRecords.size();
+}
+
+uint32_t AppendingTypeTableBuilder::size() { return SeenRecords.size(); }
+
+uint32_t AppendingTypeTableBuilder::capacity() { return SeenRecords.size(); }
+
+ArrayRef<ArrayRef<uint8_t>> AppendingTypeTableBuilder::records() const {
+ return SeenRecords;
+}
+
+void AppendingTypeTableBuilder::reset() { SeenRecords.clear(); }
+
+static ArrayRef<uint8_t> stabilize(BumpPtrAllocator &RecordStorage,
+ ArrayRef<uint8_t> Record) {
+ uint8_t *Stable = RecordStorage.Allocate<uint8_t>(Record.size());
+ memcpy(Stable, Record.data(), Record.size());
+ return ArrayRef<uint8_t>(Stable, Record.size());
+}
+
+TypeIndex
+AppendingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) {
+ TypeIndex NewTI = nextTypeIndex();
+ Record = stabilize(RecordStorage, Record);
+ SeenRecords.push_back(Record);
+ return NewTI;
+}
+
+TypeIndex
+AppendingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
+ TypeIndex TI;
+ auto Fragments = Builder.end(nextTypeIndex());
+ assert(!Fragments.empty());
+ for (auto C : Fragments)
+ TI = insertRecordBytes(C.RecordData);
+ return TI;
+}
+
+bool AppendingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
+ bool Stabilize) {
+ assert(Index.toArrayIndex() < SeenRecords.size() &&
+ "This function cannot be used to insert records!");
+
+ ArrayRef<uint8_t> Record = Data.data();
+ if (Stabilize)
+ Record = stabilize(RecordStorage, Record);
+ SeenRecords[Index.toArrayIndex()] = Record;
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
index 48b9b0496f..153eda0790 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVSymbolVisitor.cpp
@@ -1,82 +1,82 @@
-//===- CVSymbolVisitor.cpp --------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
-
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
- : Callbacks(Callbacks) {}
-
-template <typename T>
-static Error visitKnownRecord(CVSymbol &Record,
- SymbolVisitorCallbacks &Callbacks) {
- SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.kind());
- T KnownRecord(RK);
- if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
- return EC;
- return Error::success();
-}
-
-static Error finishVisitation(CVSymbol &Record,
- SymbolVisitorCallbacks &Callbacks) {
- switch (Record.kind()) {
- default:
- if (auto EC = Callbacks.visitUnknownSymbol(Record))
- return EC;
- break;
-#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- case EnumName: { \
- if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \
- return EC; \
- break; \
- }
-#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
- SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
-#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
- }
-
- if (auto EC = Callbacks.visitSymbolEnd(Record))
- return EC;
-
- return Error::success();
-}
-
-Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
- if (auto EC = Callbacks.visitSymbolBegin(Record))
- return EC;
- return finishVisitation(Record, Callbacks);
-}
-
-Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record, uint32_t Offset) {
- if (auto EC = Callbacks.visitSymbolBegin(Record, Offset))
- return EC;
- return finishVisitation(Record, Callbacks);
-}
-
-Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) {
- for (auto I : Symbols) {
- if (auto EC = visitSymbolRecord(I))
- return EC;
- }
- return Error::success();
-}
-
-Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
- uint32_t InitialOffset) {
- for (auto I : Symbols) {
- if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew()))
- return EC;
- InitialOffset += I.length();
- }
- return Error::success();
-}
+//===- CVSymbolVisitor.cpp --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+CVSymbolVisitor::CVSymbolVisitor(SymbolVisitorCallbacks &Callbacks)
+ : Callbacks(Callbacks) {}
+
+template <typename T>
+static Error visitKnownRecord(CVSymbol &Record,
+ SymbolVisitorCallbacks &Callbacks) {
+ SymbolRecordKind RK = static_cast<SymbolRecordKind>(Record.kind());
+ T KnownRecord(RK);
+ if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
+ return EC;
+ return Error::success();
+}
+
+static Error finishVisitation(CVSymbol &Record,
+ SymbolVisitorCallbacks &Callbacks) {
+ switch (Record.kind()) {
+ default:
+ if (auto EC = Callbacks.visitUnknownSymbol(Record))
+ return EC;
+ break;
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ case EnumName: { \
+ if (auto EC = visitKnownRecord<Name>(Record, Callbacks)) \
+ return EC; \
+ break; \
+ }
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
+ SYMBOL_RECORD(EnumVal, EnumVal, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
+ }
+
+ if (auto EC = Callbacks.visitSymbolEnd(Record))
+ return EC;
+
+ return Error::success();
+}
+
+Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record) {
+ if (auto EC = Callbacks.visitSymbolBegin(Record))
+ return EC;
+ return finishVisitation(Record, Callbacks);
+}
+
+Error CVSymbolVisitor::visitSymbolRecord(CVSymbol &Record, uint32_t Offset) {
+ if (auto EC = Callbacks.visitSymbolBegin(Record, Offset))
+ return EC;
+ return finishVisitation(Record, Callbacks);
+}
+
+Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols) {
+ for (auto I : Symbols) {
+ if (auto EC = visitSymbolRecord(I))
+ return EC;
+ }
+ return Error::success();
+}
+
+Error CVSymbolVisitor::visitSymbolStream(const CVSymbolArray &Symbols,
+ uint32_t InitialOffset) {
+ for (auto I : Symbols) {
+ if (auto EC = visitSymbolRecord(I, InitialOffset + Symbols.skew()))
+ return EC;
+ InitialOffset += I.length();
+ }
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVTypeVisitor.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
index dd6f75f97a..4f36c4a719 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CVTypeVisitor.cpp
@@ -1,274 +1,274 @@
-//===- CVTypeVisitor.cpp ----------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamReader.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-
-template <typename T>
-static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
- TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind());
- T KnownRecord(RK);
- if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
- return EC;
- return Error::success();
-}
-
-template <typename T>
-static Error visitKnownMember(CVMemberRecord &Record,
- TypeVisitorCallbacks &Callbacks) {
- TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Kind);
- T KnownRecord(RK);
- if (auto EC = Callbacks.visitKnownMember(Record, KnownRecord))
- return EC;
- return Error::success();
-}
-
-static Error visitMemberRecord(CVMemberRecord &Record,
- TypeVisitorCallbacks &Callbacks) {
- if (auto EC = Callbacks.visitMemberBegin(Record))
- return EC;
-
- switch (Record.Kind) {
- default:
- if (auto EC = Callbacks.visitUnknownMember(Record))
- return EC;
- break;
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- case EnumName: { \
- if (auto EC = visitKnownMember<Name##Record>(Record, Callbacks)) \
- return EC; \
- break; \
- }
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
- MEMBER_RECORD(EnumVal, EnumVal, AliasName)
-#define TYPE_RECORD(EnumName, EnumVal, Name)
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
- }
-
- if (auto EC = Callbacks.visitMemberEnd(Record))
- return EC;
-
- return Error::success();
-}
-
-namespace {
-
-class CVTypeVisitor {
-public:
- explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
-
- Error visitTypeRecord(CVType &Record, TypeIndex Index);
- Error visitTypeRecord(CVType &Record);
-
- /// Visits the type records in Data. Sets the error flag on parse failures.
- Error visitTypeStream(const CVTypeArray &Types);
- Error visitTypeStream(CVTypeRange Types);
- Error visitTypeStream(TypeCollection &Types);
-
- Error visitMemberRecord(CVMemberRecord Record);
- Error visitFieldListMemberStream(BinaryStreamReader &Stream);
-
-private:
- Error finishVisitation(CVType &Record);
-
- /// The interface to the class that gets notified of each visitation.
- TypeVisitorCallbacks &Callbacks;
-};
-
-CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
- : Callbacks(Callbacks) {}
-
-Error CVTypeVisitor::finishVisitation(CVType &Record) {
- switch (Record.kind()) {
- default:
- if (auto EC = Callbacks.visitUnknownType(Record))
- return EC;
- break;
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- case EnumName: { \
- if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \
- return EC; \
- break; \
- }
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
- TYPE_RECORD(EnumVal, EnumVal, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
- }
-
- if (auto EC = Callbacks.visitTypeEnd(Record))
- return EC;
-
- return Error::success();
-}
-
-Error CVTypeVisitor::visitTypeRecord(CVType &Record, TypeIndex Index) {
- if (auto EC = Callbacks.visitTypeBegin(Record, Index))
- return EC;
-
- return finishVisitation(Record);
-}
-
-Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
- if (auto EC = Callbacks.visitTypeBegin(Record))
- return EC;
-
- return finishVisitation(Record);
-}
-
-Error CVTypeVisitor::visitMemberRecord(CVMemberRecord Record) {
- return ::visitMemberRecord(Record, Callbacks);
-}
-
-/// Visits the type records in Data. Sets the error flag on parse failures.
-Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
- for (auto I : Types) {
- if (auto EC = visitTypeRecord(I))
- return EC;
- }
- return Error::success();
-}
-
-Error CVTypeVisitor::visitTypeStream(CVTypeRange Types) {
- for (auto I : Types) {
- if (auto EC = visitTypeRecord(I))
- return EC;
- }
- return Error::success();
-}
-
-Error CVTypeVisitor::visitTypeStream(TypeCollection &Types) {
- Optional<TypeIndex> I = Types.getFirst();
- while (I) {
- CVType Type = Types.getType(*I);
- if (auto EC = visitTypeRecord(Type, *I))
- return EC;
- I = Types.getNext(*I);
- }
- return Error::success();
-}
-
-Error CVTypeVisitor::visitFieldListMemberStream(BinaryStreamReader &Reader) {
- TypeLeafKind Leaf;
- while (!Reader.empty()) {
- if (auto EC = Reader.readEnum(Leaf))
- return EC;
-
- CVMemberRecord Record;
- Record.Kind = Leaf;
- if (auto EC = ::visitMemberRecord(Record, Callbacks))
- return EC;
- }
-
- return Error::success();
-}
-
-struct FieldListVisitHelper {
- FieldListVisitHelper(TypeVisitorCallbacks &Callbacks, ArrayRef<uint8_t> Data,
- VisitorDataSource Source)
- : Stream(Data, llvm::support::little), Reader(Stream),
- Deserializer(Reader),
- Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
- if (Source == VDS_BytesPresent) {
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(Callbacks);
- }
- }
-
- BinaryByteStream Stream;
- BinaryStreamReader Reader;
- FieldListDeserializer Deserializer;
- TypeVisitorCallbackPipeline Pipeline;
- CVTypeVisitor Visitor;
-};
-
-struct VisitHelper {
- VisitHelper(TypeVisitorCallbacks &Callbacks, VisitorDataSource Source)
- : Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
- if (Source == VDS_BytesPresent) {
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(Callbacks);
- }
- }
-
- TypeDeserializer Deserializer;
- TypeVisitorCallbackPipeline Pipeline;
- CVTypeVisitor Visitor;
-};
-}
-
-Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index,
- TypeVisitorCallbacks &Callbacks,
- VisitorDataSource Source) {
- VisitHelper V(Callbacks, Source);
- return V.Visitor.visitTypeRecord(Record, Index);
-}
-
-Error llvm::codeview::visitTypeRecord(CVType &Record,
- TypeVisitorCallbacks &Callbacks,
- VisitorDataSource Source) {
- VisitHelper V(Callbacks, Source);
- return V.Visitor.visitTypeRecord(Record);
-}
-
-Error llvm::codeview::visitTypeStream(const CVTypeArray &Types,
- TypeVisitorCallbacks &Callbacks,
- VisitorDataSource Source) {
- VisitHelper V(Callbacks, Source);
- return V.Visitor.visitTypeStream(Types);
-}
-
-Error llvm::codeview::visitTypeStream(CVTypeRange Types,
- TypeVisitorCallbacks &Callbacks) {
- VisitHelper V(Callbacks, VDS_BytesPresent);
- return V.Visitor.visitTypeStream(Types);
-}
-
-Error llvm::codeview::visitTypeStream(TypeCollection &Types,
- TypeVisitorCallbacks &Callbacks) {
- // When the internal visitor calls Types.getType(Index) the interface is
- // required to return a CVType with the bytes filled out. So we can assume
- // that the bytes will be present when individual records are visited.
- VisitHelper V(Callbacks, VDS_BytesPresent);
- return V.Visitor.visitTypeStream(Types);
-}
-
-Error llvm::codeview::visitMemberRecord(CVMemberRecord Record,
- TypeVisitorCallbacks &Callbacks,
- VisitorDataSource Source) {
- FieldListVisitHelper V(Callbacks, Record.Data, Source);
- return V.Visitor.visitMemberRecord(Record);
-}
-
-Error llvm::codeview::visitMemberRecord(TypeLeafKind Kind,
- ArrayRef<uint8_t> Record,
- TypeVisitorCallbacks &Callbacks) {
- CVMemberRecord R;
- R.Data = Record;
- R.Kind = Kind;
- return visitMemberRecord(R, Callbacks, VDS_BytesPresent);
-}
-
-Error llvm::codeview::visitMemberRecordStream(ArrayRef<uint8_t> FieldList,
- TypeVisitorCallbacks &Callbacks) {
- FieldListVisitHelper V(Callbacks, FieldList, VDS_BytesPresent);
- return V.Visitor.visitFieldListMemberStream(V.Reader);
-}
+//===- CVTypeVisitor.cpp ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbackPipeline.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+
+template <typename T>
+static Error visitKnownRecord(CVType &Record, TypeVisitorCallbacks &Callbacks) {
+ TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind());
+ T KnownRecord(RK);
+ if (auto EC = Callbacks.visitKnownRecord(Record, KnownRecord))
+ return EC;
+ return Error::success();
+}
+
+template <typename T>
+static Error visitKnownMember(CVMemberRecord &Record,
+ TypeVisitorCallbacks &Callbacks) {
+ TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Kind);
+ T KnownRecord(RK);
+ if (auto EC = Callbacks.visitKnownMember(Record, KnownRecord))
+ return EC;
+ return Error::success();
+}
+
+static Error visitMemberRecord(CVMemberRecord &Record,
+ TypeVisitorCallbacks &Callbacks) {
+ if (auto EC = Callbacks.visitMemberBegin(Record))
+ return EC;
+
+ switch (Record.Kind) {
+ default:
+ if (auto EC = Callbacks.visitUnknownMember(Record))
+ return EC;
+ break;
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ case EnumName: { \
+ if (auto EC = visitKnownMember<Name##Record>(Record, Callbacks)) \
+ return EC; \
+ break; \
+ }
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
+ MEMBER_RECORD(EnumVal, EnumVal, AliasName)
+#define TYPE_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ }
+
+ if (auto EC = Callbacks.visitMemberEnd(Record))
+ return EC;
+
+ return Error::success();
+}
+
+namespace {
+
+class CVTypeVisitor {
+public:
+ explicit CVTypeVisitor(TypeVisitorCallbacks &Callbacks);
+
+ Error visitTypeRecord(CVType &Record, TypeIndex Index);
+ Error visitTypeRecord(CVType &Record);
+
+ /// Visits the type records in Data. Sets the error flag on parse failures.
+ Error visitTypeStream(const CVTypeArray &Types);
+ Error visitTypeStream(CVTypeRange Types);
+ Error visitTypeStream(TypeCollection &Types);
+
+ Error visitMemberRecord(CVMemberRecord Record);
+ Error visitFieldListMemberStream(BinaryStreamReader &Stream);
+
+private:
+ Error finishVisitation(CVType &Record);
+
+ /// The interface to the class that gets notified of each visitation.
+ TypeVisitorCallbacks &Callbacks;
+};
+
+CVTypeVisitor::CVTypeVisitor(TypeVisitorCallbacks &Callbacks)
+ : Callbacks(Callbacks) {}
+
+Error CVTypeVisitor::finishVisitation(CVType &Record) {
+ switch (Record.kind()) {
+ default:
+ if (auto EC = Callbacks.visitUnknownType(Record))
+ return EC;
+ break;
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ case EnumName: { \
+ if (auto EC = visitKnownRecord<Name##Record>(Record, Callbacks)) \
+ return EC; \
+ break; \
+ }
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \
+ TYPE_RECORD(EnumVal, EnumVal, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ }
+
+ if (auto EC = Callbacks.visitTypeEnd(Record))
+ return EC;
+
+ return Error::success();
+}
+
+Error CVTypeVisitor::visitTypeRecord(CVType &Record, TypeIndex Index) {
+ if (auto EC = Callbacks.visitTypeBegin(Record, Index))
+ return EC;
+
+ return finishVisitation(Record);
+}
+
+Error CVTypeVisitor::visitTypeRecord(CVType &Record) {
+ if (auto EC = Callbacks.visitTypeBegin(Record))
+ return EC;
+
+ return finishVisitation(Record);
+}
+
+Error CVTypeVisitor::visitMemberRecord(CVMemberRecord Record) {
+ return ::visitMemberRecord(Record, Callbacks);
+}
+
+/// Visits the type records in Data. Sets the error flag on parse failures.
+Error CVTypeVisitor::visitTypeStream(const CVTypeArray &Types) {
+ for (auto I : Types) {
+ if (auto EC = visitTypeRecord(I))
+ return EC;
+ }
+ return Error::success();
+}
+
+Error CVTypeVisitor::visitTypeStream(CVTypeRange Types) {
+ for (auto I : Types) {
+ if (auto EC = visitTypeRecord(I))
+ return EC;
+ }
+ return Error::success();
+}
+
+Error CVTypeVisitor::visitTypeStream(TypeCollection &Types) {
+ Optional<TypeIndex> I = Types.getFirst();
+ while (I) {
+ CVType Type = Types.getType(*I);
+ if (auto EC = visitTypeRecord(Type, *I))
+ return EC;
+ I = Types.getNext(*I);
+ }
+ return Error::success();
+}
+
+Error CVTypeVisitor::visitFieldListMemberStream(BinaryStreamReader &Reader) {
+ TypeLeafKind Leaf;
+ while (!Reader.empty()) {
+ if (auto EC = Reader.readEnum(Leaf))
+ return EC;
+
+ CVMemberRecord Record;
+ Record.Kind = Leaf;
+ if (auto EC = ::visitMemberRecord(Record, Callbacks))
+ return EC;
+ }
+
+ return Error::success();
+}
+
+struct FieldListVisitHelper {
+ FieldListVisitHelper(TypeVisitorCallbacks &Callbacks, ArrayRef<uint8_t> Data,
+ VisitorDataSource Source)
+ : Stream(Data, llvm::support::little), Reader(Stream),
+ Deserializer(Reader),
+ Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
+ if (Source == VDS_BytesPresent) {
+ Pipeline.addCallbackToPipeline(Deserializer);
+ Pipeline.addCallbackToPipeline(Callbacks);
+ }
+ }
+
+ BinaryByteStream Stream;
+ BinaryStreamReader Reader;
+ FieldListDeserializer Deserializer;
+ TypeVisitorCallbackPipeline Pipeline;
+ CVTypeVisitor Visitor;
+};
+
+struct VisitHelper {
+ VisitHelper(TypeVisitorCallbacks &Callbacks, VisitorDataSource Source)
+ : Visitor((Source == VDS_BytesPresent) ? Pipeline : Callbacks) {
+ if (Source == VDS_BytesPresent) {
+ Pipeline.addCallbackToPipeline(Deserializer);
+ Pipeline.addCallbackToPipeline(Callbacks);
+ }
+ }
+
+ TypeDeserializer Deserializer;
+ TypeVisitorCallbackPipeline Pipeline;
+ CVTypeVisitor Visitor;
+};
+}
+
+Error llvm::codeview::visitTypeRecord(CVType &Record, TypeIndex Index,
+ TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source) {
+ VisitHelper V(Callbacks, Source);
+ return V.Visitor.visitTypeRecord(Record, Index);
+}
+
+Error llvm::codeview::visitTypeRecord(CVType &Record,
+ TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source) {
+ VisitHelper V(Callbacks, Source);
+ return V.Visitor.visitTypeRecord(Record);
+}
+
+Error llvm::codeview::visitTypeStream(const CVTypeArray &Types,
+ TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source) {
+ VisitHelper V(Callbacks, Source);
+ return V.Visitor.visitTypeStream(Types);
+}
+
+Error llvm::codeview::visitTypeStream(CVTypeRange Types,
+ TypeVisitorCallbacks &Callbacks) {
+ VisitHelper V(Callbacks, VDS_BytesPresent);
+ return V.Visitor.visitTypeStream(Types);
+}
+
+Error llvm::codeview::visitTypeStream(TypeCollection &Types,
+ TypeVisitorCallbacks &Callbacks) {
+ // When the internal visitor calls Types.getType(Index) the interface is
+ // required to return a CVType with the bytes filled out. So we can assume
+ // that the bytes will be present when individual records are visited.
+ VisitHelper V(Callbacks, VDS_BytesPresent);
+ return V.Visitor.visitTypeStream(Types);
+}
+
+Error llvm::codeview::visitMemberRecord(CVMemberRecord Record,
+ TypeVisitorCallbacks &Callbacks,
+ VisitorDataSource Source) {
+ FieldListVisitHelper V(Callbacks, Record.Data, Source);
+ return V.Visitor.visitMemberRecord(Record);
+}
+
+Error llvm::codeview::visitMemberRecord(TypeLeafKind Kind,
+ ArrayRef<uint8_t> Record,
+ TypeVisitorCallbacks &Callbacks) {
+ CVMemberRecord R;
+ R.Data = Record;
+ R.Kind = Kind;
+ return visitMemberRecord(R, Callbacks, VDS_BytesPresent);
+}
+
+Error llvm::codeview::visitMemberRecordStream(ArrayRef<uint8_t> FieldList,
+ TypeVisitorCallbacks &Callbacks) {
+ FieldListVisitHelper V(Callbacks, FieldList, VDS_BytesPresent);
+ return V.Visitor.visitFieldListMemberStream(V.Reader);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewError.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewError.cpp
index 69390c708f..40c45b1f07 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewError.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewError.cpp
@@ -1,49 +1,49 @@
-//===- CodeViewError.cpp - Error extensions for CodeView --------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
-
-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.
-class CodeViewErrorCategory : public std::error_category {
-public:
- const char *name() const noexcept override { return "llvm.codeview"; }
- std::string message(int Condition) const override {
- switch (static_cast<cv_error_code>(Condition)) {
- case cv_error_code::unspecified:
- return "An unknown CodeView error has occurred.";
- case cv_error_code::insufficient_buffer:
- return "The buffer is not large enough to read the requested number of "
- "bytes.";
- case cv_error_code::corrupt_record:
- return "The CodeView record is corrupted.";
- case cv_error_code::no_records:
- return "There are no records.";
- case cv_error_code::operation_unsupported:
- return "The requested operation is not supported.";
- case cv_error_code::unknown_member_record:
- return "The member record is of an unknown type.";
- }
- llvm_unreachable("Unrecognized cv_error_code");
- }
-};
-} // namespace
-
-static llvm::ManagedStatic<CodeViewErrorCategory> CodeViewErrCategory;
-const std::error_category &llvm::codeview::CVErrorCategory() {
- return *CodeViewErrCategory;
-}
-
-char CodeViewError::ID;
+//===- CodeViewError.cpp - Error extensions for CodeView --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+
+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.
+class CodeViewErrorCategory : public std::error_category {
+public:
+ const char *name() const noexcept override { return "llvm.codeview"; }
+ std::string message(int Condition) const override {
+ switch (static_cast<cv_error_code>(Condition)) {
+ case cv_error_code::unspecified:
+ return "An unknown CodeView error has occurred.";
+ case cv_error_code::insufficient_buffer:
+ return "The buffer is not large enough to read the requested number of "
+ "bytes.";
+ case cv_error_code::corrupt_record:
+ return "The CodeView record is corrupted.";
+ case cv_error_code::no_records:
+ return "There are no records.";
+ case cv_error_code::operation_unsupported:
+ return "The requested operation is not supported.";
+ case cv_error_code::unknown_member_record:
+ return "The member record is of an unknown type.";
+ }
+ llvm_unreachable("Unrecognized cv_error_code");
+ }
+};
+} // namespace
+
+static llvm::ManagedStatic<CodeViewErrorCategory> CodeViewErrCategory;
+const std::error_category &llvm::codeview::CVErrorCategory() {
+ return *CodeViewErrCategory;
+}
+
+char CodeViewError::ID;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
index c272985cf2..df7a78fcd2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/CodeViewRecordIO.cpp
@@ -1,370 +1,370 @@
-//===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
- RecordLimit Limit;
- Limit.MaxLength = MaxLength;
- Limit.BeginOffset = getCurrentOffset();
- Limits.push_back(Limit);
- return Error::success();
-}
-
-Error CodeViewRecordIO::endRecord() {
- assert(!Limits.empty() && "Not in a record!");
- Limits.pop_back();
- // We would like to assert that we actually read / wrote all the bytes that we
- // expected to for this record, but unfortunately we can't do this. Some
- // producers such as MASM over-allocate for certain types of records and
- // commit the extraneous data, so when reading we can't be sure every byte
- // will have been read. And when writing we over-allocate temporarily since
- // 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;
- }
- resetStreamedLen();
- }
- 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
- // be allowed by any of the sub-records we're in. In practice, we can only
- // ever be at most 1 sub-record deep (in a FieldList), but this works for
- // the general case.
- uint32_t Offset = getCurrentOffset();
- Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
- for (auto X : makeArrayRef(Limits).drop_front()) {
- Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
- if (ThisMin.hasValue())
- Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
- }
- assert(Min.hasValue() && "Every field must have a maximum length!");
-
- return *Min;
-}
-
-Error CodeViewRecordIO::padToAlignment(uint32_t Align) {
- if (isReading())
- return Reader->padToAlignment(Align);
- return Writer->padToAlignment(Align);
-}
-
-Error CodeViewRecordIO::skipPadding() {
- assert(!isWriting() && "Cannot skip padding while writing!");
-
- if (Reader->bytesRemaining() == 0)
- return Error::success();
-
- uint8_t Leaf = Reader->peek();
- if (Leaf < LF_PAD0)
- return Error::success();
- // Leaf is greater than 0xf0. We should advance by the number of bytes in
- // the low 4 bits.
- unsigned BytesToAdvance = Leaf & 0x0F;
- return Reader->skip(BytesToAdvance);
-}
-
-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 {
- if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
- return EC;
- }
- return Error::success();
-}
-
-Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes,
- const Twine &Comment) {
- ArrayRef<uint8_t> BytesRef(Bytes);
- if (auto EC = mapByteVectorTail(BytesRef, Comment))
- return EC;
- if (!isWriting())
- Bytes.assign(BytesRef.begin(), BytesRef.end());
-
- return Error::success();
-}
-
-Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) {
- if (isStreaming()) {
- std::string TypeNameStr = Streamer->getTypeName(TypeInd);
- if (!TypeNameStr.empty())
- emitComment(Comment + ": " + TypeNameStr);
- else
- emitComment(Comment);
- Streamer->emitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
- incrStreamedLen(sizeof(TypeInd.getIndex()));
- } else if (isWriting()) {
- if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
- return EC;
- } else {
- uint32_t I;
- if (auto EC = Reader->readInteger(I))
- return EC;
- TypeInd.setIndex(I);
- }
- return Error::success();
-}
-
-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;
- } else {
- if (auto EC = writeEncodedSignedInteger(Value))
- return EC;
- }
- } else {
- APSInt N;
- if (auto EC = consume(*Reader, N))
- return EC;
- Value = N.getExtValue();
- }
-
- return Error::success();
-}
-
-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 {
- APSInt N;
- if (auto EC = consume(*Reader, N))
- return EC;
- Value = N.getZExtValue();
- }
- return Error::success();
-}
-
-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());
- } else
- return consume(*Reader, Value);
- return Error::success();
-}
-
-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))
- return EC;
- } else {
- if (auto EC = Reader->readCString(Value))
- return EC;
- }
- return Error::success();
-}
-
-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);
-
- if (isWriting()) {
- if (auto EC = Writer->writeBytes(Guid.Guid))
- return EC;
- } else {
- ArrayRef<uint8_t> GuidBytes;
- if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
- return EC;
- memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
- }
- return Error::success();
-}
-
-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;
- }
- uint8_t FinalZero = 0;
- if (auto EC = mapInteger(FinalZero))
- return EC;
- } else {
- StringRef S;
- if (auto EC = mapStringZ(S))
- return EC;
- while (!S.empty()) {
- Value.push_back(S);
- if (auto EC = mapStringZ(S))
- return EC;
- };
- }
- return Error::success();
-}
-
-void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
- const Twine &Comment) {
- 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) {
- if (Value >= std::numeric_limits<int8_t>::min()) {
- if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
- return EC;
- if (auto EC = Writer->writeInteger<int8_t>(Value))
- return EC;
- } else if (Value >= std::numeric_limits<int16_t>::min()) {
- if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
- return EC;
- if (auto EC = Writer->writeInteger<int16_t>(Value))
- return EC;
- } else if (Value >= std::numeric_limits<int32_t>::min()) {
- if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
- return EC;
- if (auto EC = Writer->writeInteger<int32_t>(Value))
- return EC;
- } else {
- if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
- return EC;
- if (auto EC = Writer->writeInteger(Value))
- return EC;
- }
- return Error::success();
-}
-
-Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
- if (Value < LF_NUMERIC) {
- if (auto EC = Writer->writeInteger<uint16_t>(Value))
- return EC;
- } else if (Value <= std::numeric_limits<uint16_t>::max()) {
- if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
- return EC;
- if (auto EC = Writer->writeInteger<uint16_t>(Value))
- return EC;
- } else if (Value <= std::numeric_limits<uint32_t>::max()) {
- if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
- return EC;
- if (auto EC = Writer->writeInteger<uint32_t>(Value))
- return EC;
- } else {
- if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
- return EC;
- if (auto EC = Writer->writeInteger(Value))
- return EC;
- }
-
- return Error::success();
-}
+//===- CodeViewRecordIO.cpp -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/CodeViewRecordIO.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error CodeViewRecordIO::beginRecord(Optional<uint32_t> MaxLength) {
+ RecordLimit Limit;
+ Limit.MaxLength = MaxLength;
+ Limit.BeginOffset = getCurrentOffset();
+ Limits.push_back(Limit);
+ return Error::success();
+}
+
+Error CodeViewRecordIO::endRecord() {
+ assert(!Limits.empty() && "Not in a record!");
+ Limits.pop_back();
+ // We would like to assert that we actually read / wrote all the bytes that we
+ // expected to for this record, but unfortunately we can't do this. Some
+ // producers such as MASM over-allocate for certain types of records and
+ // commit the extraneous data, so when reading we can't be sure every byte
+ // will have been read. And when writing we over-allocate temporarily since
+ // 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;
+ }
+ resetStreamedLen();
+ }
+ 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
+ // be allowed by any of the sub-records we're in. In practice, we can only
+ // ever be at most 1 sub-record deep (in a FieldList), but this works for
+ // the general case.
+ uint32_t Offset = getCurrentOffset();
+ Optional<uint32_t> Min = Limits.front().bytesRemaining(Offset);
+ for (auto X : makeArrayRef(Limits).drop_front()) {
+ Optional<uint32_t> ThisMin = X.bytesRemaining(Offset);
+ if (ThisMin.hasValue())
+ Min = (Min.hasValue()) ? std::min(*Min, *ThisMin) : *ThisMin;
+ }
+ assert(Min.hasValue() && "Every field must have a maximum length!");
+
+ return *Min;
+}
+
+Error CodeViewRecordIO::padToAlignment(uint32_t Align) {
+ if (isReading())
+ return Reader->padToAlignment(Align);
+ return Writer->padToAlignment(Align);
+}
+
+Error CodeViewRecordIO::skipPadding() {
+ assert(!isWriting() && "Cannot skip padding while writing!");
+
+ if (Reader->bytesRemaining() == 0)
+ return Error::success();
+
+ uint8_t Leaf = Reader->peek();
+ if (Leaf < LF_PAD0)
+ return Error::success();
+ // Leaf is greater than 0xf0. We should advance by the number of bytes in
+ // the low 4 bits.
+ unsigned BytesToAdvance = Leaf & 0x0F;
+ return Reader->skip(BytesToAdvance);
+}
+
+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 {
+ if (auto EC = Reader->readBytes(Bytes, Reader->bytesRemaining()))
+ return EC;
+ }
+ return Error::success();
+}
+
+Error CodeViewRecordIO::mapByteVectorTail(std::vector<uint8_t> &Bytes,
+ const Twine &Comment) {
+ ArrayRef<uint8_t> BytesRef(Bytes);
+ if (auto EC = mapByteVectorTail(BytesRef, Comment))
+ return EC;
+ if (!isWriting())
+ Bytes.assign(BytesRef.begin(), BytesRef.end());
+
+ return Error::success();
+}
+
+Error CodeViewRecordIO::mapInteger(TypeIndex &TypeInd, const Twine &Comment) {
+ if (isStreaming()) {
+ std::string TypeNameStr = Streamer->getTypeName(TypeInd);
+ if (!TypeNameStr.empty())
+ emitComment(Comment + ": " + TypeNameStr);
+ else
+ emitComment(Comment);
+ Streamer->emitIntValue(TypeInd.getIndex(), sizeof(TypeInd.getIndex()));
+ incrStreamedLen(sizeof(TypeInd.getIndex()));
+ } else if (isWriting()) {
+ if (auto EC = Writer->writeInteger(TypeInd.getIndex()))
+ return EC;
+ } else {
+ uint32_t I;
+ if (auto EC = Reader->readInteger(I))
+ return EC;
+ TypeInd.setIndex(I);
+ }
+ return Error::success();
+}
+
+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;
+ } else {
+ if (auto EC = writeEncodedSignedInteger(Value))
+ return EC;
+ }
+ } else {
+ APSInt N;
+ if (auto EC = consume(*Reader, N))
+ return EC;
+ Value = N.getExtValue();
+ }
+
+ return Error::success();
+}
+
+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 {
+ APSInt N;
+ if (auto EC = consume(*Reader, N))
+ return EC;
+ Value = N.getZExtValue();
+ }
+ return Error::success();
+}
+
+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());
+ } else
+ return consume(*Reader, Value);
+ return Error::success();
+}
+
+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))
+ return EC;
+ } else {
+ if (auto EC = Reader->readCString(Value))
+ return EC;
+ }
+ return Error::success();
+}
+
+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);
+
+ if (isWriting()) {
+ if (auto EC = Writer->writeBytes(Guid.Guid))
+ return EC;
+ } else {
+ ArrayRef<uint8_t> GuidBytes;
+ if (auto EC = Reader->readBytes(GuidBytes, GuidSize))
+ return EC;
+ memcpy(Guid.Guid, GuidBytes.data(), GuidSize);
+ }
+ return Error::success();
+}
+
+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;
+ }
+ uint8_t FinalZero = 0;
+ if (auto EC = mapInteger(FinalZero))
+ return EC;
+ } else {
+ StringRef S;
+ if (auto EC = mapStringZ(S))
+ return EC;
+ while (!S.empty()) {
+ Value.push_back(S);
+ if (auto EC = mapStringZ(S))
+ return EC;
+ };
+ }
+ return Error::success();
+}
+
+void CodeViewRecordIO::emitEncodedSignedInteger(const int64_t &Value,
+ const Twine &Comment) {
+ 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) {
+ if (Value >= std::numeric_limits<int8_t>::min()) {
+ if (auto EC = Writer->writeInteger<uint16_t>(LF_CHAR))
+ return EC;
+ if (auto EC = Writer->writeInteger<int8_t>(Value))
+ return EC;
+ } else if (Value >= std::numeric_limits<int16_t>::min()) {
+ if (auto EC = Writer->writeInteger<uint16_t>(LF_SHORT))
+ return EC;
+ if (auto EC = Writer->writeInteger<int16_t>(Value))
+ return EC;
+ } else if (Value >= std::numeric_limits<int32_t>::min()) {
+ if (auto EC = Writer->writeInteger<uint16_t>(LF_LONG))
+ return EC;
+ if (auto EC = Writer->writeInteger<int32_t>(Value))
+ return EC;
+ } else {
+ if (auto EC = Writer->writeInteger<uint16_t>(LF_QUADWORD))
+ return EC;
+ if (auto EC = Writer->writeInteger(Value))
+ return EC;
+ }
+ return Error::success();
+}
+
+Error CodeViewRecordIO::writeEncodedUnsignedInteger(const uint64_t &Value) {
+ if (Value < LF_NUMERIC) {
+ if (auto EC = Writer->writeInteger<uint16_t>(Value))
+ return EC;
+ } else if (Value <= std::numeric_limits<uint16_t>::max()) {
+ if (auto EC = Writer->writeInteger<uint16_t>(LF_USHORT))
+ return EC;
+ if (auto EC = Writer->writeInteger<uint16_t>(Value))
+ return EC;
+ } else if (Value <= std::numeric_limits<uint32_t>::max()) {
+ if (auto EC = Writer->writeInteger<uint16_t>(LF_ULONG))
+ return EC;
+ if (auto EC = Writer->writeInteger<uint32_t>(Value))
+ return EC;
+ } else {
+ if (auto EC = Writer->writeInteger<uint16_t>(LF_UQUADWORD))
+ return EC;
+ if (auto EC = Writer->writeInteger(Value))
+ return EC;
+ }
+
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp
index 799cffb711..52389956dc 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/ContinuationRecordBuilder.cpp
@@ -1,251 +1,251 @@
-#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-namespace {
-struct ContinuationRecord {
- ulittle16_t Kind{uint16_t(TypeLeafKind::LF_INDEX)};
- ulittle16_t Size{0};
- ulittle32_t IndexRef{0xB0C0B0C0};
-};
-
-struct SegmentInjection {
- SegmentInjection(TypeLeafKind Kind) { Prefix.RecordKind = Kind; }
-
- ContinuationRecord Cont;
- RecordPrefix Prefix;
-};
-} // namespace
-
-static void addPadding(BinaryStreamWriter &Writer) {
- uint32_t Align = Writer.getOffset() % 4;
- if (Align == 0)
- return;
-
- int PaddingBytes = 4 - Align;
- while (PaddingBytes > 0) {
- uint8_t Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
- cantFail(Writer.writeInteger(Pad));
- --PaddingBytes;
- }
-}
-
-static SegmentInjection InjectFieldList(TypeLeafKind::LF_FIELDLIST);
-static SegmentInjection InjectMethodOverloadList(TypeLeafKind::LF_METHODLIST);
-
-static constexpr uint32_t ContinuationLength = sizeof(ContinuationRecord);
-static constexpr uint32_t MaxSegmentLength =
- MaxRecordLength - ContinuationLength;
-
-static inline TypeLeafKind getTypeLeafKind(ContinuationRecordKind CK) {
- return (CK == ContinuationRecordKind::FieldList) ? LF_FIELDLIST
- : LF_METHODLIST;
-}
-
-ContinuationRecordBuilder::ContinuationRecordBuilder()
- : SegmentWriter(Buffer), Mapping(SegmentWriter) {}
-
-ContinuationRecordBuilder::~ContinuationRecordBuilder() {}
-
-void ContinuationRecordBuilder::begin(ContinuationRecordKind RecordKind) {
- assert(!Kind.hasValue());
- Kind = RecordKind;
- Buffer.clear();
- SegmentWriter.setOffset(0);
- SegmentOffsets.clear();
- SegmentOffsets.push_back(0);
- assert(SegmentWriter.getOffset() == 0);
- assert(SegmentWriter.getLength() == 0);
-
- const SegmentInjection *FLI =
- (RecordKind == ContinuationRecordKind::FieldList)
- ? &InjectFieldList
- : &InjectMethodOverloadList;
- const uint8_t *FLIB = reinterpret_cast<const uint8_t *>(FLI);
- InjectedSegmentBytes =
- ArrayRef<uint8_t>(FLIB, FLIB + sizeof(SegmentInjection));
-
- // Seed the first record with an appropriate record prefix.
- RecordPrefix Prefix(getTypeLeafKind(RecordKind));
- CVType Type(&Prefix, sizeof(Prefix));
- cantFail(Mapping.visitTypeBegin(Type));
-
- cantFail(SegmentWriter.writeObject(Prefix));
-}
-
-template <typename RecordType>
-void ContinuationRecordBuilder::writeMemberType(RecordType &Record) {
- assert(Kind.hasValue());
-
- uint32_t OriginalOffset = SegmentWriter.getOffset();
- CVMemberRecord CVMR;
- CVMR.Kind = static_cast<TypeLeafKind>(Record.getKind());
-
- // Member Records aren't length-prefixed, they only have a 2-byte TypeLeafKind
- // at the beginning.
- cantFail(SegmentWriter.writeEnum(CVMR.Kind));
-
- // Let the Mapping handle the rest.
- cantFail(Mapping.visitMemberBegin(CVMR));
- cantFail(Mapping.visitKnownMember(CVMR, Record));
- cantFail(Mapping.visitMemberEnd(CVMR));
-
- // Make sure it's padded to 4 bytes.
- addPadding(SegmentWriter);
- assert(getCurrentSegmentLength() % 4 == 0);
-
- // The maximum length of a single segment is 64KB minus the size to insert a
- // continuation. So if we are over that, inject a continuation between the
- // previous member and the member that was just written, then end the previous
- // segment after the continuation and begin a new one with the just-written
- // member.
- if (getCurrentSegmentLength() > MaxSegmentLength) {
- // We need to inject some bytes before the member we just wrote but after
- // the previous member. Save off the length of the member we just wrote so
- // that we can do some sanity checking on it.
- uint32_t MemberLength = SegmentWriter.getOffset() - OriginalOffset;
- (void) MemberLength;
- insertSegmentEnd(OriginalOffset);
- // Since this member now becomes a new top-level record, it should have
- // gotten a RecordPrefix injected, and that RecordPrefix + the member we
- // just wrote should now constitute the entirety of the current "new"
- // segment.
- assert(getCurrentSegmentLength() == MemberLength + sizeof(RecordPrefix));
- }
-
- assert(getCurrentSegmentLength() % 4 == 0);
- assert(getCurrentSegmentLength() <= MaxSegmentLength);
-}
-
-uint32_t ContinuationRecordBuilder::getCurrentSegmentLength() const {
- return SegmentWriter.getOffset() - SegmentOffsets.back();
-}
-
-void ContinuationRecordBuilder::insertSegmentEnd(uint32_t Offset) {
- uint32_t SegmentBegin = SegmentOffsets.back();
- (void)SegmentBegin;
- assert(Offset > SegmentBegin);
- assert(Offset - SegmentBegin <= MaxSegmentLength);
-
- // We need to make space for the continuation record. For now we can't fill
- // out the length or the TypeIndex of the back-reference, but we need the
- // space to at least be there.
- Buffer.insert(Offset, InjectedSegmentBytes);
-
- uint32_t NewSegmentBegin = Offset + ContinuationLength;
- uint32_t SegmentLength = NewSegmentBegin - SegmentOffsets.back();
- (void) SegmentLength;
-
- assert(SegmentLength % 4 == 0);
- assert(SegmentLength <= MaxRecordLength);
- SegmentOffsets.push_back(NewSegmentBegin);
-
- // Seek to the end so that we can keep writing against the new segment.
- SegmentWriter.setOffset(SegmentWriter.getLength());
- assert(SegmentWriter.bytesRemaining() == 0);
-}
-
-CVType ContinuationRecordBuilder::createSegmentRecord(
- uint32_t OffBegin, uint32_t OffEnd, Optional<TypeIndex> RefersTo) {
- assert(OffEnd - OffBegin <= USHRT_MAX);
-
- MutableArrayRef<uint8_t> Data = Buffer.data();
- Data = Data.slice(OffBegin, OffEnd - OffBegin);
-
- // Write the length to the RecordPrefix, making sure it does not include
- // sizeof(RecordPrefix.Length)
- RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(Data.data());
- Prefix->RecordLen = Data.size() - sizeof(RecordPrefix::RecordLen);
-
- if (RefersTo.hasValue()) {
- auto Continuation = Data.take_back(ContinuationLength);
- ContinuationRecord *CR =
- reinterpret_cast<ContinuationRecord *>(Continuation.data());
- assert(CR->Kind == TypeLeafKind::LF_INDEX);
- assert(CR->IndexRef == 0xB0C0B0C0);
- CR->IndexRef = RefersTo->getIndex();
- }
-
- return CVType(Data);
-}
-
-std::vector<CVType> ContinuationRecordBuilder::end(TypeIndex Index) {
- 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
- // offset specified in the SegmentOffsets array. We now need to iterate
- // over each segment and post-process them in the following two ways:
- // 1) Each top-level record has a RecordPrefix whose type is either
- // LF_FIELDLIST or LF_METHODLIST, but the Length field is still 0.
- // Those should all be set to the correct length now.
- // 2) Each continuation record has an IndexRef field which we set to the
- // magic value 0xB0C0B0C0. Now that the caller has told us the TypeIndex
- // they want this sequence to start from, we can go through and update
- // each one.
- //
- // Logically, the sequence of records we've built up looks like this:
- //
- // SegmentOffsets[0]: <Length> (Initially: uninitialized)
- // SegmentOffsets[0]+2: LF_FIELDLIST
- // SegmentOffsets[0]+4: Member[0]
- // SegmentOffsets[0]+?: ...
- // SegmentOffsets[0]+?: Member[4]
- // SegmentOffsets[1]-8: LF_INDEX
- // SegmentOffsets[1]-6: 0
- // SegmentOffsets[1]-4: <Type Index of Next Record> (Initially: 0xB0C0B0C0)
- //
- // SegmentOffsets[1]: <Length> (Initially: uninitialized)
- // SegmentOffsets[1]+2: LF_FIELDLIST
- // SegmentOffsets[1]+4: Member[0]
- // SegmentOffsets[1]+?: ...
- // SegmentOffsets[1]+?: Member[s]
- // SegmentOffsets[2]-8: LF_INDEX
- // SegmentOffsets[2]-6: 0
- // SegmentOffsets[2]-4: <Type Index of Next Record> (Initially: 0xB0C0B0C0)
- //
- // ...
- //
- // SegmentOffsets[N]: <Length> (Initially: uninitialized)
- // SegmentOffsets[N]+2: LF_FIELDLIST
- // SegmentOffsets[N]+4: Member[0]
- // SegmentOffsets[N]+?: ...
- // SegmentOffsets[N]+?: Member[t]
- //
- // And this is the way we have laid them out in the serialization buffer. But
- // we cannot actually commit them to the underlying stream this way, due to
- // the topological sorting requirement of a type stream (specifically,
- // TypeIndex references can only point backwards, not forwards). So the
- // sequence that we return to the caller contains the records in reverse
- // order, which is the proper order for committing the serialized records.
-
- std::vector<CVType> Types;
- Types.reserve(SegmentOffsets.size());
-
- auto SO = makeArrayRef(SegmentOffsets);
-
- uint32_t End = SegmentWriter.getOffset();
-
- Optional<TypeIndex> RefersTo;
- for (uint32_t Offset : reverse(SO)) {
- Types.push_back(createSegmentRecord(Offset, End, RefersTo));
-
- End = Offset;
- RefersTo = Index++;
- }
-
- Kind.reset();
- return Types;
-}
-
-// Explicitly instantiate the member function for each known type so that we can
-// implement this in the cpp file.
-#define TYPE_RECORD(EnumName, EnumVal, Name)
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name) \
- template void llvm::codeview::ContinuationRecordBuilder::writeMemberType( \
- Name##Record &Record);
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+namespace {
+struct ContinuationRecord {
+ ulittle16_t Kind{uint16_t(TypeLeafKind::LF_INDEX)};
+ ulittle16_t Size{0};
+ ulittle32_t IndexRef{0xB0C0B0C0};
+};
+
+struct SegmentInjection {
+ SegmentInjection(TypeLeafKind Kind) { Prefix.RecordKind = Kind; }
+
+ ContinuationRecord Cont;
+ RecordPrefix Prefix;
+};
+} // namespace
+
+static void addPadding(BinaryStreamWriter &Writer) {
+ uint32_t Align = Writer.getOffset() % 4;
+ if (Align == 0)
+ return;
+
+ int PaddingBytes = 4 - Align;
+ while (PaddingBytes > 0) {
+ uint8_t Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
+ cantFail(Writer.writeInteger(Pad));
+ --PaddingBytes;
+ }
+}
+
+static SegmentInjection InjectFieldList(TypeLeafKind::LF_FIELDLIST);
+static SegmentInjection InjectMethodOverloadList(TypeLeafKind::LF_METHODLIST);
+
+static constexpr uint32_t ContinuationLength = sizeof(ContinuationRecord);
+static constexpr uint32_t MaxSegmentLength =
+ MaxRecordLength - ContinuationLength;
+
+static inline TypeLeafKind getTypeLeafKind(ContinuationRecordKind CK) {
+ return (CK == ContinuationRecordKind::FieldList) ? LF_FIELDLIST
+ : LF_METHODLIST;
+}
+
+ContinuationRecordBuilder::ContinuationRecordBuilder()
+ : SegmentWriter(Buffer), Mapping(SegmentWriter) {}
+
+ContinuationRecordBuilder::~ContinuationRecordBuilder() {}
+
+void ContinuationRecordBuilder::begin(ContinuationRecordKind RecordKind) {
+ assert(!Kind.hasValue());
+ Kind = RecordKind;
+ Buffer.clear();
+ SegmentWriter.setOffset(0);
+ SegmentOffsets.clear();
+ SegmentOffsets.push_back(0);
+ assert(SegmentWriter.getOffset() == 0);
+ assert(SegmentWriter.getLength() == 0);
+
+ const SegmentInjection *FLI =
+ (RecordKind == ContinuationRecordKind::FieldList)
+ ? &InjectFieldList
+ : &InjectMethodOverloadList;
+ const uint8_t *FLIB = reinterpret_cast<const uint8_t *>(FLI);
+ InjectedSegmentBytes =
+ ArrayRef<uint8_t>(FLIB, FLIB + sizeof(SegmentInjection));
+
+ // Seed the first record with an appropriate record prefix.
+ RecordPrefix Prefix(getTypeLeafKind(RecordKind));
+ CVType Type(&Prefix, sizeof(Prefix));
+ cantFail(Mapping.visitTypeBegin(Type));
+
+ cantFail(SegmentWriter.writeObject(Prefix));
+}
+
+template <typename RecordType>
+void ContinuationRecordBuilder::writeMemberType(RecordType &Record) {
+ assert(Kind.hasValue());
+
+ uint32_t OriginalOffset = SegmentWriter.getOffset();
+ CVMemberRecord CVMR;
+ CVMR.Kind = static_cast<TypeLeafKind>(Record.getKind());
+
+ // Member Records aren't length-prefixed, they only have a 2-byte TypeLeafKind
+ // at the beginning.
+ cantFail(SegmentWriter.writeEnum(CVMR.Kind));
+
+ // Let the Mapping handle the rest.
+ cantFail(Mapping.visitMemberBegin(CVMR));
+ cantFail(Mapping.visitKnownMember(CVMR, Record));
+ cantFail(Mapping.visitMemberEnd(CVMR));
+
+ // Make sure it's padded to 4 bytes.
+ addPadding(SegmentWriter);
+ assert(getCurrentSegmentLength() % 4 == 0);
+
+ // The maximum length of a single segment is 64KB minus the size to insert a
+ // continuation. So if we are over that, inject a continuation between the
+ // previous member and the member that was just written, then end the previous
+ // segment after the continuation and begin a new one with the just-written
+ // member.
+ if (getCurrentSegmentLength() > MaxSegmentLength) {
+ // We need to inject some bytes before the member we just wrote but after
+ // the previous member. Save off the length of the member we just wrote so
+ // that we can do some sanity checking on it.
+ uint32_t MemberLength = SegmentWriter.getOffset() - OriginalOffset;
+ (void) MemberLength;
+ insertSegmentEnd(OriginalOffset);
+ // Since this member now becomes a new top-level record, it should have
+ // gotten a RecordPrefix injected, and that RecordPrefix + the member we
+ // just wrote should now constitute the entirety of the current "new"
+ // segment.
+ assert(getCurrentSegmentLength() == MemberLength + sizeof(RecordPrefix));
+ }
+
+ assert(getCurrentSegmentLength() % 4 == 0);
+ assert(getCurrentSegmentLength() <= MaxSegmentLength);
+}
+
+uint32_t ContinuationRecordBuilder::getCurrentSegmentLength() const {
+ return SegmentWriter.getOffset() - SegmentOffsets.back();
+}
+
+void ContinuationRecordBuilder::insertSegmentEnd(uint32_t Offset) {
+ uint32_t SegmentBegin = SegmentOffsets.back();
+ (void)SegmentBegin;
+ assert(Offset > SegmentBegin);
+ assert(Offset - SegmentBegin <= MaxSegmentLength);
+
+ // We need to make space for the continuation record. For now we can't fill
+ // out the length or the TypeIndex of the back-reference, but we need the
+ // space to at least be there.
+ Buffer.insert(Offset, InjectedSegmentBytes);
+
+ uint32_t NewSegmentBegin = Offset + ContinuationLength;
+ uint32_t SegmentLength = NewSegmentBegin - SegmentOffsets.back();
+ (void) SegmentLength;
+
+ assert(SegmentLength % 4 == 0);
+ assert(SegmentLength <= MaxRecordLength);
+ SegmentOffsets.push_back(NewSegmentBegin);
+
+ // Seek to the end so that we can keep writing against the new segment.
+ SegmentWriter.setOffset(SegmentWriter.getLength());
+ assert(SegmentWriter.bytesRemaining() == 0);
+}
+
+CVType ContinuationRecordBuilder::createSegmentRecord(
+ uint32_t OffBegin, uint32_t OffEnd, Optional<TypeIndex> RefersTo) {
+ assert(OffEnd - OffBegin <= USHRT_MAX);
+
+ MutableArrayRef<uint8_t> Data = Buffer.data();
+ Data = Data.slice(OffBegin, OffEnd - OffBegin);
+
+ // Write the length to the RecordPrefix, making sure it does not include
+ // sizeof(RecordPrefix.Length)
+ RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(Data.data());
+ Prefix->RecordLen = Data.size() - sizeof(RecordPrefix::RecordLen);
+
+ if (RefersTo.hasValue()) {
+ auto Continuation = Data.take_back(ContinuationLength);
+ ContinuationRecord *CR =
+ reinterpret_cast<ContinuationRecord *>(Continuation.data());
+ assert(CR->Kind == TypeLeafKind::LF_INDEX);
+ assert(CR->IndexRef == 0xB0C0B0C0);
+ CR->IndexRef = RefersTo->getIndex();
+ }
+
+ return CVType(Data);
+}
+
+std::vector<CVType> ContinuationRecordBuilder::end(TypeIndex Index) {
+ 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
+ // offset specified in the SegmentOffsets array. We now need to iterate
+ // over each segment and post-process them in the following two ways:
+ // 1) Each top-level record has a RecordPrefix whose type is either
+ // LF_FIELDLIST or LF_METHODLIST, but the Length field is still 0.
+ // Those should all be set to the correct length now.
+ // 2) Each continuation record has an IndexRef field which we set to the
+ // magic value 0xB0C0B0C0. Now that the caller has told us the TypeIndex
+ // they want this sequence to start from, we can go through and update
+ // each one.
+ //
+ // Logically, the sequence of records we've built up looks like this:
+ //
+ // SegmentOffsets[0]: <Length> (Initially: uninitialized)
+ // SegmentOffsets[0]+2: LF_FIELDLIST
+ // SegmentOffsets[0]+4: Member[0]
+ // SegmentOffsets[0]+?: ...
+ // SegmentOffsets[0]+?: Member[4]
+ // SegmentOffsets[1]-8: LF_INDEX
+ // SegmentOffsets[1]-6: 0
+ // SegmentOffsets[1]-4: <Type Index of Next Record> (Initially: 0xB0C0B0C0)
+ //
+ // SegmentOffsets[1]: <Length> (Initially: uninitialized)
+ // SegmentOffsets[1]+2: LF_FIELDLIST
+ // SegmentOffsets[1]+4: Member[0]
+ // SegmentOffsets[1]+?: ...
+ // SegmentOffsets[1]+?: Member[s]
+ // SegmentOffsets[2]-8: LF_INDEX
+ // SegmentOffsets[2]-6: 0
+ // SegmentOffsets[2]-4: <Type Index of Next Record> (Initially: 0xB0C0B0C0)
+ //
+ // ...
+ //
+ // SegmentOffsets[N]: <Length> (Initially: uninitialized)
+ // SegmentOffsets[N]+2: LF_FIELDLIST
+ // SegmentOffsets[N]+4: Member[0]
+ // SegmentOffsets[N]+?: ...
+ // SegmentOffsets[N]+?: Member[t]
+ //
+ // And this is the way we have laid them out in the serialization buffer. But
+ // we cannot actually commit them to the underlying stream this way, due to
+ // the topological sorting requirement of a type stream (specifically,
+ // TypeIndex references can only point backwards, not forwards). So the
+ // sequence that we return to the caller contains the records in reverse
+ // order, which is the proper order for committing the serialized records.
+
+ std::vector<CVType> Types;
+ Types.reserve(SegmentOffsets.size());
+
+ auto SO = makeArrayRef(SegmentOffsets);
+
+ uint32_t End = SegmentWriter.getOffset();
+
+ Optional<TypeIndex> RefersTo;
+ for (uint32_t Offset : reverse(SO)) {
+ Types.push_back(createSegmentRecord(Offset, End, RefersTo));
+
+ End = Offset;
+ RefersTo = Index++;
+ }
+
+ Kind.reset();
+ return Types;
+}
+
+// Explicitly instantiate the member function for each known type so that we can
+// implement this in the cpp file.
+#define TYPE_RECORD(EnumName, EnumVal, Name)
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name) \
+ template void llvm::codeview::ContinuationRecordBuilder::writeMemberType( \
+ Name##Record &Record);
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp
index 3d28bac00c..856bc26dfa 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugChecksumsSubsection.cpp
@@ -1,115 +1,115 @@
-//===- DebugChecksumsSubsection.cpp ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-struct FileChecksumEntryHeader {
- using ulittle32_t = support::ulittle32_t;
-
- ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
- uint8_t ChecksumSize; // Number of bytes of checksum.
- uint8_t ChecksumKind; // FileChecksumKind
- // Checksum bytes follow.
-};
-
-Error VarStreamArrayExtractor<FileChecksumEntry>::
-operator()(BinaryStreamRef Stream, uint32_t &Len, FileChecksumEntry &Item) {
- BinaryStreamReader Reader(Stream);
-
- const FileChecksumEntryHeader *Header;
- if (auto EC = Reader.readObject(Header))
- return EC;
-
- Item.FileNameOffset = Header->FileNameOffset;
- Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
- if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
- return EC;
-
- Len = alignTo(Header->ChecksumSize + sizeof(FileChecksumEntryHeader), 4);
- return Error::success();
-}
-
-Error DebugChecksumsSubsectionRef::initialize(BinaryStreamReader Reader) {
- if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))
- return EC;
-
- return Error::success();
-}
-
-Error DebugChecksumsSubsectionRef::initialize(BinaryStreamRef Section) {
- BinaryStreamReader Reader(Section);
- return initialize(Reader);
-}
-
-DebugChecksumsSubsection::DebugChecksumsSubsection(
- DebugStringTableSubsection &Strings)
- : DebugSubsection(DebugSubsectionKind::FileChecksums), Strings(Strings) {}
-
-void DebugChecksumsSubsection::addChecksum(StringRef FileName,
- FileChecksumKind Kind,
- ArrayRef<uint8_t> Bytes) {
- FileChecksumEntry Entry;
- if (!Bytes.empty()) {
- uint8_t *Copy = Storage.Allocate<uint8_t>(Bytes.size());
- ::memcpy(Copy, Bytes.data(), Bytes.size());
- Entry.Checksum = makeArrayRef(Copy, Bytes.size());
- }
-
- Entry.FileNameOffset = Strings.insert(FileName);
- Entry.Kind = Kind;
- Checksums.push_back(Entry);
-
- // This maps the offset of this string in the string table to the offset
- // of this checksum entry in the checksum buffer.
- OffsetMap[Entry.FileNameOffset] = SerializedSize;
- assert(SerializedSize % 4 == 0);
-
- uint32_t Len = alignTo(sizeof(FileChecksumEntryHeader) + Bytes.size(), 4);
- SerializedSize += Len;
-}
-
-uint32_t DebugChecksumsSubsection::calculateSerializedSize() const {
- return SerializedSize;
-}
-
-Error DebugChecksumsSubsection::commit(BinaryStreamWriter &Writer) const {
- for (const auto &FC : Checksums) {
- FileChecksumEntryHeader Header;
- Header.ChecksumKind = uint8_t(FC.Kind);
- Header.ChecksumSize = FC.Checksum.size();
- Header.FileNameOffset = FC.FileNameOffset;
- if (auto EC = Writer.writeObject(Header))
- return EC;
- if (auto EC = Writer.writeArray(makeArrayRef(FC.Checksum)))
- return EC;
- if (auto EC = Writer.padToAlignment(4))
- return EC;
- }
- return Error::success();
-}
-
-uint32_t DebugChecksumsSubsection::mapChecksumOffset(StringRef FileName) const {
- uint32_t Offset = Strings.getIdForString(FileName);
- auto Iter = OffsetMap.find(Offset);
- assert(Iter != OffsetMap.end());
- return Iter->second;
-}
+//===- DebugChecksumsSubsection.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+struct FileChecksumEntryHeader {
+ using ulittle32_t = support::ulittle32_t;
+
+ ulittle32_t FileNameOffset; // Byte offset of filename in global string table.
+ uint8_t ChecksumSize; // Number of bytes of checksum.
+ uint8_t ChecksumKind; // FileChecksumKind
+ // Checksum bytes follow.
+};
+
+Error VarStreamArrayExtractor<FileChecksumEntry>::
+operator()(BinaryStreamRef Stream, uint32_t &Len, FileChecksumEntry &Item) {
+ BinaryStreamReader Reader(Stream);
+
+ const FileChecksumEntryHeader *Header;
+ if (auto EC = Reader.readObject(Header))
+ return EC;
+
+ Item.FileNameOffset = Header->FileNameOffset;
+ Item.Kind = static_cast<FileChecksumKind>(Header->ChecksumKind);
+ if (auto EC = Reader.readBytes(Item.Checksum, Header->ChecksumSize))
+ return EC;
+
+ Len = alignTo(Header->ChecksumSize + sizeof(FileChecksumEntryHeader), 4);
+ return Error::success();
+}
+
+Error DebugChecksumsSubsectionRef::initialize(BinaryStreamReader Reader) {
+ if (auto EC = Reader.readArray(Checksums, Reader.bytesRemaining()))
+ return EC;
+
+ return Error::success();
+}
+
+Error DebugChecksumsSubsectionRef::initialize(BinaryStreamRef Section) {
+ BinaryStreamReader Reader(Section);
+ return initialize(Reader);
+}
+
+DebugChecksumsSubsection::DebugChecksumsSubsection(
+ DebugStringTableSubsection &Strings)
+ : DebugSubsection(DebugSubsectionKind::FileChecksums), Strings(Strings) {}
+
+void DebugChecksumsSubsection::addChecksum(StringRef FileName,
+ FileChecksumKind Kind,
+ ArrayRef<uint8_t> Bytes) {
+ FileChecksumEntry Entry;
+ if (!Bytes.empty()) {
+ uint8_t *Copy = Storage.Allocate<uint8_t>(Bytes.size());
+ ::memcpy(Copy, Bytes.data(), Bytes.size());
+ Entry.Checksum = makeArrayRef(Copy, Bytes.size());
+ }
+
+ Entry.FileNameOffset = Strings.insert(FileName);
+ Entry.Kind = Kind;
+ Checksums.push_back(Entry);
+
+ // This maps the offset of this string in the string table to the offset
+ // of this checksum entry in the checksum buffer.
+ OffsetMap[Entry.FileNameOffset] = SerializedSize;
+ assert(SerializedSize % 4 == 0);
+
+ uint32_t Len = alignTo(sizeof(FileChecksumEntryHeader) + Bytes.size(), 4);
+ SerializedSize += Len;
+}
+
+uint32_t DebugChecksumsSubsection::calculateSerializedSize() const {
+ return SerializedSize;
+}
+
+Error DebugChecksumsSubsection::commit(BinaryStreamWriter &Writer) const {
+ for (const auto &FC : Checksums) {
+ FileChecksumEntryHeader Header;
+ Header.ChecksumKind = uint8_t(FC.Kind);
+ Header.ChecksumSize = FC.Checksum.size();
+ Header.FileNameOffset = FC.FileNameOffset;
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(FC.Checksum)))
+ return EC;
+ if (auto EC = Writer.padToAlignment(4))
+ return EC;
+ }
+ return Error::success();
+}
+
+uint32_t DebugChecksumsSubsection::mapChecksumOffset(StringRef FileName) const {
+ uint32_t Offset = Strings.getIdForString(FileName);
+ auto Iter = OffsetMap.find(Offset);
+ assert(Iter != OffsetMap.end());
+ return Iter->second;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp
index b23410409f..2334e9f5f6 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossExSubsection.cpp
@@ -1,52 +1,52 @@
-//===- DebugCrossExSubsection.cpp -----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error DebugCrossModuleExportsSubsectionRef::initialize(
- BinaryStreamReader Reader) {
- if (Reader.bytesRemaining() % sizeof(CrossModuleExport) != 0)
- return make_error<CodeViewError>(
- cv_error_code::corrupt_record,
- "Cross Scope Exports section is an invalid size!");
-
- uint32_t Size = Reader.bytesRemaining() / sizeof(CrossModuleExport);
- return Reader.readArray(References, Size);
-}
-
-Error DebugCrossModuleExportsSubsectionRef::initialize(BinaryStreamRef Stream) {
- BinaryStreamReader Reader(Stream);
- return initialize(Reader);
-}
-
-void DebugCrossModuleExportsSubsection::addMapping(uint32_t Local,
- uint32_t Global) {
- Mappings[Local] = Global;
-}
-
-uint32_t DebugCrossModuleExportsSubsection::calculateSerializedSize() const {
- return Mappings.size() * sizeof(CrossModuleExport);
-}
-
-Error DebugCrossModuleExportsSubsection::commit(
- BinaryStreamWriter &Writer) const {
- for (const auto &M : Mappings) {
- if (auto EC = Writer.writeInteger(M.first))
- return EC;
- if (auto EC = Writer.writeInteger(M.second))
- return EC;
- }
- return Error::success();
-}
+//===- DebugCrossExSubsection.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error DebugCrossModuleExportsSubsectionRef::initialize(
+ BinaryStreamReader Reader) {
+ if (Reader.bytesRemaining() % sizeof(CrossModuleExport) != 0)
+ return make_error<CodeViewError>(
+ cv_error_code::corrupt_record,
+ "Cross Scope Exports section is an invalid size!");
+
+ uint32_t Size = Reader.bytesRemaining() / sizeof(CrossModuleExport);
+ return Reader.readArray(References, Size);
+}
+
+Error DebugCrossModuleExportsSubsectionRef::initialize(BinaryStreamRef Stream) {
+ BinaryStreamReader Reader(Stream);
+ return initialize(Reader);
+}
+
+void DebugCrossModuleExportsSubsection::addMapping(uint32_t Local,
+ uint32_t Global) {
+ Mappings[Local] = Global;
+}
+
+uint32_t DebugCrossModuleExportsSubsection::calculateSerializedSize() const {
+ return Mappings.size() * sizeof(CrossModuleExport);
+}
+
+Error DebugCrossModuleExportsSubsection::commit(
+ BinaryStreamWriter &Writer) const {
+ for (const auto &M : Mappings) {
+ if (auto EC = Writer.writeInteger(M.first))
+ return EC;
+ if (auto EC = Writer.writeInteger(M.second))
+ return EC;
+ }
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
index dbadafd3aa..58b479ae16 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugCrossImpSubsection.cpp
@@ -1,96 +1,96 @@
-//===- DebugCrossImpSubsection.cpp ----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-#include <utility>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error VarStreamArrayExtractor<CrossModuleImportItem>::
-operator()(BinaryStreamRef Stream, uint32_t &Len,
- codeview::CrossModuleImportItem &Item) {
- BinaryStreamReader Reader(Stream);
- if (Reader.bytesRemaining() < sizeof(CrossModuleImport))
- return make_error<CodeViewError>(
- cv_error_code::insufficient_buffer,
- "Not enough bytes for a Cross Module Import Header!");
- if (auto EC = Reader.readObject(Item.Header))
- return EC;
- if (Reader.bytesRemaining() < Item.Header->Count * sizeof(uint32_t))
- return make_error<CodeViewError>(
- cv_error_code::insufficient_buffer,
- "Not enough to read specified number of Cross Module References!");
- if (auto EC = Reader.readArray(Item.Imports, Item.Header->Count))
- return EC;
- return Error::success();
-}
-
-Error DebugCrossModuleImportsSubsectionRef::initialize(
- BinaryStreamReader Reader) {
- return Reader.readArray(References, Reader.bytesRemaining());
-}
-
-Error DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream) {
- BinaryStreamReader Reader(Stream);
- return initialize(Reader);
-}
-
-void DebugCrossModuleImportsSubsection::addImport(StringRef Module,
- uint32_t ImportId) {
- Strings.insert(Module);
- std::vector<support::ulittle32_t> Targets = {support::ulittle32_t(ImportId)};
- auto Result = Mappings.insert(std::make_pair(Module, Targets));
- if (!Result.second)
- Result.first->getValue().push_back(Targets[0]);
-}
-
-uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const {
- uint32_t Size = 0;
- for (const auto &Item : Mappings) {
- Size += sizeof(CrossModuleImport);
- Size += sizeof(support::ulittle32_t) * Item.second.size();
- }
- return Size;
-}
-
-Error DebugCrossModuleImportsSubsection::commit(
- BinaryStreamWriter &Writer) const {
- using T = decltype(&*Mappings.begin());
- std::vector<T> Ids;
- Ids.reserve(Mappings.size());
-
- for (const auto &M : Mappings)
- Ids.push_back(&M);
-
- llvm::sort(Ids, [this](const T &L1, const T &L2) {
- return Strings.getIdForString(L1->getKey()) <
- Strings.getIdForString(L2->getKey());
- });
-
- for (const auto &Item : Ids) {
- CrossModuleImport Imp;
- Imp.ModuleNameOffset = Strings.getIdForString(Item->getKey());
- Imp.Count = Item->getValue().size();
- if (auto EC = Writer.writeObject(Imp))
- return EC;
- if (auto EC = Writer.writeArray(makeArrayRef(Item->getValue())))
- return EC;
- }
- return Error::success();
-}
+//===- DebugCrossImpSubsection.cpp ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error VarStreamArrayExtractor<CrossModuleImportItem>::
+operator()(BinaryStreamRef Stream, uint32_t &Len,
+ codeview::CrossModuleImportItem &Item) {
+ BinaryStreamReader Reader(Stream);
+ if (Reader.bytesRemaining() < sizeof(CrossModuleImport))
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Not enough bytes for a Cross Module Import Header!");
+ if (auto EC = Reader.readObject(Item.Header))
+ return EC;
+ if (Reader.bytesRemaining() < Item.Header->Count * sizeof(uint32_t))
+ return make_error<CodeViewError>(
+ cv_error_code::insufficient_buffer,
+ "Not enough to read specified number of Cross Module References!");
+ if (auto EC = Reader.readArray(Item.Imports, Item.Header->Count))
+ return EC;
+ return Error::success();
+}
+
+Error DebugCrossModuleImportsSubsectionRef::initialize(
+ BinaryStreamReader Reader) {
+ return Reader.readArray(References, Reader.bytesRemaining());
+}
+
+Error DebugCrossModuleImportsSubsectionRef::initialize(BinaryStreamRef Stream) {
+ BinaryStreamReader Reader(Stream);
+ return initialize(Reader);
+}
+
+void DebugCrossModuleImportsSubsection::addImport(StringRef Module,
+ uint32_t ImportId) {
+ Strings.insert(Module);
+ std::vector<support::ulittle32_t> Targets = {support::ulittle32_t(ImportId)};
+ auto Result = Mappings.insert(std::make_pair(Module, Targets));
+ if (!Result.second)
+ Result.first->getValue().push_back(Targets[0]);
+}
+
+uint32_t DebugCrossModuleImportsSubsection::calculateSerializedSize() const {
+ uint32_t Size = 0;
+ for (const auto &Item : Mappings) {
+ Size += sizeof(CrossModuleImport);
+ Size += sizeof(support::ulittle32_t) * Item.second.size();
+ }
+ return Size;
+}
+
+Error DebugCrossModuleImportsSubsection::commit(
+ BinaryStreamWriter &Writer) const {
+ using T = decltype(&*Mappings.begin());
+ std::vector<T> Ids;
+ Ids.reserve(Mappings.size());
+
+ for (const auto &M : Mappings)
+ Ids.push_back(&M);
+
+ llvm::sort(Ids, [this](const T &L1, const T &L2) {
+ return Strings.getIdForString(L1->getKey()) <
+ Strings.getIdForString(L2->getKey());
+ });
+
+ for (const auto &Item : Ids) {
+ CrossModuleImport Imp;
+ Imp.ModuleNameOffset = Strings.getIdForString(Item->getKey());
+ Imp.Count = Item->getValue().size();
+ if (auto EC = Writer.writeObject(Imp))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(Item->getValue())))
+ return EC;
+ }
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
index 9bc69abea1..1da20b8144 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugFrameDataSubsection.cpp
@@ -1,60 +1,60 @@
-//===- DebugFrameDataSubsection.cpp -----------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) {
- if (Reader.bytesRemaining() % sizeof(FrameData) != 0) {
- if (auto EC = Reader.readObject(RelocPtr))
- return EC;
- }
-
- if (Reader.bytesRemaining() % sizeof(FrameData) != 0)
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid frame data record format!");
-
- uint32_t Count = Reader.bytesRemaining() / sizeof(FrameData);
- if (auto EC = Reader.readArray(Frames, Count))
- return EC;
- return Error::success();
-}
-
-Error DebugFrameDataSubsectionRef::initialize(BinaryStreamRef Section) {
- BinaryStreamReader Reader(Section);
- return initialize(Reader);
-}
-
-uint32_t DebugFrameDataSubsection::calculateSerializedSize() const {
- uint32_t Size = sizeof(FrameData) * Frames.size();
- if (IncludeRelocPtr)
- Size += sizeof(uint32_t);
- return Size;
-}
-
-Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const {
- if (IncludeRelocPtr) {
- if (auto EC = Writer.writeInteger<uint32_t>(0))
- return EC;
- }
-
- std::vector<FrameData> SortedFrames(Frames.begin(), Frames.end());
+//===- DebugFrameDataSubsection.cpp -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error DebugFrameDataSubsectionRef::initialize(BinaryStreamReader Reader) {
+ if (Reader.bytesRemaining() % sizeof(FrameData) != 0) {
+ if (auto EC = Reader.readObject(RelocPtr))
+ return EC;
+ }
+
+ if (Reader.bytesRemaining() % sizeof(FrameData) != 0)
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid frame data record format!");
+
+ uint32_t Count = Reader.bytesRemaining() / sizeof(FrameData);
+ if (auto EC = Reader.readArray(Frames, Count))
+ return EC;
+ return Error::success();
+}
+
+Error DebugFrameDataSubsectionRef::initialize(BinaryStreamRef Section) {
+ BinaryStreamReader Reader(Section);
+ return initialize(Reader);
+}
+
+uint32_t DebugFrameDataSubsection::calculateSerializedSize() const {
+ uint32_t Size = sizeof(FrameData) * Frames.size();
+ if (IncludeRelocPtr)
+ Size += sizeof(uint32_t);
+ return Size;
+}
+
+Error DebugFrameDataSubsection::commit(BinaryStreamWriter &Writer) const {
+ if (IncludeRelocPtr) {
+ if (auto EC = Writer.writeInteger<uint32_t>(0))
+ return EC;
+ }
+
+ std::vector<FrameData> SortedFrames(Frames.begin(), Frames.end());
llvm::sort(SortedFrames, [](const FrameData &LHS, const FrameData &RHS) {
return LHS.RvaStart < RHS.RvaStart;
});
- if (auto EC = Writer.writeArray(makeArrayRef(SortedFrames)))
- return EC;
- return Error::success();
-}
-
-void DebugFrameDataSubsection::addFrameData(const FrameData &Frame) {
- Frames.push_back(Frame);
-}
+ if (auto EC = Writer.writeArray(makeArrayRef(SortedFrames)))
+ return EC;
+ return Error::success();
+}
+
+void DebugFrameDataSubsection::addFrameData(const FrameData &Frame) {
+ Frames.push_back(Frame);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp
index 48ec7e4ecd..4893b3fab7 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugInlineeLinesSubsection.cpp
@@ -1,125 +1,125 @@
-//===- DebugInlineeLinesSubsection.cpp ------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error VarStreamArrayExtractor<InlineeSourceLine>::
-operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) {
- BinaryStreamReader Reader(Stream);
-
- if (auto EC = Reader.readObject(Item.Header))
- return EC;
-
- if (HasExtraFiles) {
- uint32_t ExtraFileCount;
- if (auto EC = Reader.readInteger(ExtraFileCount))
- return EC;
- if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
- return EC;
- }
-
- Len = Reader.getOffset();
- return Error::success();
-}
-
-DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
- : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
-
-Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
- if (auto EC = Reader.readEnum(Signature))
- return EC;
-
- Lines.getExtractor().HasExtraFiles = hasExtraFiles();
- if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining()))
- return EC;
-
- assert(Reader.bytesRemaining() == 0);
- return Error::success();
-}
-
-bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
- return Signature == InlineeLinesSignature::ExtraFiles;
-}
-
-DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
- DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
- : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
- HasExtraFiles(HasExtraFiles) {}
-
-uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
- // 4 bytes for the signature
- uint32_t Size = sizeof(InlineeLinesSignature);
-
- // one header for each entry.
- Size += Entries.size() * sizeof(InlineeSourceLineHeader);
- if (HasExtraFiles) {
- // If extra files are enabled, one count for each entry.
- Size += Entries.size() * sizeof(uint32_t);
-
- // And one file id for each file.
- Size += ExtraFileCount * sizeof(uint32_t);
- }
- assert(Size % 4 == 0);
- return Size;
-}
-
-Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
- InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
- if (HasExtraFiles)
- Sig = InlineeLinesSignature::ExtraFiles;
-
- if (auto EC = Writer.writeEnum(Sig))
- return EC;
-
- for (const auto &E : Entries) {
- if (auto EC = Writer.writeObject(E.Header))
- return EC;
-
- if (!HasExtraFiles)
- continue;
-
- if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
- return EC;
- if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
- return EC;
- }
-
- return Error::success();
-}
-
-void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
- uint32_t Offset = Checksums.mapChecksumOffset(FileName);
-
- auto &Entry = Entries.back();
- Entry.ExtraFiles.push_back(ulittle32_t(Offset));
- ++ExtraFileCount;
-}
-
-void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
- StringRef FileName,
- uint32_t SourceLine) {
- uint32_t Offset = Checksums.mapChecksumOffset(FileName);
-
- Entries.emplace_back();
- auto &Entry = Entries.back();
- Entry.Header.FileID = Offset;
- Entry.Header.SourceLineNum = SourceLine;
- Entry.Header.Inlinee = FuncId;
-}
+//===- DebugInlineeLinesSubsection.cpp ------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error VarStreamArrayExtractor<InlineeSourceLine>::
+operator()(BinaryStreamRef Stream, uint32_t &Len, InlineeSourceLine &Item) {
+ BinaryStreamReader Reader(Stream);
+
+ if (auto EC = Reader.readObject(Item.Header))
+ return EC;
+
+ if (HasExtraFiles) {
+ uint32_t ExtraFileCount;
+ if (auto EC = Reader.readInteger(ExtraFileCount))
+ return EC;
+ if (auto EC = Reader.readArray(Item.ExtraFiles, ExtraFileCount))
+ return EC;
+ }
+
+ Len = Reader.getOffset();
+ return Error::success();
+}
+
+DebugInlineeLinesSubsectionRef::DebugInlineeLinesSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::InlineeLines) {}
+
+Error DebugInlineeLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
+ if (auto EC = Reader.readEnum(Signature))
+ return EC;
+
+ Lines.getExtractor().HasExtraFiles = hasExtraFiles();
+ if (auto EC = Reader.readArray(Lines, Reader.bytesRemaining()))
+ return EC;
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+bool DebugInlineeLinesSubsectionRef::hasExtraFiles() const {
+ return Signature == InlineeLinesSignature::ExtraFiles;
+}
+
+DebugInlineeLinesSubsection::DebugInlineeLinesSubsection(
+ DebugChecksumsSubsection &Checksums, bool HasExtraFiles)
+ : DebugSubsection(DebugSubsectionKind::InlineeLines), Checksums(Checksums),
+ HasExtraFiles(HasExtraFiles) {}
+
+uint32_t DebugInlineeLinesSubsection::calculateSerializedSize() const {
+ // 4 bytes for the signature
+ uint32_t Size = sizeof(InlineeLinesSignature);
+
+ // one header for each entry.
+ Size += Entries.size() * sizeof(InlineeSourceLineHeader);
+ if (HasExtraFiles) {
+ // If extra files are enabled, one count for each entry.
+ Size += Entries.size() * sizeof(uint32_t);
+
+ // And one file id for each file.
+ Size += ExtraFileCount * sizeof(uint32_t);
+ }
+ assert(Size % 4 == 0);
+ return Size;
+}
+
+Error DebugInlineeLinesSubsection::commit(BinaryStreamWriter &Writer) const {
+ InlineeLinesSignature Sig = InlineeLinesSignature::Normal;
+ if (HasExtraFiles)
+ Sig = InlineeLinesSignature::ExtraFiles;
+
+ if (auto EC = Writer.writeEnum(Sig))
+ return EC;
+
+ for (const auto &E : Entries) {
+ if (auto EC = Writer.writeObject(E.Header))
+ return EC;
+
+ if (!HasExtraFiles)
+ continue;
+
+ if (auto EC = Writer.writeInteger<uint32_t>(E.ExtraFiles.size()))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(E.ExtraFiles)))
+ return EC;
+ }
+
+ return Error::success();
+}
+
+void DebugInlineeLinesSubsection::addExtraFile(StringRef FileName) {
+ uint32_t Offset = Checksums.mapChecksumOffset(FileName);
+
+ auto &Entry = Entries.back();
+ Entry.ExtraFiles.push_back(ulittle32_t(Offset));
+ ++ExtraFileCount;
+}
+
+void DebugInlineeLinesSubsection::addInlineSite(TypeIndex FuncId,
+ StringRef FileName,
+ uint32_t SourceLine) {
+ uint32_t Offset = Checksums.mapChecksumOffset(FileName);
+
+ Entries.emplace_back();
+ auto &Entry = Entries.back();
+ Entry.Header.FileID = Offset;
+ Entry.Header.SourceLineNum = SourceLine;
+ Entry.Header.Inlinee = FuncId;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp
index ea16c0a6c6..e653d77092 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugLinesSubsection.cpp
@@ -1,160 +1,160 @@
-//===- DebugLinesSubsection.cpp -------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error LineColumnExtractor::operator()(BinaryStreamRef Stream, uint32_t &Len,
- LineColumnEntry &Item) {
- const LineBlockFragmentHeader *BlockHeader;
- BinaryStreamReader Reader(Stream);
- if (auto EC = Reader.readObject(BlockHeader))
- return EC;
- bool HasColumn = Header->Flags & uint16_t(LF_HaveColumns);
- uint32_t LineInfoSize =
- BlockHeader->NumLines *
- (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
- if (BlockHeader->BlockSize < sizeof(LineBlockFragmentHeader))
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid line block record size");
- uint32_t Size = BlockHeader->BlockSize - sizeof(LineBlockFragmentHeader);
- if (LineInfoSize > Size)
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Invalid line block record size");
- // The value recorded in BlockHeader->BlockSize includes the size of
- // LineBlockFragmentHeader.
- Len = BlockHeader->BlockSize;
- Item.NameIndex = BlockHeader->NameIndex;
- if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
- return EC;
- if (HasColumn) {
- if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
- return EC;
- }
- return Error::success();
-}
-
-DebugLinesSubsectionRef::DebugLinesSubsectionRef()
- : DebugSubsectionRef(DebugSubsectionKind::Lines) {}
-
-Error DebugLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
- if (auto EC = Reader.readObject(Header))
- return EC;
-
- LinesAndColumns.getExtractor().Header = Header;
- if (auto EC = Reader.readArray(LinesAndColumns, Reader.bytesRemaining()))
- return EC;
-
- return Error::success();
-}
-
-bool DebugLinesSubsectionRef::hasColumnInfo() const {
- return !!(Header->Flags & LF_HaveColumns);
-}
-
-DebugLinesSubsection::DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
- DebugStringTableSubsection &Strings)
- : DebugSubsection(DebugSubsectionKind::Lines), Checksums(Checksums) {}
-
-void DebugLinesSubsection::createBlock(StringRef FileName) {
- uint32_t Offset = Checksums.mapChecksumOffset(FileName);
-
- Blocks.emplace_back(Offset);
-}
-
-void DebugLinesSubsection::addLineInfo(uint32_t Offset, const LineInfo &Line) {
- Block &B = Blocks.back();
- LineNumberEntry LNE;
- LNE.Flags = Line.getRawData();
- LNE.Offset = Offset;
- B.Lines.push_back(LNE);
-}
-
-void DebugLinesSubsection::addLineAndColumnInfo(uint32_t Offset,
- const LineInfo &Line,
- uint32_t ColStart,
- uint32_t ColEnd) {
- Block &B = Blocks.back();
- assert(B.Lines.size() == B.Columns.size());
-
- addLineInfo(Offset, Line);
- ColumnNumberEntry CNE;
- CNE.StartColumn = ColStart;
- CNE.EndColumn = ColEnd;
- B.Columns.push_back(CNE);
-}
-
-Error DebugLinesSubsection::commit(BinaryStreamWriter &Writer) const {
- LineFragmentHeader Header;
- Header.CodeSize = CodeSize;
- Header.Flags = hasColumnInfo() ? LF_HaveColumns : 0;
- Header.RelocOffset = RelocOffset;
- Header.RelocSegment = RelocSegment;
-
- if (auto EC = Writer.writeObject(Header))
- return EC;
-
- for (const auto &B : Blocks) {
- LineBlockFragmentHeader BlockHeader;
- assert(B.Lines.size() == B.Columns.size() || B.Columns.empty());
-
- BlockHeader.NumLines = B.Lines.size();
- BlockHeader.BlockSize = sizeof(LineBlockFragmentHeader);
- BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(LineNumberEntry);
- if (hasColumnInfo())
- BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(ColumnNumberEntry);
- BlockHeader.NameIndex = B.ChecksumBufferOffset;
- if (auto EC = Writer.writeObject(BlockHeader))
- return EC;
-
- if (auto EC = Writer.writeArray(makeArrayRef(B.Lines)))
- return EC;
-
- if (hasColumnInfo()) {
- if (auto EC = Writer.writeArray(makeArrayRef(B.Columns)))
- return EC;
- }
- }
- return Error::success();
-}
-
-uint32_t DebugLinesSubsection::calculateSerializedSize() const {
- uint32_t Size = sizeof(LineFragmentHeader);
- for (const auto &B : Blocks) {
- Size += sizeof(LineBlockFragmentHeader);
- Size += B.Lines.size() * sizeof(LineNumberEntry);
- if (hasColumnInfo())
- Size += B.Columns.size() * sizeof(ColumnNumberEntry);
- }
- return Size;
-}
-
-void DebugLinesSubsection::setRelocationAddress(uint16_t Segment,
- uint32_t Offset) {
- RelocOffset = Offset;
- RelocSegment = Segment;
-}
-
-void DebugLinesSubsection::setCodeSize(uint32_t Size) { CodeSize = Size; }
-
-void DebugLinesSubsection::setFlags(LineFlags Flags) { this->Flags = Flags; }
-
-bool DebugLinesSubsection::hasColumnInfo() const {
- return Flags & LF_HaveColumns;
-}
+//===- DebugLinesSubsection.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error LineColumnExtractor::operator()(BinaryStreamRef Stream, uint32_t &Len,
+ LineColumnEntry &Item) {
+ const LineBlockFragmentHeader *BlockHeader;
+ BinaryStreamReader Reader(Stream);
+ if (auto EC = Reader.readObject(BlockHeader))
+ return EC;
+ bool HasColumn = Header->Flags & uint16_t(LF_HaveColumns);
+ uint32_t LineInfoSize =
+ BlockHeader->NumLines *
+ (sizeof(LineNumberEntry) + (HasColumn ? sizeof(ColumnNumberEntry) : 0));
+ if (BlockHeader->BlockSize < sizeof(LineBlockFragmentHeader))
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid line block record size");
+ uint32_t Size = BlockHeader->BlockSize - sizeof(LineBlockFragmentHeader);
+ if (LineInfoSize > Size)
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Invalid line block record size");
+ // The value recorded in BlockHeader->BlockSize includes the size of
+ // LineBlockFragmentHeader.
+ Len = BlockHeader->BlockSize;
+ Item.NameIndex = BlockHeader->NameIndex;
+ if (auto EC = Reader.readArray(Item.LineNumbers, BlockHeader->NumLines))
+ return EC;
+ if (HasColumn) {
+ if (auto EC = Reader.readArray(Item.Columns, BlockHeader->NumLines))
+ return EC;
+ }
+ return Error::success();
+}
+
+DebugLinesSubsectionRef::DebugLinesSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::Lines) {}
+
+Error DebugLinesSubsectionRef::initialize(BinaryStreamReader Reader) {
+ if (auto EC = Reader.readObject(Header))
+ return EC;
+
+ LinesAndColumns.getExtractor().Header = Header;
+ if (auto EC = Reader.readArray(LinesAndColumns, Reader.bytesRemaining()))
+ return EC;
+
+ return Error::success();
+}
+
+bool DebugLinesSubsectionRef::hasColumnInfo() const {
+ return !!(Header->Flags & LF_HaveColumns);
+}
+
+DebugLinesSubsection::DebugLinesSubsection(DebugChecksumsSubsection &Checksums,
+ DebugStringTableSubsection &Strings)
+ : DebugSubsection(DebugSubsectionKind::Lines), Checksums(Checksums) {}
+
+void DebugLinesSubsection::createBlock(StringRef FileName) {
+ uint32_t Offset = Checksums.mapChecksumOffset(FileName);
+
+ Blocks.emplace_back(Offset);
+}
+
+void DebugLinesSubsection::addLineInfo(uint32_t Offset, const LineInfo &Line) {
+ Block &B = Blocks.back();
+ LineNumberEntry LNE;
+ LNE.Flags = Line.getRawData();
+ LNE.Offset = Offset;
+ B.Lines.push_back(LNE);
+}
+
+void DebugLinesSubsection::addLineAndColumnInfo(uint32_t Offset,
+ const LineInfo &Line,
+ uint32_t ColStart,
+ uint32_t ColEnd) {
+ Block &B = Blocks.back();
+ assert(B.Lines.size() == B.Columns.size());
+
+ addLineInfo(Offset, Line);
+ ColumnNumberEntry CNE;
+ CNE.StartColumn = ColStart;
+ CNE.EndColumn = ColEnd;
+ B.Columns.push_back(CNE);
+}
+
+Error DebugLinesSubsection::commit(BinaryStreamWriter &Writer) const {
+ LineFragmentHeader Header;
+ Header.CodeSize = CodeSize;
+ Header.Flags = hasColumnInfo() ? LF_HaveColumns : 0;
+ Header.RelocOffset = RelocOffset;
+ Header.RelocSegment = RelocSegment;
+
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+
+ for (const auto &B : Blocks) {
+ LineBlockFragmentHeader BlockHeader;
+ assert(B.Lines.size() == B.Columns.size() || B.Columns.empty());
+
+ BlockHeader.NumLines = B.Lines.size();
+ BlockHeader.BlockSize = sizeof(LineBlockFragmentHeader);
+ BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(LineNumberEntry);
+ if (hasColumnInfo())
+ BlockHeader.BlockSize += BlockHeader.NumLines * sizeof(ColumnNumberEntry);
+ BlockHeader.NameIndex = B.ChecksumBufferOffset;
+ if (auto EC = Writer.writeObject(BlockHeader))
+ return EC;
+
+ if (auto EC = Writer.writeArray(makeArrayRef(B.Lines)))
+ return EC;
+
+ if (hasColumnInfo()) {
+ if (auto EC = Writer.writeArray(makeArrayRef(B.Columns)))
+ return EC;
+ }
+ }
+ return Error::success();
+}
+
+uint32_t DebugLinesSubsection::calculateSerializedSize() const {
+ uint32_t Size = sizeof(LineFragmentHeader);
+ for (const auto &B : Blocks) {
+ Size += sizeof(LineBlockFragmentHeader);
+ Size += B.Lines.size() * sizeof(LineNumberEntry);
+ if (hasColumnInfo())
+ Size += B.Columns.size() * sizeof(ColumnNumberEntry);
+ }
+ return Size;
+}
+
+void DebugLinesSubsection::setRelocationAddress(uint16_t Segment,
+ uint32_t Offset) {
+ RelocOffset = Offset;
+ RelocSegment = Segment;
+}
+
+void DebugLinesSubsection::setCodeSize(uint32_t Size) { CodeSize = Size; }
+
+void DebugLinesSubsection::setFlags(LineFlags Flags) { this->Flags = Flags; }
+
+bool DebugLinesSubsection::hasColumnInfo() const {
+ return Flags & LF_HaveColumns;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
index 6334274991..205678c500 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugStringTableSubsection.cpp
@@ -1,107 +1,107 @@
-//===- DebugStringTableSubsection.cpp - CodeView String Table -------------===//
-//
-// 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/DebugStringTableSubsection.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
- : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
-
-Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
- Stream = Contents;
- return Error::success();
-}
-
-Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {
- return Reader.readStreamRef(Stream);
-}
-
-Expected<StringRef>
-DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
- BinaryStreamReader Reader(Stream);
- Reader.setOffset(Offset);
- StringRef Result;
- if (auto EC = Reader.readCString(Result))
- return std::move(EC);
- return Result;
-}
-
-DebugStringTableSubsection::DebugStringTableSubsection()
- : DebugSubsection(DebugSubsectionKind::StringTable) {}
-
-uint32_t DebugStringTableSubsection::insert(StringRef S) {
- auto P = StringToId.insert({S, StringSize});
-
- // If a given string didn't exist in the string table, we want to increment
- // the string table size and insert it into the reverse lookup.
- if (P.second) {
- IdToString.insert({P.first->getValue(), P.first->getKey()});
- StringSize += S.size() + 1; // +1 for '\0'
- }
-
- return P.first->second;
-}
-
-uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
- return StringSize;
-}
-
-Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
- uint32_t Begin = Writer.getOffset();
- uint32_t End = Begin + StringSize;
-
- // Write a null string at the beginning.
- if (auto EC = Writer.writeCString(StringRef()))
- return EC;
-
- for (auto &Pair : StringToId) {
- StringRef S = Pair.getKey();
- uint32_t Offset = Begin + Pair.getValue();
- Writer.setOffset(Offset);
- if (auto EC = Writer.writeCString(S))
- return EC;
- assert(Writer.getOffset() <= End);
- }
-
- Writer.setOffset(End);
- assert((End - Begin) == StringSize);
- return Error::success();
-}
-
-uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }
-
-std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const {
- std::vector<uint32_t> Result;
- Result.reserve(IdToString.size());
- for (const auto &Entry : IdToString)
- Result.push_back(Entry.first);
- llvm::sort(Result);
- return Result;
-}
-
-uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {
- auto Iter = StringToId.find(S);
- assert(Iter != StringToId.end());
- return Iter->second;
-}
-
-StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const {
- auto Iter = IdToString.find(Id);
- assert(Iter != IdToString.end());
- return Iter->second;
-}
+//===- DebugStringTableSubsection.cpp - CodeView String Table -------------===//
+//
+// 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/DebugStringTableSubsection.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+DebugStringTableSubsectionRef::DebugStringTableSubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::StringTable) {}
+
+Error DebugStringTableSubsectionRef::initialize(BinaryStreamRef Contents) {
+ Stream = Contents;
+ return Error::success();
+}
+
+Error DebugStringTableSubsectionRef::initialize(BinaryStreamReader &Reader) {
+ return Reader.readStreamRef(Stream);
+}
+
+Expected<StringRef>
+DebugStringTableSubsectionRef::getString(uint32_t Offset) const {
+ BinaryStreamReader Reader(Stream);
+ Reader.setOffset(Offset);
+ StringRef Result;
+ if (auto EC = Reader.readCString(Result))
+ return std::move(EC);
+ return Result;
+}
+
+DebugStringTableSubsection::DebugStringTableSubsection()
+ : DebugSubsection(DebugSubsectionKind::StringTable) {}
+
+uint32_t DebugStringTableSubsection::insert(StringRef S) {
+ auto P = StringToId.insert({S, StringSize});
+
+ // If a given string didn't exist in the string table, we want to increment
+ // the string table size and insert it into the reverse lookup.
+ if (P.second) {
+ IdToString.insert({P.first->getValue(), P.first->getKey()});
+ StringSize += S.size() + 1; // +1 for '\0'
+ }
+
+ return P.first->second;
+}
+
+uint32_t DebugStringTableSubsection::calculateSerializedSize() const {
+ return StringSize;
+}
+
+Error DebugStringTableSubsection::commit(BinaryStreamWriter &Writer) const {
+ uint32_t Begin = Writer.getOffset();
+ uint32_t End = Begin + StringSize;
+
+ // Write a null string at the beginning.
+ if (auto EC = Writer.writeCString(StringRef()))
+ return EC;
+
+ for (auto &Pair : StringToId) {
+ StringRef S = Pair.getKey();
+ uint32_t Offset = Begin + Pair.getValue();
+ Writer.setOffset(Offset);
+ if (auto EC = Writer.writeCString(S))
+ return EC;
+ assert(Writer.getOffset() <= End);
+ }
+
+ Writer.setOffset(End);
+ assert((End - Begin) == StringSize);
+ return Error::success();
+}
+
+uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }
+
+std::vector<uint32_t> DebugStringTableSubsection::sortedIds() const {
+ std::vector<uint32_t> Result;
+ Result.reserve(IdToString.size());
+ for (const auto &Entry : IdToString)
+ Result.push_back(Entry.first);
+ llvm::sort(Result);
+ return Result;
+}
+
+uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {
+ auto Iter = StringToId.find(S);
+ assert(Iter != StringToId.end());
+ return Iter->second;
+}
+
+StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const {
+ auto Iter = IdToString.find(Id);
+ assert(Iter != IdToString.end());
+ return Iter->second;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsection.cpp
index 3f93463fe6..484afa6653 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsection.cpp
@@ -1,15 +1,15 @@
-//===- DebugSubsection.cpp -----------------------------------*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
-
-using namespace llvm::codeview;
-
-DebugSubsectionRef::~DebugSubsectionRef() {}
-
-DebugSubsection::~DebugSubsection() {}
+//===- DebugSubsection.cpp -----------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+
+using namespace llvm::codeview;
+
+DebugSubsectionRef::~DebugSubsectionRef() {}
+
+DebugSubsection::~DebugSubsection() {}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
index 3c8a301014..9070125d82 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionRecord.cpp
@@ -1,94 +1,94 @@
-//===- DebugSubsectionRecord.cpp ------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-DebugSubsectionRecord::DebugSubsectionRecord() = default;
-
-DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind,
- BinaryStreamRef Data)
- : Kind(Kind), Data(Data) {}
-
-Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream,
- DebugSubsectionRecord &Info) {
- const DebugSubsectionHeader *Header;
- BinaryStreamReader Reader(Stream);
- if (auto EC = Reader.readObject(Header))
- return EC;
-
- DebugSubsectionKind Kind =
- static_cast<DebugSubsectionKind>(uint32_t(Header->Kind));
- if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
- return EC;
- Info.Kind = Kind;
- return Error::success();
-}
-
-uint32_t DebugSubsectionRecord::getRecordLength() const {
- return sizeof(DebugSubsectionHeader) + Data.getLength();
-}
-
-DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; }
-
-BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
-
-DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
- std::shared_ptr<DebugSubsection> Subsection)
- : Subsection(std::move(Subsection)) {}
-
-DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
- const DebugSubsectionRecord &Contents)
- : Contents(Contents) {}
-
-uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() const {
- uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
- : Contents.getRecordData().getLength();
- // The length of the entire subsection is always padded to 4 bytes,
- // regardless of the container kind.
- return sizeof(DebugSubsectionHeader) + alignTo(DataSize, 4);
-}
-
-Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer,
- CodeViewContainer Container) const {
- assert(Writer.getOffset() % alignOf(Container) == 0 &&
- "Debug Subsection not properly aligned");
-
- DebugSubsectionHeader Header;
- Header.Kind = uint32_t(Subsection ? Subsection->kind() : Contents.kind());
- // The value written into the Header's Length field is only padded to the
- // container's alignment
- uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
- : Contents.getRecordData().getLength();
- Header.Length = alignTo(DataSize, alignOf(Container));
-
- if (auto EC = Writer.writeObject(Header))
- return EC;
- if (Subsection) {
- if (auto EC = Subsection->commit(Writer))
- return EC;
- } else {
- if (auto EC = Writer.writeStreamRef(Contents.getRecordData()))
- return EC;
- }
- if (auto EC = Writer.padToAlignment(4))
- return EC;
-
- return Error::success();
-}
+//===- DebugSubsectionRecord.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+DebugSubsectionRecord::DebugSubsectionRecord() = default;
+
+DebugSubsectionRecord::DebugSubsectionRecord(DebugSubsectionKind Kind,
+ BinaryStreamRef Data)
+ : Kind(Kind), Data(Data) {}
+
+Error DebugSubsectionRecord::initialize(BinaryStreamRef Stream,
+ DebugSubsectionRecord &Info) {
+ const DebugSubsectionHeader *Header;
+ BinaryStreamReader Reader(Stream);
+ if (auto EC = Reader.readObject(Header))
+ return EC;
+
+ DebugSubsectionKind Kind =
+ static_cast<DebugSubsectionKind>(uint32_t(Header->Kind));
+ if (auto EC = Reader.readStreamRef(Info.Data, Header->Length))
+ return EC;
+ Info.Kind = Kind;
+ return Error::success();
+}
+
+uint32_t DebugSubsectionRecord::getRecordLength() const {
+ return sizeof(DebugSubsectionHeader) + Data.getLength();
+}
+
+DebugSubsectionKind DebugSubsectionRecord::kind() const { return Kind; }
+
+BinaryStreamRef DebugSubsectionRecord::getRecordData() const { return Data; }
+
+DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
+ std::shared_ptr<DebugSubsection> Subsection)
+ : Subsection(std::move(Subsection)) {}
+
+DebugSubsectionRecordBuilder::DebugSubsectionRecordBuilder(
+ const DebugSubsectionRecord &Contents)
+ : Contents(Contents) {}
+
+uint32_t DebugSubsectionRecordBuilder::calculateSerializedLength() const {
+ uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
+ : Contents.getRecordData().getLength();
+ // The length of the entire subsection is always padded to 4 bytes,
+ // regardless of the container kind.
+ return sizeof(DebugSubsectionHeader) + alignTo(DataSize, 4);
+}
+
+Error DebugSubsectionRecordBuilder::commit(BinaryStreamWriter &Writer,
+ CodeViewContainer Container) const {
+ assert(Writer.getOffset() % alignOf(Container) == 0 &&
+ "Debug Subsection not properly aligned");
+
+ DebugSubsectionHeader Header;
+ Header.Kind = uint32_t(Subsection ? Subsection->kind() : Contents.kind());
+ // The value written into the Header's Length field is only padded to the
+ // container's alignment
+ uint32_t DataSize = Subsection ? Subsection->calculateSerializedSize()
+ : Contents.getRecordData().getLength();
+ Header.Length = alignTo(DataSize, alignOf(Container));
+
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+ if (Subsection) {
+ if (auto EC = Subsection->commit(Writer))
+ return EC;
+ } else {
+ if (auto EC = Writer.writeStreamRef(Contents.getRecordData()))
+ return EC;
+ }
+ if (auto EC = Writer.padToAlignment(4))
+ return EC;
+
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
index 7968b6a2d7..b6c46fe4cc 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSubsectionVisitor.cpp
@@ -1,94 +1,94 @@
-//===- DebugSubsectionVisitor.cpp -------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
-
-#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
-#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamRef.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error llvm::codeview::visitDebugSubsection(
- const DebugSubsectionRecord &R, DebugSubsectionVisitor &V,
- const StringsAndChecksumsRef &State) {
- BinaryStreamReader Reader(R.getRecordData());
- switch (R.kind()) {
- case DebugSubsectionKind::Lines: {
- DebugLinesSubsectionRef Fragment;
- if (auto EC = Fragment.initialize(Reader))
- return EC;
-
- return V.visitLines(Fragment, State);
- }
- case DebugSubsectionKind::FileChecksums: {
- DebugChecksumsSubsectionRef Fragment;
- if (auto EC = Fragment.initialize(Reader))
- return EC;
-
- return V.visitFileChecksums(Fragment, State);
- }
- case DebugSubsectionKind::InlineeLines: {
- DebugInlineeLinesSubsectionRef Fragment;
- if (auto EC = Fragment.initialize(Reader))
- return EC;
- return V.visitInlineeLines(Fragment, State);
- }
- case DebugSubsectionKind::CrossScopeExports: {
- DebugCrossModuleExportsSubsectionRef Section;
- if (auto EC = Section.initialize(Reader))
- return EC;
- return V.visitCrossModuleExports(Section, State);
- }
- case DebugSubsectionKind::CrossScopeImports: {
- DebugCrossModuleImportsSubsectionRef Section;
- if (auto EC = Section.initialize(Reader))
- return EC;
- return V.visitCrossModuleImports(Section, State);
- }
- case DebugSubsectionKind::Symbols: {
- DebugSymbolsSubsectionRef Section;
- if (auto EC = Section.initialize(Reader))
- return EC;
- return V.visitSymbols(Section, State);
- }
- case DebugSubsectionKind::StringTable: {
- DebugStringTableSubsectionRef Section;
- if (auto EC = Section.initialize(Reader))
- return EC;
- return V.visitStringTable(Section, State);
- }
- case DebugSubsectionKind::FrameData: {
- DebugFrameDataSubsectionRef Section;
- if (auto EC = Section.initialize(Reader))
- return EC;
- return V.visitFrameData(Section, State);
- }
- case DebugSubsectionKind::CoffSymbolRVA: {
- DebugSymbolRVASubsectionRef Section;
- if (auto EC = Section.initialize(Reader))
- return EC;
- return V.visitCOFFSymbolRVAs(Section, State);
- }
- default: {
- DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
- return V.visitUnknown(Fragment);
- }
- }
-}
+//===- DebugSubsectionVisitor.cpp -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
+
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugCrossExSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugCrossImpSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugUnknownSubsection.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error llvm::codeview::visitDebugSubsection(
+ const DebugSubsectionRecord &R, DebugSubsectionVisitor &V,
+ const StringsAndChecksumsRef &State) {
+ BinaryStreamReader Reader(R.getRecordData());
+ switch (R.kind()) {
+ case DebugSubsectionKind::Lines: {
+ DebugLinesSubsectionRef Fragment;
+ if (auto EC = Fragment.initialize(Reader))
+ return EC;
+
+ return V.visitLines(Fragment, State);
+ }
+ case DebugSubsectionKind::FileChecksums: {
+ DebugChecksumsSubsectionRef Fragment;
+ if (auto EC = Fragment.initialize(Reader))
+ return EC;
+
+ return V.visitFileChecksums(Fragment, State);
+ }
+ case DebugSubsectionKind::InlineeLines: {
+ DebugInlineeLinesSubsectionRef Fragment;
+ if (auto EC = Fragment.initialize(Reader))
+ return EC;
+ return V.visitInlineeLines(Fragment, State);
+ }
+ case DebugSubsectionKind::CrossScopeExports: {
+ DebugCrossModuleExportsSubsectionRef Section;
+ if (auto EC = Section.initialize(Reader))
+ return EC;
+ return V.visitCrossModuleExports(Section, State);
+ }
+ case DebugSubsectionKind::CrossScopeImports: {
+ DebugCrossModuleImportsSubsectionRef Section;
+ if (auto EC = Section.initialize(Reader))
+ return EC;
+ return V.visitCrossModuleImports(Section, State);
+ }
+ case DebugSubsectionKind::Symbols: {
+ DebugSymbolsSubsectionRef Section;
+ if (auto EC = Section.initialize(Reader))
+ return EC;
+ return V.visitSymbols(Section, State);
+ }
+ case DebugSubsectionKind::StringTable: {
+ DebugStringTableSubsectionRef Section;
+ if (auto EC = Section.initialize(Reader))
+ return EC;
+ return V.visitStringTable(Section, State);
+ }
+ case DebugSubsectionKind::FrameData: {
+ DebugFrameDataSubsectionRef Section;
+ if (auto EC = Section.initialize(Reader))
+ return EC;
+ return V.visitFrameData(Section, State);
+ }
+ case DebugSubsectionKind::CoffSymbolRVA: {
+ DebugSymbolRVASubsectionRef Section;
+ if (auto EC = Section.initialize(Reader))
+ return EC;
+ return V.visitCOFFSymbolRVAs(Section, State);
+ }
+ default: {
+ DebugUnknownSubsectionRef Fragment(R.kind(), R.getRecordData());
+ return V.visitUnknown(Fragment);
+ }
+ }
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp
index 5232896735..eb5c4129fe 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolRVASubsection.cpp
@@ -1,35 +1,35 @@
-//===- DebugSymbolRVASubsection.cpp ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-DebugSymbolRVASubsectionRef::DebugSymbolRVASubsectionRef()
- : DebugSubsectionRef(DebugSubsectionKind::CoffSymbolRVA) {}
-
-Error DebugSymbolRVASubsectionRef::initialize(BinaryStreamReader &Reader) {
- return Reader.readArray(RVAs, Reader.bytesRemaining() / sizeof(uint32_t));
-}
-
-DebugSymbolRVASubsection::DebugSymbolRVASubsection()
- : DebugSubsection(DebugSubsectionKind::CoffSymbolRVA) {}
-
-Error DebugSymbolRVASubsection::commit(BinaryStreamWriter &Writer) const {
- return Writer.writeArray(makeArrayRef(RVAs));
-}
-
-uint32_t DebugSymbolRVASubsection::calculateSerializedSize() const {
- return RVAs.size() * sizeof(uint32_t);
-}
+//===- DebugSymbolRVASubsection.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugSymbolRVASubsection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+DebugSymbolRVASubsectionRef::DebugSymbolRVASubsectionRef()
+ : DebugSubsectionRef(DebugSubsectionKind::CoffSymbolRVA) {}
+
+Error DebugSymbolRVASubsectionRef::initialize(BinaryStreamReader &Reader) {
+ return Reader.readArray(RVAs, Reader.bytesRemaining() / sizeof(uint32_t));
+}
+
+DebugSymbolRVASubsection::DebugSymbolRVASubsection()
+ : DebugSubsection(DebugSubsectionKind::CoffSymbolRVA) {}
+
+Error DebugSymbolRVASubsection::commit(BinaryStreamWriter &Writer) const {
+ return Writer.writeArray(makeArrayRef(RVAs));
+}
+
+uint32_t DebugSymbolRVASubsection::calculateSerializedSize() const {
+ return RVAs.size() * sizeof(uint32_t);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp
index c833103663..0719ebff7e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/DebugSymbolsSubsection.cpp
@@ -1,33 +1,33 @@
-//===- DebugSymbolsSubsection.cpp -------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-Error DebugSymbolsSubsectionRef::initialize(BinaryStreamReader Reader) {
- return Reader.readArray(Records, Reader.getLength());
-}
-
-uint32_t DebugSymbolsSubsection::calculateSerializedSize() const {
- return Length;
-}
-
-Error DebugSymbolsSubsection::commit(BinaryStreamWriter &Writer) const {
- for (const auto &Record : Records) {
- if (auto EC = Writer.writeBytes(Record.RecordData))
- return EC;
- }
- return Error::success();
-}
-
-void DebugSymbolsSubsection::addSymbol(CVSymbol Symbol) {
- Records.push_back(Symbol);
- Length += Symbol.length();
-}
+//===- DebugSymbolsSubsection.cpp -------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/DebugSymbolsSubsection.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+Error DebugSymbolsSubsectionRef::initialize(BinaryStreamReader Reader) {
+ return Reader.readArray(Records, Reader.getLength());
+}
+
+uint32_t DebugSymbolsSubsection::calculateSerializedSize() const {
+ return Length;
+}
+
+Error DebugSymbolsSubsection::commit(BinaryStreamWriter &Writer) const {
+ for (const auto &Record : Records) {
+ if (auto EC = Writer.writeBytes(Record.RecordData))
+ return EC;
+ }
+ return Error::success();
+}
+
+void DebugSymbolsSubsection::addSymbol(CVSymbol Symbol) {
+ Records.push_back(Symbol);
+ Length += Symbol.length();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp
index 949707bf54..62e84f9769 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/EnumTables.cpp
@@ -1,44 +1,44 @@
-//===- EnumTables.cpp - Enum to string conversion tables ------------------===//
-//
-// 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/EnumTables.h"
-#include "llvm/Support/ScopedPrinter.h"
-#include <type_traits>
-
-using namespace llvm;
-using namespace codeview;
-
-#define CV_ENUM_CLASS_ENT(enum_class, enum) \
- { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
-
-#define CV_ENUM_ENT(ns, enum) \
- { #enum, ns::enum }
-
-static const EnumEntry<SymbolKind> SymbolTypeNames[] = {
-#define CV_SYMBOL(enum, val) {#enum, enum},
-#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
-#undef CV_SYMBOL
-};
-
-static const EnumEntry<TypeLeafKind> TypeLeafNames[] = {
-#define CV_TYPE(name, val) {#name, name},
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
-#undef CV_TYPE
-};
-
-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
-};
-
+//===- EnumTables.cpp - Enum to string conversion tables ------------------===//
+//
+// 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/EnumTables.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include <type_traits>
+
+using namespace llvm;
+using namespace codeview;
+
+#define CV_ENUM_CLASS_ENT(enum_class, enum) \
+ { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
+
+#define CV_ENUM_ENT(ns, enum) \
+ { #enum, ns::enum }
+
+static const EnumEntry<SymbolKind> SymbolTypeNames[] = {
+#define CV_SYMBOL(enum, val) {#enum, enum},
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
+#undef CV_SYMBOL
+};
+
+static const EnumEntry<TypeLeafKind> TypeLeafNames[] = {
+#define CV_TYPE(name, val) {#name, name},
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+#undef CV_TYPE
+};
+
+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_ARM[] = {
#define CV_REGISTERS_ARM
#define CV_REGISTER(name, val) CV_ENUM_CLASS_ENT(RegisterId, name),
@@ -47,513 +47,513 @@ static const EnumEntry<uint16_t> RegisterNames_ARM[] = {
#undef CV_REGISTERS_ARM
};
-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[] = {
- CV_ENUM_CLASS_ENT(PublicSymFlags, Code),
- CV_ENUM_CLASS_ENT(PublicSymFlags, Function),
- CV_ENUM_CLASS_ENT(PublicSymFlags, Managed),
- CV_ENUM_CLASS_ENT(PublicSymFlags, MSIL),
-};
-
-static const EnumEntry<uint8_t> ProcSymFlagNames[] = {
- CV_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
- CV_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
- CV_ENUM_CLASS_ENT(ProcSymFlags, HasFRET),
- CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn),
- CV_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable),
- CV_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv),
- CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline),
- CV_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
-};
-
-static const EnumEntry<uint16_t> LocalFlags[] = {
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
- CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
-};
-
-static const EnumEntry<uint8_t> FrameCookieKinds[] = {
- CV_ENUM_CLASS_ENT(FrameCookieKind, Copy),
- CV_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
- CV_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
- CV_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
-};
-
-static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
- CV_ENUM_ENT(SourceLanguage, C), CV_ENUM_ENT(SourceLanguage, Cpp),
- CV_ENUM_ENT(SourceLanguage, Fortran), CV_ENUM_ENT(SourceLanguage, Masm),
- CV_ENUM_ENT(SourceLanguage, Pascal), CV_ENUM_ENT(SourceLanguage, Basic),
- CV_ENUM_ENT(SourceLanguage, Cobol), CV_ENUM_ENT(SourceLanguage, Link),
- CV_ENUM_ENT(SourceLanguage, Cvtres), CV_ENUM_ENT(SourceLanguage, Cvtpgd),
- CV_ENUM_ENT(SourceLanguage, CSharp), CV_ENUM_ENT(SourceLanguage, VB),
- 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[] = {
- CV_ENUM_CLASS_ENT(CompileSym2Flags, EC),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDbgInfo),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, LTCG),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDataAlign),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, ManagedPresent),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, SecurityChecks),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, HotPatch),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, CVTCIL),
- CV_ENUM_CLASS_ENT(CompileSym2Flags, MSILModule),
-};
-
-static const EnumEntry<uint32_t> CompileSym3FlagNames[] = {
- CV_ENUM_CLASS_ENT(CompileSym3Flags, EC),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
- CV_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
-};
-
-static const EnumEntry<uint32_t> FileChecksumNames[] = {
- CV_ENUM_CLASS_ENT(FileChecksumKind, None),
- CV_ENUM_CLASS_ENT(FileChecksumKind, MD5),
- CV_ENUM_CLASS_ENT(FileChecksumKind, SHA1),
- CV_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
-};
-
-static const EnumEntry<unsigned> CPUTypeNames[] = {
- CV_ENUM_CLASS_ENT(CPUType, Intel8080),
- CV_ENUM_CLASS_ENT(CPUType, Intel8086),
- CV_ENUM_CLASS_ENT(CPUType, Intel80286),
- CV_ENUM_CLASS_ENT(CPUType, Intel80386),
- CV_ENUM_CLASS_ENT(CPUType, Intel80486),
- CV_ENUM_CLASS_ENT(CPUType, Pentium),
- CV_ENUM_CLASS_ENT(CPUType, PentiumPro),
- CV_ENUM_CLASS_ENT(CPUType, Pentium3),
- CV_ENUM_CLASS_ENT(CPUType, MIPS),
- CV_ENUM_CLASS_ENT(CPUType, MIPS16),
- CV_ENUM_CLASS_ENT(CPUType, MIPS32),
- CV_ENUM_CLASS_ENT(CPUType, MIPS64),
- CV_ENUM_CLASS_ENT(CPUType, MIPSI),
- CV_ENUM_CLASS_ENT(CPUType, MIPSII),
- CV_ENUM_CLASS_ENT(CPUType, MIPSIII),
- CV_ENUM_CLASS_ENT(CPUType, MIPSIV),
- CV_ENUM_CLASS_ENT(CPUType, MIPSV),
- CV_ENUM_CLASS_ENT(CPUType, M68000),
- CV_ENUM_CLASS_ENT(CPUType, M68010),
- CV_ENUM_CLASS_ENT(CPUType, M68020),
- CV_ENUM_CLASS_ENT(CPUType, M68030),
- CV_ENUM_CLASS_ENT(CPUType, M68040),
- CV_ENUM_CLASS_ENT(CPUType, Alpha),
- CV_ENUM_CLASS_ENT(CPUType, Alpha21164),
- CV_ENUM_CLASS_ENT(CPUType, Alpha21164A),
- CV_ENUM_CLASS_ENT(CPUType, Alpha21264),
- CV_ENUM_CLASS_ENT(CPUType, Alpha21364),
- CV_ENUM_CLASS_ENT(CPUType, PPC601),
- CV_ENUM_CLASS_ENT(CPUType, PPC603),
- CV_ENUM_CLASS_ENT(CPUType, PPC604),
- CV_ENUM_CLASS_ENT(CPUType, PPC620),
- CV_ENUM_CLASS_ENT(CPUType, PPCFP),
- CV_ENUM_CLASS_ENT(CPUType, PPCBE),
- CV_ENUM_CLASS_ENT(CPUType, SH3),
- CV_ENUM_CLASS_ENT(CPUType, SH3E),
- CV_ENUM_CLASS_ENT(CPUType, SH3DSP),
- CV_ENUM_CLASS_ENT(CPUType, SH4),
- CV_ENUM_CLASS_ENT(CPUType, SHMedia),
- CV_ENUM_CLASS_ENT(CPUType, ARM3),
- CV_ENUM_CLASS_ENT(CPUType, ARM4),
- CV_ENUM_CLASS_ENT(CPUType, ARM4T),
- CV_ENUM_CLASS_ENT(CPUType, ARM5),
- CV_ENUM_CLASS_ENT(CPUType, ARM5T),
- CV_ENUM_CLASS_ENT(CPUType, ARM6),
- 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),
- CV_ENUM_CLASS_ENT(CPUType, CEE),
- CV_ENUM_CLASS_ENT(CPUType, AM33),
- CV_ENUM_CLASS_ENT(CPUType, M32R),
- CV_ENUM_CLASS_ENT(CPUType, TriCore),
- CV_ENUM_CLASS_ENT(CPUType, X64),
- CV_ENUM_CLASS_ENT(CPUType, EBC),
- CV_ENUM_CLASS_ENT(CPUType, Thumb),
- CV_ENUM_CLASS_ENT(CPUType, ARMNT),
- CV_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
-};
-
-static const EnumEntry<uint32_t> FrameProcSymFlagNames[] = {
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasStructuredExceptionHandling),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, AsynchronousExceptionHandling),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, NoStackOrderingForSecurityChecks),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedLocalBasePointerMask),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedParamBasePointerMask),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
- CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
-};
-
-static const EnumEntry<uint32_t> ModuleSubstreamKindNames[] = {
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, None),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, Symbols),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, Lines),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, StringTable),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, FileChecksums),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, FrameData),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, InlineeLines),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeImports),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeExports),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, ILLines),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, FuncMDTokenMap),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, TypeMDTokenMap),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, MergedAssemblyInput),
- CV_ENUM_CLASS_ENT(DebugSubsectionKind, CoffSymbolRVA),
-};
-
-static const EnumEntry<uint16_t> ExportSymFlagNames[] = {
- CV_ENUM_CLASS_ENT(ExportFlags, IsConstant),
- CV_ENUM_CLASS_ENT(ExportFlags, IsData),
- CV_ENUM_CLASS_ENT(ExportFlags, IsPrivate),
- CV_ENUM_CLASS_ENT(ExportFlags, HasNoName),
- CV_ENUM_CLASS_ENT(ExportFlags, HasExplicitOrdinal),
- CV_ENUM_CLASS_ENT(ExportFlags, IsForwarder),
-};
-
-static const EnumEntry<uint8_t> ThunkOrdinalNames[] = {
- CV_ENUM_CLASS_ENT(ThunkOrdinal, Standard),
- CV_ENUM_CLASS_ENT(ThunkOrdinal, ThisAdjustor),
- CV_ENUM_CLASS_ENT(ThunkOrdinal, Vcall),
- CV_ENUM_CLASS_ENT(ThunkOrdinal, Pcode),
- CV_ENUM_CLASS_ENT(ThunkOrdinal, UnknownLoad),
- CV_ENUM_CLASS_ENT(ThunkOrdinal, TrampIncremental),
- CV_ENUM_CLASS_ENT(ThunkOrdinal, BranchIsland),
-};
-
-static const EnumEntry<uint16_t> TrampolineNames[] = {
- CV_ENUM_CLASS_ENT(TrampolineType, TrampIncremental),
- CV_ENUM_CLASS_ENT(TrampolineType, BranchIsland),
-};
-
-static const EnumEntry<COFF::SectionCharacteristics>
- ImageSectionCharacteristicNames[] = {
- CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD),
- CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD),
- CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE),
- CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA),
- CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
- CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER),
- CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO),
- CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE),
- CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT),
- CV_ENUM_ENT(COFF, IMAGE_SCN_GPREL),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES),
- CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ),
- CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE)};
-
-static const EnumEntry<uint16_t> ClassOptionNames[] = {
- CV_ENUM_CLASS_ENT(ClassOptions, Packed),
- CV_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor),
- CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator),
- CV_ENUM_CLASS_ENT(ClassOptions, Nested),
- CV_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass),
- CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator),
- CV_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator),
- CV_ENUM_CLASS_ENT(ClassOptions, ForwardReference),
- CV_ENUM_CLASS_ENT(ClassOptions, Scoped),
- CV_ENUM_CLASS_ENT(ClassOptions, HasUniqueName),
- CV_ENUM_CLASS_ENT(ClassOptions, Sealed),
- CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
-};
-
-static const EnumEntry<uint8_t> MemberAccessNames[] = {
- CV_ENUM_CLASS_ENT(MemberAccess, None),
- CV_ENUM_CLASS_ENT(MemberAccess, Private),
- CV_ENUM_CLASS_ENT(MemberAccess, Protected),
- CV_ENUM_CLASS_ENT(MemberAccess, Public),
-};
-
-static const EnumEntry<uint16_t> MethodOptionNames[] = {
- CV_ENUM_CLASS_ENT(MethodOptions, Pseudo),
- CV_ENUM_CLASS_ENT(MethodOptions, NoInherit),
- CV_ENUM_CLASS_ENT(MethodOptions, NoConstruct),
- CV_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated),
- CV_ENUM_CLASS_ENT(MethodOptions, Sealed),
-};
-
-static const EnumEntry<uint16_t> MemberKindNames[] = {
- CV_ENUM_CLASS_ENT(MethodKind, Vanilla),
- CV_ENUM_CLASS_ENT(MethodKind, Virtual),
- CV_ENUM_CLASS_ENT(MethodKind, Static),
- CV_ENUM_CLASS_ENT(MethodKind, Friend),
- CV_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual),
- CV_ENUM_CLASS_ENT(MethodKind, PureVirtual),
- CV_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual),
-};
-
-static const EnumEntry<uint8_t> PtrKindNames[] = {
- CV_ENUM_CLASS_ENT(PointerKind, Near16),
- CV_ENUM_CLASS_ENT(PointerKind, Far16),
- CV_ENUM_CLASS_ENT(PointerKind, Huge16),
- CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegment),
- CV_ENUM_CLASS_ENT(PointerKind, BasedOnValue),
- CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue),
- CV_ENUM_CLASS_ENT(PointerKind, BasedOnAddress),
- CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress),
- CV_ENUM_CLASS_ENT(PointerKind, BasedOnType),
- CV_ENUM_CLASS_ENT(PointerKind, BasedOnSelf),
- CV_ENUM_CLASS_ENT(PointerKind, Near32),
- CV_ENUM_CLASS_ENT(PointerKind, Far32),
- CV_ENUM_CLASS_ENT(PointerKind, Near64),
-};
-
-static const EnumEntry<uint8_t> PtrModeNames[] = {
- CV_ENUM_CLASS_ENT(PointerMode, Pointer),
- CV_ENUM_CLASS_ENT(PointerMode, LValueReference),
- CV_ENUM_CLASS_ENT(PointerMode, PointerToDataMember),
- CV_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction),
- CV_ENUM_CLASS_ENT(PointerMode, RValueReference),
-};
-
-static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceData),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, MultipleInheritanceData),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, VirtualInheritanceData),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceFunction),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
- MultipleInheritanceFunction),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
- VirtualInheritanceFunction),
- CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction),
-};
-
-static const EnumEntry<uint16_t> TypeModifierNames[] = {
- CV_ENUM_CLASS_ENT(ModifierOptions, Const),
- CV_ENUM_CLASS_ENT(ModifierOptions, Volatile),
- CV_ENUM_CLASS_ENT(ModifierOptions, Unaligned),
-};
-
-static const EnumEntry<uint8_t> CallingConventions[] = {
- CV_ENUM_CLASS_ENT(CallingConvention, NearC),
- CV_ENUM_CLASS_ENT(CallingConvention, FarC),
- CV_ENUM_CLASS_ENT(CallingConvention, NearPascal),
- CV_ENUM_CLASS_ENT(CallingConvention, FarPascal),
- CV_ENUM_CLASS_ENT(CallingConvention, NearFast),
- CV_ENUM_CLASS_ENT(CallingConvention, FarFast),
- CV_ENUM_CLASS_ENT(CallingConvention, NearStdCall),
- CV_ENUM_CLASS_ENT(CallingConvention, FarStdCall),
- CV_ENUM_CLASS_ENT(CallingConvention, NearSysCall),
- CV_ENUM_CLASS_ENT(CallingConvention, FarSysCall),
- CV_ENUM_CLASS_ENT(CallingConvention, ThisCall),
- CV_ENUM_CLASS_ENT(CallingConvention, MipsCall),
- CV_ENUM_CLASS_ENT(CallingConvention, Generic),
- CV_ENUM_CLASS_ENT(CallingConvention, AlphaCall),
- CV_ENUM_CLASS_ENT(CallingConvention, PpcCall),
- CV_ENUM_CLASS_ENT(CallingConvention, SHCall),
- CV_ENUM_CLASS_ENT(CallingConvention, ArmCall),
- CV_ENUM_CLASS_ENT(CallingConvention, AM33Call),
- CV_ENUM_CLASS_ENT(CallingConvention, TriCall),
- CV_ENUM_CLASS_ENT(CallingConvention, SH5Call),
- CV_ENUM_CLASS_ENT(CallingConvention, M32RCall),
- CV_ENUM_CLASS_ENT(CallingConvention, ClrCall),
- CV_ENUM_CLASS_ENT(CallingConvention, Inline),
- CV_ENUM_CLASS_ENT(CallingConvention, NearVector),
-};
-
-static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
- CV_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt),
- CV_ENUM_CLASS_ENT(FunctionOptions, Constructor),
- CV_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases),
-};
-
-static const EnumEntry<uint16_t> LabelTypeEnum[] = {
- CV_ENUM_CLASS_ENT(LabelType, Near),
- CV_ENUM_CLASS_ENT(LabelType, Far),
-};
-
-namespace llvm {
-namespace codeview {
-
-ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames() {
- return makeArrayRef(SymbolTypeNames);
-}
-
-ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() {
- return makeArrayRef(TypeLeafNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu) {
+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[] = {
+ CV_ENUM_CLASS_ENT(PublicSymFlags, Code),
+ CV_ENUM_CLASS_ENT(PublicSymFlags, Function),
+ CV_ENUM_CLASS_ENT(PublicSymFlags, Managed),
+ CV_ENUM_CLASS_ENT(PublicSymFlags, MSIL),
+};
+
+static const EnumEntry<uint8_t> ProcSymFlagNames[] = {
+ CV_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
+ CV_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
+ CV_ENUM_CLASS_ENT(ProcSymFlags, HasFRET),
+ CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn),
+ CV_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable),
+ CV_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv),
+ CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline),
+ CV_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
+};
+
+static const EnumEntry<uint16_t> LocalFlags[] = {
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
+ CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
+};
+
+static const EnumEntry<uint8_t> FrameCookieKinds[] = {
+ CV_ENUM_CLASS_ENT(FrameCookieKind, Copy),
+ CV_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
+ CV_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
+ CV_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
+};
+
+static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
+ CV_ENUM_ENT(SourceLanguage, C), CV_ENUM_ENT(SourceLanguage, Cpp),
+ CV_ENUM_ENT(SourceLanguage, Fortran), CV_ENUM_ENT(SourceLanguage, Masm),
+ CV_ENUM_ENT(SourceLanguage, Pascal), CV_ENUM_ENT(SourceLanguage, Basic),
+ CV_ENUM_ENT(SourceLanguage, Cobol), CV_ENUM_ENT(SourceLanguage, Link),
+ CV_ENUM_ENT(SourceLanguage, Cvtres), CV_ENUM_ENT(SourceLanguage, Cvtpgd),
+ CV_ENUM_ENT(SourceLanguage, CSharp), CV_ENUM_ENT(SourceLanguage, VB),
+ 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[] = {
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, EC),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDbgInfo),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, LTCG),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDataAlign),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, ManagedPresent),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, SecurityChecks),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, HotPatch),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, CVTCIL),
+ CV_ENUM_CLASS_ENT(CompileSym2Flags, MSILModule),
+};
+
+static const EnumEntry<uint32_t> CompileSym3FlagNames[] = {
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, EC),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
+ CV_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
+};
+
+static const EnumEntry<uint32_t> FileChecksumNames[] = {
+ CV_ENUM_CLASS_ENT(FileChecksumKind, None),
+ CV_ENUM_CLASS_ENT(FileChecksumKind, MD5),
+ CV_ENUM_CLASS_ENT(FileChecksumKind, SHA1),
+ CV_ENUM_CLASS_ENT(FileChecksumKind, SHA256),
+};
+
+static const EnumEntry<unsigned> CPUTypeNames[] = {
+ CV_ENUM_CLASS_ENT(CPUType, Intel8080),
+ CV_ENUM_CLASS_ENT(CPUType, Intel8086),
+ CV_ENUM_CLASS_ENT(CPUType, Intel80286),
+ CV_ENUM_CLASS_ENT(CPUType, Intel80386),
+ CV_ENUM_CLASS_ENT(CPUType, Intel80486),
+ CV_ENUM_CLASS_ENT(CPUType, Pentium),
+ CV_ENUM_CLASS_ENT(CPUType, PentiumPro),
+ CV_ENUM_CLASS_ENT(CPUType, Pentium3),
+ CV_ENUM_CLASS_ENT(CPUType, MIPS),
+ CV_ENUM_CLASS_ENT(CPUType, MIPS16),
+ CV_ENUM_CLASS_ENT(CPUType, MIPS32),
+ CV_ENUM_CLASS_ENT(CPUType, MIPS64),
+ CV_ENUM_CLASS_ENT(CPUType, MIPSI),
+ CV_ENUM_CLASS_ENT(CPUType, MIPSII),
+ CV_ENUM_CLASS_ENT(CPUType, MIPSIII),
+ CV_ENUM_CLASS_ENT(CPUType, MIPSIV),
+ CV_ENUM_CLASS_ENT(CPUType, MIPSV),
+ CV_ENUM_CLASS_ENT(CPUType, M68000),
+ CV_ENUM_CLASS_ENT(CPUType, M68010),
+ CV_ENUM_CLASS_ENT(CPUType, M68020),
+ CV_ENUM_CLASS_ENT(CPUType, M68030),
+ CV_ENUM_CLASS_ENT(CPUType, M68040),
+ CV_ENUM_CLASS_ENT(CPUType, Alpha),
+ CV_ENUM_CLASS_ENT(CPUType, Alpha21164),
+ CV_ENUM_CLASS_ENT(CPUType, Alpha21164A),
+ CV_ENUM_CLASS_ENT(CPUType, Alpha21264),
+ CV_ENUM_CLASS_ENT(CPUType, Alpha21364),
+ CV_ENUM_CLASS_ENT(CPUType, PPC601),
+ CV_ENUM_CLASS_ENT(CPUType, PPC603),
+ CV_ENUM_CLASS_ENT(CPUType, PPC604),
+ CV_ENUM_CLASS_ENT(CPUType, PPC620),
+ CV_ENUM_CLASS_ENT(CPUType, PPCFP),
+ CV_ENUM_CLASS_ENT(CPUType, PPCBE),
+ CV_ENUM_CLASS_ENT(CPUType, SH3),
+ CV_ENUM_CLASS_ENT(CPUType, SH3E),
+ CV_ENUM_CLASS_ENT(CPUType, SH3DSP),
+ CV_ENUM_CLASS_ENT(CPUType, SH4),
+ CV_ENUM_CLASS_ENT(CPUType, SHMedia),
+ CV_ENUM_CLASS_ENT(CPUType, ARM3),
+ CV_ENUM_CLASS_ENT(CPUType, ARM4),
+ CV_ENUM_CLASS_ENT(CPUType, ARM4T),
+ CV_ENUM_CLASS_ENT(CPUType, ARM5),
+ CV_ENUM_CLASS_ENT(CPUType, ARM5T),
+ CV_ENUM_CLASS_ENT(CPUType, ARM6),
+ 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),
+ CV_ENUM_CLASS_ENT(CPUType, CEE),
+ CV_ENUM_CLASS_ENT(CPUType, AM33),
+ CV_ENUM_CLASS_ENT(CPUType, M32R),
+ CV_ENUM_CLASS_ENT(CPUType, TriCore),
+ CV_ENUM_CLASS_ENT(CPUType, X64),
+ CV_ENUM_CLASS_ENT(CPUType, EBC),
+ CV_ENUM_CLASS_ENT(CPUType, Thumb),
+ CV_ENUM_CLASS_ENT(CPUType, ARMNT),
+ CV_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
+};
+
+static const EnumEntry<uint32_t> FrameProcSymFlagNames[] = {
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasStructuredExceptionHandling),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, AsynchronousExceptionHandling),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, NoStackOrderingForSecurityChecks),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedLocalBasePointerMask),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, EncodedParamBasePointerMask),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
+ CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
+};
+
+static const EnumEntry<uint32_t> ModuleSubstreamKindNames[] = {
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, None),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, Symbols),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, Lines),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, StringTable),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, FileChecksums),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, FrameData),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, InlineeLines),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeImports),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, CrossScopeExports),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, ILLines),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, FuncMDTokenMap),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, TypeMDTokenMap),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, MergedAssemblyInput),
+ CV_ENUM_CLASS_ENT(DebugSubsectionKind, CoffSymbolRVA),
+};
+
+static const EnumEntry<uint16_t> ExportSymFlagNames[] = {
+ CV_ENUM_CLASS_ENT(ExportFlags, IsConstant),
+ CV_ENUM_CLASS_ENT(ExportFlags, IsData),
+ CV_ENUM_CLASS_ENT(ExportFlags, IsPrivate),
+ CV_ENUM_CLASS_ENT(ExportFlags, HasNoName),
+ CV_ENUM_CLASS_ENT(ExportFlags, HasExplicitOrdinal),
+ CV_ENUM_CLASS_ENT(ExportFlags, IsForwarder),
+};
+
+static const EnumEntry<uint8_t> ThunkOrdinalNames[] = {
+ CV_ENUM_CLASS_ENT(ThunkOrdinal, Standard),
+ CV_ENUM_CLASS_ENT(ThunkOrdinal, ThisAdjustor),
+ CV_ENUM_CLASS_ENT(ThunkOrdinal, Vcall),
+ CV_ENUM_CLASS_ENT(ThunkOrdinal, Pcode),
+ CV_ENUM_CLASS_ENT(ThunkOrdinal, UnknownLoad),
+ CV_ENUM_CLASS_ENT(ThunkOrdinal, TrampIncremental),
+ CV_ENUM_CLASS_ENT(ThunkOrdinal, BranchIsland),
+};
+
+static const EnumEntry<uint16_t> TrampolineNames[] = {
+ CV_ENUM_CLASS_ENT(TrampolineType, TrampIncremental),
+ CV_ENUM_CLASS_ENT(TrampolineType, BranchIsland),
+};
+
+static const EnumEntry<COFF::SectionCharacteristics>
+ ImageSectionCharacteristicNames[] = {
+ CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NOLOAD),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_GPREL),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ),
+ CV_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE)};
+
+static const EnumEntry<uint16_t> ClassOptionNames[] = {
+ CV_ENUM_CLASS_ENT(ClassOptions, Packed),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasConstructorOrDestructor),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedOperator),
+ CV_ENUM_CLASS_ENT(ClassOptions, Nested),
+ CV_ENUM_CLASS_ENT(ClassOptions, ContainsNestedClass),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasOverloadedAssignmentOperator),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasConversionOperator),
+ CV_ENUM_CLASS_ENT(ClassOptions, ForwardReference),
+ CV_ENUM_CLASS_ENT(ClassOptions, Scoped),
+ CV_ENUM_CLASS_ENT(ClassOptions, HasUniqueName),
+ CV_ENUM_CLASS_ENT(ClassOptions, Sealed),
+ CV_ENUM_CLASS_ENT(ClassOptions, Intrinsic),
+};
+
+static const EnumEntry<uint8_t> MemberAccessNames[] = {
+ CV_ENUM_CLASS_ENT(MemberAccess, None),
+ CV_ENUM_CLASS_ENT(MemberAccess, Private),
+ CV_ENUM_CLASS_ENT(MemberAccess, Protected),
+ CV_ENUM_CLASS_ENT(MemberAccess, Public),
+};
+
+static const EnumEntry<uint16_t> MethodOptionNames[] = {
+ CV_ENUM_CLASS_ENT(MethodOptions, Pseudo),
+ CV_ENUM_CLASS_ENT(MethodOptions, NoInherit),
+ CV_ENUM_CLASS_ENT(MethodOptions, NoConstruct),
+ CV_ENUM_CLASS_ENT(MethodOptions, CompilerGenerated),
+ CV_ENUM_CLASS_ENT(MethodOptions, Sealed),
+};
+
+static const EnumEntry<uint16_t> MemberKindNames[] = {
+ CV_ENUM_CLASS_ENT(MethodKind, Vanilla),
+ CV_ENUM_CLASS_ENT(MethodKind, Virtual),
+ CV_ENUM_CLASS_ENT(MethodKind, Static),
+ CV_ENUM_CLASS_ENT(MethodKind, Friend),
+ CV_ENUM_CLASS_ENT(MethodKind, IntroducingVirtual),
+ CV_ENUM_CLASS_ENT(MethodKind, PureVirtual),
+ CV_ENUM_CLASS_ENT(MethodKind, PureIntroducingVirtual),
+};
+
+static const EnumEntry<uint8_t> PtrKindNames[] = {
+ CV_ENUM_CLASS_ENT(PointerKind, Near16),
+ CV_ENUM_CLASS_ENT(PointerKind, Far16),
+ CV_ENUM_CLASS_ENT(PointerKind, Huge16),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegment),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnValue),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentValue),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnAddress),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSegmentAddress),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnType),
+ CV_ENUM_CLASS_ENT(PointerKind, BasedOnSelf),
+ CV_ENUM_CLASS_ENT(PointerKind, Near32),
+ CV_ENUM_CLASS_ENT(PointerKind, Far32),
+ CV_ENUM_CLASS_ENT(PointerKind, Near64),
+};
+
+static const EnumEntry<uint8_t> PtrModeNames[] = {
+ CV_ENUM_CLASS_ENT(PointerMode, Pointer),
+ CV_ENUM_CLASS_ENT(PointerMode, LValueReference),
+ CV_ENUM_CLASS_ENT(PointerMode, PointerToDataMember),
+ CV_ENUM_CLASS_ENT(PointerMode, PointerToMemberFunction),
+ CV_ENUM_CLASS_ENT(PointerMode, RValueReference),
+};
+
+static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, Unknown),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, MultipleInheritanceData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, VirtualInheritanceData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralData),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, SingleInheritanceFunction),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ MultipleInheritanceFunction),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation,
+ VirtualInheritanceFunction),
+ CV_ENUM_CLASS_ENT(PointerToMemberRepresentation, GeneralFunction),
+};
+
+static const EnumEntry<uint16_t> TypeModifierNames[] = {
+ CV_ENUM_CLASS_ENT(ModifierOptions, Const),
+ CV_ENUM_CLASS_ENT(ModifierOptions, Volatile),
+ CV_ENUM_CLASS_ENT(ModifierOptions, Unaligned),
+};
+
+static const EnumEntry<uint8_t> CallingConventions[] = {
+ CV_ENUM_CLASS_ENT(CallingConvention, NearC),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarC),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearPascal),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarPascal),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearFast),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarFast),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearStdCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarStdCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearSysCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, FarSysCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, ThisCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, MipsCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, Generic),
+ CV_ENUM_CLASS_ENT(CallingConvention, AlphaCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, PpcCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, SHCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, ArmCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, AM33Call),
+ CV_ENUM_CLASS_ENT(CallingConvention, TriCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, SH5Call),
+ CV_ENUM_CLASS_ENT(CallingConvention, M32RCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, ClrCall),
+ CV_ENUM_CLASS_ENT(CallingConvention, Inline),
+ CV_ENUM_CLASS_ENT(CallingConvention, NearVector),
+};
+
+static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
+ CV_ENUM_CLASS_ENT(FunctionOptions, CxxReturnUdt),
+ CV_ENUM_CLASS_ENT(FunctionOptions, Constructor),
+ CV_ENUM_CLASS_ENT(FunctionOptions, ConstructorWithVirtualBases),
+};
+
+static const EnumEntry<uint16_t> LabelTypeEnum[] = {
+ CV_ENUM_CLASS_ENT(LabelType, Near),
+ CV_ENUM_CLASS_ENT(LabelType, Far),
+};
+
+namespace llvm {
+namespace codeview {
+
+ArrayRef<EnumEntry<SymbolKind>> getSymbolTypeNames() {
+ return makeArrayRef(SymbolTypeNames);
+}
+
+ArrayRef<EnumEntry<TypeLeafKind>> getTypeLeafNames() {
+ return makeArrayRef(TypeLeafNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getRegisterNames(CPUType Cpu) {
if (Cpu == CPUType::ARMNT) {
return makeArrayRef(RegisterNames_ARM);
} else if (Cpu == CPUType::ARM64) {
- return makeArrayRef(RegisterNames_ARM64);
- }
- return makeArrayRef(RegisterNames_X86);
-}
-
-ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames() {
- return makeArrayRef(PublicSymFlagNames);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames() {
- return makeArrayRef(ProcSymFlagNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames() {
- return makeArrayRef(LocalFlags);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames() {
- return makeArrayRef(FrameCookieKinds);
-}
-
-ArrayRef<EnumEntry<SourceLanguage>> getSourceLanguageNames() {
- return makeArrayRef(SourceLanguages);
-}
-
-ArrayRef<EnumEntry<uint32_t>> getCompileSym2FlagNames() {
- return makeArrayRef(CompileSym2FlagNames);
-}
-
-ArrayRef<EnumEntry<uint32_t>> getCompileSym3FlagNames() {
- return makeArrayRef(CompileSym3FlagNames);
-}
-
-ArrayRef<EnumEntry<uint32_t>> getFileChecksumNames() {
- return makeArrayRef(FileChecksumNames);
-}
-
-ArrayRef<EnumEntry<unsigned>> getCPUTypeNames() {
- return makeArrayRef(CPUTypeNames);
-}
-
-ArrayRef<EnumEntry<uint32_t>> getFrameProcSymFlagNames() {
- return makeArrayRef(FrameProcSymFlagNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getExportSymFlagNames() {
- return makeArrayRef(ExportSymFlagNames);
-}
-
-ArrayRef<EnumEntry<uint32_t>> getModuleSubstreamKindNames() {
- return makeArrayRef(ModuleSubstreamKindNames);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames() {
- return makeArrayRef(ThunkOrdinalNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getTrampolineNames() {
- return makeArrayRef(TrampolineNames);
-}
-
-ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
-getImageSectionCharacteristicNames() {
- return makeArrayRef(ImageSectionCharacteristicNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getClassOptionNames() {
- return makeArrayRef(ClassOptionNames);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames() {
- return makeArrayRef(MemberAccessNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames() {
- return makeArrayRef(MethodOptionNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getMemberKindNames() {
- return makeArrayRef(MemberKindNames);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getPtrKindNames() {
- return makeArrayRef(PtrKindNames);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getPtrModeNames() {
- return makeArrayRef(PtrModeNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames() {
- return makeArrayRef(PtrMemberRepNames);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames() {
- return makeArrayRef(TypeModifierNames);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getCallingConventions() {
- return makeArrayRef(CallingConventions);
-}
-
-ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum() {
- return makeArrayRef(FunctionOptionEnum);
-}
-
-ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum() {
- return makeArrayRef(LabelTypeEnum);
-}
-
-} // end namespace codeview
-} // end namespace llvm
+ return makeArrayRef(RegisterNames_ARM64);
+ }
+ return makeArrayRef(RegisterNames_X86);
+}
+
+ArrayRef<EnumEntry<uint32_t>> getPublicSymFlagNames() {
+ return makeArrayRef(PublicSymFlagNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getProcSymFlagNames() {
+ return makeArrayRef(ProcSymFlagNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getLocalFlagNames() {
+ return makeArrayRef(LocalFlags);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getFrameCookieKindNames() {
+ return makeArrayRef(FrameCookieKinds);
+}
+
+ArrayRef<EnumEntry<SourceLanguage>> getSourceLanguageNames() {
+ return makeArrayRef(SourceLanguages);
+}
+
+ArrayRef<EnumEntry<uint32_t>> getCompileSym2FlagNames() {
+ return makeArrayRef(CompileSym2FlagNames);
+}
+
+ArrayRef<EnumEntry<uint32_t>> getCompileSym3FlagNames() {
+ return makeArrayRef(CompileSym3FlagNames);
+}
+
+ArrayRef<EnumEntry<uint32_t>> getFileChecksumNames() {
+ return makeArrayRef(FileChecksumNames);
+}
+
+ArrayRef<EnumEntry<unsigned>> getCPUTypeNames() {
+ return makeArrayRef(CPUTypeNames);
+}
+
+ArrayRef<EnumEntry<uint32_t>> getFrameProcSymFlagNames() {
+ return makeArrayRef(FrameProcSymFlagNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getExportSymFlagNames() {
+ return makeArrayRef(ExportSymFlagNames);
+}
+
+ArrayRef<EnumEntry<uint32_t>> getModuleSubstreamKindNames() {
+ return makeArrayRef(ModuleSubstreamKindNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getThunkOrdinalNames() {
+ return makeArrayRef(ThunkOrdinalNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getTrampolineNames() {
+ return makeArrayRef(TrampolineNames);
+}
+
+ArrayRef<EnumEntry<COFF::SectionCharacteristics>>
+getImageSectionCharacteristicNames() {
+ return makeArrayRef(ImageSectionCharacteristicNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getClassOptionNames() {
+ return makeArrayRef(ClassOptionNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getMemberAccessNames() {
+ return makeArrayRef(MemberAccessNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getMethodOptionNames() {
+ return makeArrayRef(MethodOptionNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getMemberKindNames() {
+ return makeArrayRef(MemberKindNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getPtrKindNames() {
+ return makeArrayRef(PtrKindNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getPtrModeNames() {
+ return makeArrayRef(PtrModeNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getPtrMemberRepNames() {
+ return makeArrayRef(PtrMemberRepNames);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getTypeModifierNames() {
+ return makeArrayRef(TypeModifierNames);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getCallingConventions() {
+ return makeArrayRef(CallingConventions);
+}
+
+ArrayRef<EnumEntry<uint8_t>> getFunctionOptionEnum() {
+ return makeArrayRef(FunctionOptionEnum);
+}
+
+ArrayRef<EnumEntry<uint16_t>> getLabelTypeEnum() {
+ return makeArrayRef(LabelTypeEnum);
+}
+
+} // end namespace codeview
+} // end namespace llvm
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/Formatters.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/Formatters.cpp
index a7a8c7ff82..fc8482ed81 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/Formatters.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/Formatters.cpp
@@ -1,47 +1,47 @@
-//===- Formatters.cpp -----------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/Formatters.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/GUID.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::codeview::detail;
-
-GuidAdapter::GuidAdapter(StringRef Guid)
- : FormatAdapter(makeArrayRef(Guid.bytes_begin(), Guid.bytes_end())) {}
-
-GuidAdapter::GuidAdapter(ArrayRef<uint8_t> Guid)
- : FormatAdapter(std::move(Guid)) {}
-
-void GuidAdapter::format(raw_ostream &Stream, StringRef Style) {
- static const char *Lookup = "0123456789ABCDEF";
-
- assert(Item.size() == 16 && "Expected 16-byte GUID");
- Stream << "{";
- for (int i = 0; i < 16;) {
- uint8_t Byte = Item[i];
- uint8_t HighNibble = (Byte >> 4) & 0xF;
- uint8_t LowNibble = Byte & 0xF;
- Stream << Lookup[HighNibble] << Lookup[LowNibble];
- ++i;
- if (i >= 4 && i <= 10 && i % 2 == 0)
- Stream << "-";
- }
- Stream << "}";
-}
-
-raw_ostream &llvm::codeview::operator<<(raw_ostream &OS, const GUID &Guid) {
- codeview::detail::GuidAdapter A(Guid.Guid);
- A.format(OS, "");
- return OS;
-}
+//===- Formatters.cpp -----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/Formatters.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/GUID.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::codeview::detail;
+
+GuidAdapter::GuidAdapter(StringRef Guid)
+ : FormatAdapter(makeArrayRef(Guid.bytes_begin(), Guid.bytes_end())) {}
+
+GuidAdapter::GuidAdapter(ArrayRef<uint8_t> Guid)
+ : FormatAdapter(std::move(Guid)) {}
+
+void GuidAdapter::format(raw_ostream &Stream, StringRef Style) {
+ static const char *Lookup = "0123456789ABCDEF";
+
+ assert(Item.size() == 16 && "Expected 16-byte GUID");
+ Stream << "{";
+ for (int i = 0; i < 16;) {
+ uint8_t Byte = Item[i];
+ uint8_t HighNibble = (Byte >> 4) & 0xF;
+ uint8_t LowNibble = Byte & 0xF;
+ Stream << Lookup[HighNibble] << Lookup[LowNibble];
+ ++i;
+ if (i >= 4 && i <= 10 && i % 2 == 0)
+ Stream << "-";
+ }
+ Stream << "}";
+}
+
+raw_ostream &llvm::codeview::operator<<(raw_ostream &OS, const GUID &Guid) {
+ codeview::detail::GuidAdapter A(Guid.Guid);
+ A.format(OS, "");
+ return OS;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
index 7cd9ca7498..0923eb1729 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/GlobalTypeTableBuilder.cpp
@@ -1,140 +1,140 @@
-//===- GlobalTypeTableBuilder.cpp -----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-TypeIndex GlobalTypeTableBuilder::nextTypeIndex() const {
- return TypeIndex::fromArrayIndex(SeenRecords.size());
-}
-
-GlobalTypeTableBuilder::GlobalTypeTableBuilder(BumpPtrAllocator &Storage)
- : RecordStorage(Storage) {
- SeenRecords.reserve(4096);
-}
-
-GlobalTypeTableBuilder::~GlobalTypeTableBuilder() = default;
-
-Optional<TypeIndex> GlobalTypeTableBuilder::getFirst() {
- if (empty())
- return None;
-
- return TypeIndex(TypeIndex::FirstNonSimpleIndex);
-}
-
-Optional<TypeIndex> GlobalTypeTableBuilder::getNext(TypeIndex Prev) {
- if (++Prev == nextTypeIndex())
- return None;
- return Prev;
-}
-
-CVType GlobalTypeTableBuilder::getType(TypeIndex Index) {
- CVType Type(SeenRecords[Index.toArrayIndex()]);
- return Type;
-}
-
-StringRef GlobalTypeTableBuilder::getTypeName(TypeIndex Index) {
- llvm_unreachable("Method not implemented");
-}
-
-bool GlobalTypeTableBuilder::contains(TypeIndex Index) {
- if (Index.isSimple() || Index.isNoneType())
- return false;
-
- return Index.toArrayIndex() < SeenRecords.size();
-}
-
-uint32_t GlobalTypeTableBuilder::size() { return SeenRecords.size(); }
-
-uint32_t GlobalTypeTableBuilder::capacity() { return SeenRecords.size(); }
-
-ArrayRef<ArrayRef<uint8_t>> GlobalTypeTableBuilder::records() const {
- return SeenRecords;
-}
-
-ArrayRef<GloballyHashedType> GlobalTypeTableBuilder::hashes() const {
- return SeenHashes;
-}
-
-void GlobalTypeTableBuilder::reset() {
- HashedRecords.clear();
- SeenRecords.clear();
-}
-
-static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
- ArrayRef<uint8_t> Data) {
- uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
- memcpy(Stable, Data.data(), Data.size());
- return makeArrayRef(Stable, Data.size());
-}
-
-TypeIndex GlobalTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> Record) {
- GloballyHashedType GHT =
- GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
- return insertRecordAs(GHT, Record.size(),
- [Record](MutableArrayRef<uint8_t> Data) {
- assert(Data.size() == Record.size());
- ::memcpy(Data.data(), Record.data(), Record.size());
- return Data;
- });
-}
-
-TypeIndex
-GlobalTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
- TypeIndex TI;
- auto Fragments = Builder.end(nextTypeIndex());
- assert(!Fragments.empty());
- for (auto C : Fragments)
- TI = insertRecordBytes(C.RecordData);
- return TI;
-}
-
-bool GlobalTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
- bool Stabilize) {
- assert(Index.toArrayIndex() < SeenRecords.size() &&
- "This function cannot be used to insert records!");
-
- ArrayRef<uint8_t> Record = Data.data();
- assert(Record.size() < UINT32_MAX && "Record too big");
- assert(Record.size() % 4 == 0 &&
- "The type record size is not a multiple of 4 bytes which will cause "
- "misalignment in the output TPI stream!");
-
- GloballyHashedType Hash =
- GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
- auto Result = HashedRecords.try_emplace(Hash, Index.toArrayIndex());
- if (!Result.second) {
- Index = Result.first->second;
- return false; // The record is already there, at a different location
- }
-
- if (Stabilize)
- Record = stabilize(RecordStorage, Record);
-
- SeenRecords[Index.toArrayIndex()] = Record;
- SeenHashes[Index.toArrayIndex()] = Hash;
- return true;
-}
+//===- GlobalTypeTableBuilder.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+TypeIndex GlobalTypeTableBuilder::nextTypeIndex() const {
+ return TypeIndex::fromArrayIndex(SeenRecords.size());
+}
+
+GlobalTypeTableBuilder::GlobalTypeTableBuilder(BumpPtrAllocator &Storage)
+ : RecordStorage(Storage) {
+ SeenRecords.reserve(4096);
+}
+
+GlobalTypeTableBuilder::~GlobalTypeTableBuilder() = default;
+
+Optional<TypeIndex> GlobalTypeTableBuilder::getFirst() {
+ if (empty())
+ return None;
+
+ return TypeIndex(TypeIndex::FirstNonSimpleIndex);
+}
+
+Optional<TypeIndex> GlobalTypeTableBuilder::getNext(TypeIndex Prev) {
+ if (++Prev == nextTypeIndex())
+ return None;
+ return Prev;
+}
+
+CVType GlobalTypeTableBuilder::getType(TypeIndex Index) {
+ CVType Type(SeenRecords[Index.toArrayIndex()]);
+ return Type;
+}
+
+StringRef GlobalTypeTableBuilder::getTypeName(TypeIndex Index) {
+ llvm_unreachable("Method not implemented");
+}
+
+bool GlobalTypeTableBuilder::contains(TypeIndex Index) {
+ if (Index.isSimple() || Index.isNoneType())
+ return false;
+
+ return Index.toArrayIndex() < SeenRecords.size();
+}
+
+uint32_t GlobalTypeTableBuilder::size() { return SeenRecords.size(); }
+
+uint32_t GlobalTypeTableBuilder::capacity() { return SeenRecords.size(); }
+
+ArrayRef<ArrayRef<uint8_t>> GlobalTypeTableBuilder::records() const {
+ return SeenRecords;
+}
+
+ArrayRef<GloballyHashedType> GlobalTypeTableBuilder::hashes() const {
+ return SeenHashes;
+}
+
+void GlobalTypeTableBuilder::reset() {
+ HashedRecords.clear();
+ SeenRecords.clear();
+}
+
+static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
+ ArrayRef<uint8_t> Data) {
+ uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
+ memcpy(Stable, Data.data(), Data.size());
+ return makeArrayRef(Stable, Data.size());
+}
+
+TypeIndex GlobalTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> Record) {
+ GloballyHashedType GHT =
+ GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
+ return insertRecordAs(GHT, Record.size(),
+ [Record](MutableArrayRef<uint8_t> Data) {
+ assert(Data.size() == Record.size());
+ ::memcpy(Data.data(), Record.data(), Record.size());
+ return Data;
+ });
+}
+
+TypeIndex
+GlobalTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
+ TypeIndex TI;
+ auto Fragments = Builder.end(nextTypeIndex());
+ assert(!Fragments.empty());
+ for (auto C : Fragments)
+ TI = insertRecordBytes(C.RecordData);
+ return TI;
+}
+
+bool GlobalTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
+ bool Stabilize) {
+ assert(Index.toArrayIndex() < SeenRecords.size() &&
+ "This function cannot be used to insert records!");
+
+ ArrayRef<uint8_t> Record = Data.data();
+ assert(Record.size() < UINT32_MAX && "Record too big");
+ assert(Record.size() % 4 == 0 &&
+ "The type record size is not a multiple of 4 bytes which will cause "
+ "misalignment in the output TPI stream!");
+
+ GloballyHashedType Hash =
+ GloballyHashedType::hashType(Record, SeenHashes, SeenHashes);
+ auto Result = HashedRecords.try_emplace(Hash, Index.toArrayIndex());
+ if (!Result.second) {
+ Index = Result.first->second;
+ return false; // The record is already there, at a different location
+ }
+
+ if (Stabilize)
+ Record = stabilize(RecordStorage, Record);
+
+ SeenRecords[Index.toArrayIndex()] = Record;
+ SeenHashes[Index.toArrayIndex()] = Hash;
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
index c0fc3e0ef6..dae7fbe2ac 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/LazyRandomTypeCollection.cpp
@@ -1,284 +1,284 @@
-//===- LazyRandomTypeCollection.cpp ---------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <iterator>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-static void error(Error &&EC) {
- assert(!static_cast<bool>(EC));
- if (EC)
- consumeError(std::move(EC));
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(uint32_t RecordCountHint)
- : LazyRandomTypeCollection(CVTypeArray(), RecordCountHint,
- PartialOffsetArray()) {}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(
- const CVTypeArray &Types, uint32_t RecordCountHint,
- PartialOffsetArray PartialOffsets)
- : NameStorage(Allocator), Types(Types), PartialOffsets(PartialOffsets) {
- Records.resize(RecordCountHint);
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(ArrayRef<uint8_t> Data,
- uint32_t RecordCountHint)
- : LazyRandomTypeCollection(RecordCountHint) {
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(StringRef Data,
- uint32_t RecordCountHint)
- : LazyRandomTypeCollection(
- makeArrayRef(Data.bytes_begin(), Data.bytes_end()), RecordCountHint) {
-}
-
-LazyRandomTypeCollection::LazyRandomTypeCollection(const CVTypeArray &Types,
- uint32_t NumRecords)
- : LazyRandomTypeCollection(Types, NumRecords, PartialOffsetArray()) {}
-
-void LazyRandomTypeCollection::reset(BinaryStreamReader &Reader,
- uint32_t RecordCountHint) {
- Count = 0;
- PartialOffsets = PartialOffsetArray();
-
- error(Reader.readArray(Types, Reader.bytesRemaining()));
-
- // Clear and then resize, to make sure existing data gets destroyed.
- Records.clear();
- Records.resize(RecordCountHint);
-}
-
-void LazyRandomTypeCollection::reset(StringRef Data, uint32_t RecordCountHint) {
- BinaryStreamReader Reader(Data, support::little);
- reset(Reader, RecordCountHint);
-}
-
-void LazyRandomTypeCollection::reset(ArrayRef<uint8_t> Data,
- uint32_t RecordCountHint) {
- BinaryStreamReader Reader(Data, support::little);
- reset(Reader, RecordCountHint);
-}
-
-uint32_t LazyRandomTypeCollection::getOffsetOfType(TypeIndex Index) {
- error(ensureTypeExists(Index));
- assert(contains(Index));
-
- return Records[Index.toArrayIndex()].Offset;
-}
-
-CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
- assert(!Index.isSimple());
-
- auto EC = ensureTypeExists(Index);
- error(std::move(EC));
- assert(contains(Index));
-
- return Records[Index.toArrayIndex()].Type;
-}
-
-Optional<CVType> LazyRandomTypeCollection::tryGetType(TypeIndex Index) {
- if (Index.isSimple())
- return None;
-
- if (auto EC = ensureTypeExists(Index)) {
- consumeError(std::move(EC));
- return None;
- }
-
- assert(contains(Index));
- return Records[Index.toArrayIndex()].Type;
-}
-
-StringRef LazyRandomTypeCollection::getTypeName(TypeIndex Index) {
- if (Index.isNoneType() || Index.isSimple())
- return TypeIndex::simpleTypeName(Index);
-
- // Try to make sure the type exists. Even if it doesn't though, it may be
- // because we're dumping a symbol stream with no corresponding type stream
- // present, in which case we still want to be able to print <unknown UDT>
- // for the type names.
- if (auto EC = ensureTypeExists(Index)) {
- consumeError(std::move(EC));
- return "<unknown UDT>";
- }
-
- uint32_t I = Index.toArrayIndex();
- ensureCapacityFor(Index);
- if (Records[I].Name.data() == nullptr) {
- StringRef Result = NameStorage.save(computeTypeName(*this, Index));
- Records[I].Name = Result;
- }
- return Records[I].Name;
-}
-
-bool LazyRandomTypeCollection::contains(TypeIndex Index) {
- if (Index.isSimple() || Index.isNoneType())
- return false;
-
- if (Records.size() <= Index.toArrayIndex())
- return false;
- if (!Records[Index.toArrayIndex()].Type.valid())
- return false;
- return true;
-}
-
-uint32_t LazyRandomTypeCollection::size() { return Count; }
-
-uint32_t LazyRandomTypeCollection::capacity() { return Records.size(); }
-
-Error LazyRandomTypeCollection::ensureTypeExists(TypeIndex TI) {
- if (contains(TI))
- return Error::success();
-
- return visitRangeForType(TI);
-}
-
-void LazyRandomTypeCollection::ensureCapacityFor(TypeIndex Index) {
- assert(!Index.isSimple());
- uint32_t MinSize = Index.toArrayIndex() + 1;
-
- if (MinSize <= capacity())
- return;
-
- uint32_t NewCapacity = MinSize * 3 / 2;
-
- assert(NewCapacity > capacity());
- Records.resize(NewCapacity);
-}
-
-Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
- assert(!TI.isSimple());
- if (PartialOffsets.empty())
- return fullScanForType(TI);
-
+//===- LazyRandomTypeCollection.cpp ---------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+static void error(Error &&EC) {
+ assert(!static_cast<bool>(EC));
+ if (EC)
+ consumeError(std::move(EC));
+}
+
+LazyRandomTypeCollection::LazyRandomTypeCollection(uint32_t RecordCountHint)
+ : LazyRandomTypeCollection(CVTypeArray(), RecordCountHint,
+ PartialOffsetArray()) {}
+
+LazyRandomTypeCollection::LazyRandomTypeCollection(
+ const CVTypeArray &Types, uint32_t RecordCountHint,
+ PartialOffsetArray PartialOffsets)
+ : NameStorage(Allocator), Types(Types), PartialOffsets(PartialOffsets) {
+ Records.resize(RecordCountHint);
+}
+
+LazyRandomTypeCollection::LazyRandomTypeCollection(ArrayRef<uint8_t> Data,
+ uint32_t RecordCountHint)
+ : LazyRandomTypeCollection(RecordCountHint) {
+}
+
+LazyRandomTypeCollection::LazyRandomTypeCollection(StringRef Data,
+ uint32_t RecordCountHint)
+ : LazyRandomTypeCollection(
+ makeArrayRef(Data.bytes_begin(), Data.bytes_end()), RecordCountHint) {
+}
+
+LazyRandomTypeCollection::LazyRandomTypeCollection(const CVTypeArray &Types,
+ uint32_t NumRecords)
+ : LazyRandomTypeCollection(Types, NumRecords, PartialOffsetArray()) {}
+
+void LazyRandomTypeCollection::reset(BinaryStreamReader &Reader,
+ uint32_t RecordCountHint) {
+ Count = 0;
+ PartialOffsets = PartialOffsetArray();
+
+ error(Reader.readArray(Types, Reader.bytesRemaining()));
+
+ // Clear and then resize, to make sure existing data gets destroyed.
+ Records.clear();
+ Records.resize(RecordCountHint);
+}
+
+void LazyRandomTypeCollection::reset(StringRef Data, uint32_t RecordCountHint) {
+ BinaryStreamReader Reader(Data, support::little);
+ reset(Reader, RecordCountHint);
+}
+
+void LazyRandomTypeCollection::reset(ArrayRef<uint8_t> Data,
+ uint32_t RecordCountHint) {
+ BinaryStreamReader Reader(Data, support::little);
+ reset(Reader, RecordCountHint);
+}
+
+uint32_t LazyRandomTypeCollection::getOffsetOfType(TypeIndex Index) {
+ error(ensureTypeExists(Index));
+ assert(contains(Index));
+
+ return Records[Index.toArrayIndex()].Offset;
+}
+
+CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
+ assert(!Index.isSimple());
+
+ auto EC = ensureTypeExists(Index);
+ error(std::move(EC));
+ assert(contains(Index));
+
+ return Records[Index.toArrayIndex()].Type;
+}
+
+Optional<CVType> LazyRandomTypeCollection::tryGetType(TypeIndex Index) {
+ if (Index.isSimple())
+ return None;
+
+ if (auto EC = ensureTypeExists(Index)) {
+ consumeError(std::move(EC));
+ return None;
+ }
+
+ assert(contains(Index));
+ return Records[Index.toArrayIndex()].Type;
+}
+
+StringRef LazyRandomTypeCollection::getTypeName(TypeIndex Index) {
+ if (Index.isNoneType() || Index.isSimple())
+ return TypeIndex::simpleTypeName(Index);
+
+ // Try to make sure the type exists. Even if it doesn't though, it may be
+ // because we're dumping a symbol stream with no corresponding type stream
+ // present, in which case we still want to be able to print <unknown UDT>
+ // for the type names.
+ if (auto EC = ensureTypeExists(Index)) {
+ consumeError(std::move(EC));
+ return "<unknown UDT>";
+ }
+
+ uint32_t I = Index.toArrayIndex();
+ ensureCapacityFor(Index);
+ if (Records[I].Name.data() == nullptr) {
+ StringRef Result = NameStorage.save(computeTypeName(*this, Index));
+ Records[I].Name = Result;
+ }
+ return Records[I].Name;
+}
+
+bool LazyRandomTypeCollection::contains(TypeIndex Index) {
+ if (Index.isSimple() || Index.isNoneType())
+ return false;
+
+ if (Records.size() <= Index.toArrayIndex())
+ return false;
+ if (!Records[Index.toArrayIndex()].Type.valid())
+ return false;
+ return true;
+}
+
+uint32_t LazyRandomTypeCollection::size() { return Count; }
+
+uint32_t LazyRandomTypeCollection::capacity() { return Records.size(); }
+
+Error LazyRandomTypeCollection::ensureTypeExists(TypeIndex TI) {
+ if (contains(TI))
+ return Error::success();
+
+ return visitRangeForType(TI);
+}
+
+void LazyRandomTypeCollection::ensureCapacityFor(TypeIndex Index) {
+ assert(!Index.isSimple());
+ uint32_t MinSize = Index.toArrayIndex() + 1;
+
+ if (MinSize <= capacity())
+ return;
+
+ uint32_t NewCapacity = MinSize * 3 / 2;
+
+ assert(NewCapacity > capacity());
+ Records.resize(NewCapacity);
+}
+
+Error LazyRandomTypeCollection::visitRangeForType(TypeIndex TI) {
+ assert(!TI.isSimple());
+ if (PartialOffsets.empty())
+ return fullScanForType(TI);
+
auto Next = llvm::upper_bound(PartialOffsets, TI,
[](TypeIndex Value, const TypeIndexOffset &IO) {
return Value < IO.Type;
});
-
- assert(Next != PartialOffsets.begin());
- auto Prev = std::prev(Next);
-
- TypeIndex TIB = Prev->Type;
- if (contains(TIB)) {
- // They've asked us to fetch a type index, but the entry we found in the
- // partial offsets array has already been visited. Since we visit an entire
- // block every time, that means this record should have been previously
+
+ assert(Next != PartialOffsets.begin());
+ auto Prev = std::prev(Next);
+
+ TypeIndex TIB = Prev->Type;
+ if (contains(TIB)) {
+ // They've asked us to fetch a type index, but the entry we found in the
+ // partial offsets array has already been visited. Since we visit an entire
+ // block every time, that means this record should have been previously
// discovered. Ultimately, this means this is a request for a non-existent
- // type index.
- return make_error<CodeViewError>("Invalid type index");
- }
-
- TypeIndex TIE;
- if (Next == PartialOffsets.end()) {
- TIE = TypeIndex::fromArrayIndex(capacity());
- } else {
- TIE = Next->Type;
- }
-
- visitRange(TIB, Prev->Offset, TIE);
- return Error::success();
-}
-
-Optional<TypeIndex> LazyRandomTypeCollection::getFirst() {
- TypeIndex TI = TypeIndex::fromArrayIndex(0);
- if (auto EC = ensureTypeExists(TI)) {
- consumeError(std::move(EC));
- return None;
- }
- return TI;
-}
-
-Optional<TypeIndex> LazyRandomTypeCollection::getNext(TypeIndex Prev) {
- // We can't be sure how long this type stream is, given that the initial count
- // given to the constructor is just a hint. So just try to make sure the next
- // record exists, and if anything goes wrong, we must be at the end.
- if (auto EC = ensureTypeExists(Prev + 1)) {
- consumeError(std::move(EC));
- return None;
- }
-
- return Prev + 1;
-}
-
-Error LazyRandomTypeCollection::fullScanForType(TypeIndex TI) {
- assert(!TI.isSimple());
- assert(PartialOffsets.empty());
-
- TypeIndex CurrentTI = TypeIndex::fromArrayIndex(0);
- auto Begin = Types.begin();
-
- if (Count > 0) {
- // In the case of type streams which we don't know the number of records of,
- // it's possible to search for a type index triggering a full scan, but then
- // later additional records are added since we didn't know how many there
- // would be until we did a full visitation, then you try to access the new
- // type triggering another full scan. To avoid this, we assume that if the
- // database has some records, this must be what's going on. We can also
- // assume that this index must be larger than the largest type index we've
- // visited, so we start from there and scan forward.
- uint32_t Offset = Records[LargestTypeIndex.toArrayIndex()].Offset;
- CurrentTI = LargestTypeIndex + 1;
- Begin = Types.at(Offset);
- ++Begin;
- }
-
- auto End = Types.end();
- while (Begin != End) {
- ensureCapacityFor(CurrentTI);
- LargestTypeIndex = std::max(LargestTypeIndex, CurrentTI);
- auto Idx = CurrentTI.toArrayIndex();
- Records[Idx].Type = *Begin;
- Records[Idx].Offset = Begin.offset();
- ++Count;
- ++Begin;
- ++CurrentTI;
- }
- if (CurrentTI <= TI) {
- return make_error<CodeViewError>("Type Index does not exist!");
- }
- return Error::success();
-}
-
-void LazyRandomTypeCollection::visitRange(TypeIndex Begin, uint32_t BeginOffset,
- TypeIndex End) {
- auto RI = Types.at(BeginOffset);
- assert(RI != Types.end());
-
- ensureCapacityFor(End);
- while (Begin != End) {
- LargestTypeIndex = std::max(LargestTypeIndex, Begin);
- auto Idx = Begin.toArrayIndex();
- Records[Idx].Type = *RI;
- Records[Idx].Offset = RI.offset();
- ++Count;
- ++Begin;
- ++RI;
- }
-}
-
-bool LazyRandomTypeCollection::replaceType(TypeIndex &Index, CVType Data,
- bool Stabilize) {
- llvm_unreachable("Method cannot be called");
-}
+ // type index.
+ return make_error<CodeViewError>("Invalid type index");
+ }
+
+ TypeIndex TIE;
+ if (Next == PartialOffsets.end()) {
+ TIE = TypeIndex::fromArrayIndex(capacity());
+ } else {
+ TIE = Next->Type;
+ }
+
+ visitRange(TIB, Prev->Offset, TIE);
+ return Error::success();
+}
+
+Optional<TypeIndex> LazyRandomTypeCollection::getFirst() {
+ TypeIndex TI = TypeIndex::fromArrayIndex(0);
+ if (auto EC = ensureTypeExists(TI)) {
+ consumeError(std::move(EC));
+ return None;
+ }
+ return TI;
+}
+
+Optional<TypeIndex> LazyRandomTypeCollection::getNext(TypeIndex Prev) {
+ // We can't be sure how long this type stream is, given that the initial count
+ // given to the constructor is just a hint. So just try to make sure the next
+ // record exists, and if anything goes wrong, we must be at the end.
+ if (auto EC = ensureTypeExists(Prev + 1)) {
+ consumeError(std::move(EC));
+ return None;
+ }
+
+ return Prev + 1;
+}
+
+Error LazyRandomTypeCollection::fullScanForType(TypeIndex TI) {
+ assert(!TI.isSimple());
+ assert(PartialOffsets.empty());
+
+ TypeIndex CurrentTI = TypeIndex::fromArrayIndex(0);
+ auto Begin = Types.begin();
+
+ if (Count > 0) {
+ // In the case of type streams which we don't know the number of records of,
+ // it's possible to search for a type index triggering a full scan, but then
+ // later additional records are added since we didn't know how many there
+ // would be until we did a full visitation, then you try to access the new
+ // type triggering another full scan. To avoid this, we assume that if the
+ // database has some records, this must be what's going on. We can also
+ // assume that this index must be larger than the largest type index we've
+ // visited, so we start from there and scan forward.
+ uint32_t Offset = Records[LargestTypeIndex.toArrayIndex()].Offset;
+ CurrentTI = LargestTypeIndex + 1;
+ Begin = Types.at(Offset);
+ ++Begin;
+ }
+
+ auto End = Types.end();
+ while (Begin != End) {
+ ensureCapacityFor(CurrentTI);
+ LargestTypeIndex = std::max(LargestTypeIndex, CurrentTI);
+ auto Idx = CurrentTI.toArrayIndex();
+ Records[Idx].Type = *Begin;
+ Records[Idx].Offset = Begin.offset();
+ ++Count;
+ ++Begin;
+ ++CurrentTI;
+ }
+ if (CurrentTI <= TI) {
+ return make_error<CodeViewError>("Type Index does not exist!");
+ }
+ return Error::success();
+}
+
+void LazyRandomTypeCollection::visitRange(TypeIndex Begin, uint32_t BeginOffset,
+ TypeIndex End) {
+ auto RI = Types.at(BeginOffset);
+ assert(RI != Types.end());
+
+ ensureCapacityFor(End);
+ while (Begin != End) {
+ LargestTypeIndex = std::max(LargestTypeIndex, Begin);
+ auto Idx = Begin.toArrayIndex();
+ Records[Idx].Type = *RI;
+ Records[Idx].Offset = RI.offset();
+ ++Count;
+ ++Begin;
+ ++RI;
+ }
+}
+
+bool LazyRandomTypeCollection::replaceType(TypeIndex &Index, CVType Data,
+ bool Stabilize) {
+ llvm_unreachable("Method cannot be called");
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/Line.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/Line.cpp
index 53adc8cac5..247cd8d9bf 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/Line.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/Line.cpp
@@ -1,21 +1,21 @@
-//===-- Line.cpp ----------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/Line.h"
-
-using namespace llvm;
-using namespace codeview;
-
-LineInfo::LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement) {
- LineData = StartLine & StartLineMask;
- uint32_t LineDelta = EndLine - StartLine;
- LineData |= (LineDelta << EndLineDeltaShift) & EndLineDeltaMask;
- if (IsStatement) {
- LineData |= StatementFlag;
- }
-}
+//===-- Line.cpp ----------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/Line.h"
+
+using namespace llvm;
+using namespace codeview;
+
+LineInfo::LineInfo(uint32_t StartLine, uint32_t EndLine, bool IsStatement) {
+ LineData = StartLine & StartLineMask;
+ uint32_t LineDelta = EndLine - StartLine;
+ LineData |= (LineDelta << EndLineDeltaShift) & EndLineDeltaMask;
+ if (IsStatement) {
+ LineData |= StatementFlag;
+ }
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
index 13ce3ae82c..67200a86aa 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/MergingTypeTableBuilder.cpp
@@ -1,152 +1,152 @@
-//===- MergingTypeTableBuilder.cpp ----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-TypeIndex MergingTypeTableBuilder::nextTypeIndex() const {
- return TypeIndex::fromArrayIndex(SeenRecords.size());
-}
-
-MergingTypeTableBuilder::MergingTypeTableBuilder(BumpPtrAllocator &Storage)
- : RecordStorage(Storage) {
- SeenRecords.reserve(4096);
-}
-
-MergingTypeTableBuilder::~MergingTypeTableBuilder() = default;
-
-Optional<TypeIndex> MergingTypeTableBuilder::getFirst() {
- if (empty())
- return None;
-
- return TypeIndex(TypeIndex::FirstNonSimpleIndex);
-}
-
-Optional<TypeIndex> MergingTypeTableBuilder::getNext(TypeIndex Prev) {
- if (++Prev == nextTypeIndex())
- return None;
- return Prev;
-}
-
-CVType MergingTypeTableBuilder::getType(TypeIndex Index) {
- CVType Type(SeenRecords[Index.toArrayIndex()]);
- return Type;
-}
-
-StringRef MergingTypeTableBuilder::getTypeName(TypeIndex Index) {
- llvm_unreachable("Method not implemented");
-}
-
-bool MergingTypeTableBuilder::contains(TypeIndex Index) {
- if (Index.isSimple() || Index.isNoneType())
- return false;
-
- return Index.toArrayIndex() < SeenRecords.size();
-}
-
-uint32_t MergingTypeTableBuilder::size() { return SeenRecords.size(); }
-
-uint32_t MergingTypeTableBuilder::capacity() { return SeenRecords.size(); }
-
-ArrayRef<ArrayRef<uint8_t>> MergingTypeTableBuilder::records() const {
- return SeenRecords;
-}
-
-void MergingTypeTableBuilder::reset() {
- HashedRecords.clear();
- SeenRecords.clear();
-}
-
-static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
- ArrayRef<uint8_t> Data) {
- uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
- memcpy(Stable, Data.data(), Data.size());
- return makeArrayRef(Stable, Data.size());
-}
-
-TypeIndex MergingTypeTableBuilder::insertRecordAs(hash_code Hash,
- ArrayRef<uint8_t> &Record) {
- assert(Record.size() < UINT32_MAX && "Record too big");
- assert(Record.size() % 4 == 0 &&
- "The type record size is not a multiple of 4 bytes which will cause "
- "misalignment in the output TPI stream!");
-
- LocallyHashedType WeakHash{Hash, Record};
- auto Result = HashedRecords.try_emplace(WeakHash, nextTypeIndex());
-
- if (Result.second) {
- ArrayRef<uint8_t> RecordData = stabilize(RecordStorage, Record);
- Result.first->first.RecordData = RecordData;
- SeenRecords.push_back(RecordData);
- }
-
- // Update the caller's copy of Record to point a stable copy.
- TypeIndex ActualTI = Result.first->second;
- Record = SeenRecords[ActualTI.toArrayIndex()];
- return ActualTI;
-}
-
-TypeIndex
-MergingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) {
- return insertRecordAs(hash_value(Record), Record);
-}
-
-TypeIndex
-MergingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
- TypeIndex TI;
- auto Fragments = Builder.end(nextTypeIndex());
- assert(!Fragments.empty());
- for (auto C : Fragments)
- TI = insertRecordBytes(C.RecordData);
- return TI;
-}
-
-bool MergingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
- bool Stabilize) {
- assert(Index.toArrayIndex() < SeenRecords.size() &&
- "This function cannot be used to insert records!");
-
- ArrayRef<uint8_t> Record = Data.data();
- assert(Record.size() < UINT32_MAX && "Record too big");
- assert(Record.size() % 4 == 0 &&
- "The type record size is not a multiple of 4 bytes which will cause "
- "misalignment in the output TPI stream!");
-
- LocallyHashedType WeakHash{hash_value(Record), Record};
- auto Result = HashedRecords.try_emplace(WeakHash, Index.toArrayIndex());
- if (!Result.second) {
- Index = Result.first->second;
- return false; // The record is already there, at a different location
- }
-
- if (Stabilize) {
- Record = stabilize(RecordStorage, Record);
- Result.first->first.RecordData = Record;
- }
-
- SeenRecords[Index.toArrayIndex()] = Record;
- return true;
-}
+//===- MergingTypeTableBuilder.cpp ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+TypeIndex MergingTypeTableBuilder::nextTypeIndex() const {
+ return TypeIndex::fromArrayIndex(SeenRecords.size());
+}
+
+MergingTypeTableBuilder::MergingTypeTableBuilder(BumpPtrAllocator &Storage)
+ : RecordStorage(Storage) {
+ SeenRecords.reserve(4096);
+}
+
+MergingTypeTableBuilder::~MergingTypeTableBuilder() = default;
+
+Optional<TypeIndex> MergingTypeTableBuilder::getFirst() {
+ if (empty())
+ return None;
+
+ return TypeIndex(TypeIndex::FirstNonSimpleIndex);
+}
+
+Optional<TypeIndex> MergingTypeTableBuilder::getNext(TypeIndex Prev) {
+ if (++Prev == nextTypeIndex())
+ return None;
+ return Prev;
+}
+
+CVType MergingTypeTableBuilder::getType(TypeIndex Index) {
+ CVType Type(SeenRecords[Index.toArrayIndex()]);
+ return Type;
+}
+
+StringRef MergingTypeTableBuilder::getTypeName(TypeIndex Index) {
+ llvm_unreachable("Method not implemented");
+}
+
+bool MergingTypeTableBuilder::contains(TypeIndex Index) {
+ if (Index.isSimple() || Index.isNoneType())
+ return false;
+
+ return Index.toArrayIndex() < SeenRecords.size();
+}
+
+uint32_t MergingTypeTableBuilder::size() { return SeenRecords.size(); }
+
+uint32_t MergingTypeTableBuilder::capacity() { return SeenRecords.size(); }
+
+ArrayRef<ArrayRef<uint8_t>> MergingTypeTableBuilder::records() const {
+ return SeenRecords;
+}
+
+void MergingTypeTableBuilder::reset() {
+ HashedRecords.clear();
+ SeenRecords.clear();
+}
+
+static inline ArrayRef<uint8_t> stabilize(BumpPtrAllocator &Alloc,
+ ArrayRef<uint8_t> Data) {
+ uint8_t *Stable = Alloc.Allocate<uint8_t>(Data.size());
+ memcpy(Stable, Data.data(), Data.size());
+ return makeArrayRef(Stable, Data.size());
+}
+
+TypeIndex MergingTypeTableBuilder::insertRecordAs(hash_code Hash,
+ ArrayRef<uint8_t> &Record) {
+ assert(Record.size() < UINT32_MAX && "Record too big");
+ assert(Record.size() % 4 == 0 &&
+ "The type record size is not a multiple of 4 bytes which will cause "
+ "misalignment in the output TPI stream!");
+
+ LocallyHashedType WeakHash{Hash, Record};
+ auto Result = HashedRecords.try_emplace(WeakHash, nextTypeIndex());
+
+ if (Result.second) {
+ ArrayRef<uint8_t> RecordData = stabilize(RecordStorage, Record);
+ Result.first->first.RecordData = RecordData;
+ SeenRecords.push_back(RecordData);
+ }
+
+ // Update the caller's copy of Record to point a stable copy.
+ TypeIndex ActualTI = Result.first->second;
+ Record = SeenRecords[ActualTI.toArrayIndex()];
+ return ActualTI;
+}
+
+TypeIndex
+MergingTypeTableBuilder::insertRecordBytes(ArrayRef<uint8_t> &Record) {
+ return insertRecordAs(hash_value(Record), Record);
+}
+
+TypeIndex
+MergingTypeTableBuilder::insertRecord(ContinuationRecordBuilder &Builder) {
+ TypeIndex TI;
+ auto Fragments = Builder.end(nextTypeIndex());
+ assert(!Fragments.empty());
+ for (auto C : Fragments)
+ TI = insertRecordBytes(C.RecordData);
+ return TI;
+}
+
+bool MergingTypeTableBuilder::replaceType(TypeIndex &Index, CVType Data,
+ bool Stabilize) {
+ assert(Index.toArrayIndex() < SeenRecords.size() &&
+ "This function cannot be used to insert records!");
+
+ ArrayRef<uint8_t> Record = Data.data();
+ assert(Record.size() < UINT32_MAX && "Record too big");
+ assert(Record.size() % 4 == 0 &&
+ "The type record size is not a multiple of 4 bytes which will cause "
+ "misalignment in the output TPI stream!");
+
+ LocallyHashedType WeakHash{hash_value(Record), Record};
+ auto Result = HashedRecords.try_emplace(WeakHash, Index.toArrayIndex());
+ if (!Result.second) {
+ Index = Result.first->second;
+ return false; // The record is already there, at a different location
+ }
+
+ if (Stabilize) {
+ Record = stabilize(RecordStorage, Record);
+ Result.first->first.RecordData = Record;
+ }
+
+ SeenRecords[Index.toArrayIndex()] = Record;
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp
index 1ca899789b..9bec737a4b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordName.cpp
@@ -1,339 +1,339 @@
-//===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/RecordName.h"
-
-#include "llvm/ADT/SmallString.h"
+//===- RecordName.cpp ----------------------------------------- *- C++ --*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
-#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
-#include "llvm/Support/FormatVariadic.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-namespace {
-class TypeNameComputer : public TypeVisitorCallbacks {
- /// The type collection. Used to calculate names of nested types.
- TypeCollection &Types;
- TypeIndex CurrentTypeIndex = TypeIndex::None();
-
- /// Name of the current type. Only valid before visitTypeEnd.
- SmallString<256> Name;
-
-public:
- explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
-
- StringRef name() const { return Name; }
-
- /// Paired begin/end actions for all types. Receives all record data,
- /// including the fixed-length record prefix.
- Error visitTypeBegin(CVType &Record) override;
- Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
- Error visitTypeEnd(CVType &Record) override;
-
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name)
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
-};
-} // namespace
-
-Error TypeNameComputer::visitTypeBegin(CVType &Record) {
- llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
- return Error::success();
-}
-
-Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
- // Reset Name to the empty string. If the visitor sets it, we know it.
- Name = "";
- CurrentTypeIndex = Index;
- return Error::success();
-}
-
-Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- FieldListRecord &FieldList) {
- Name = "<field list>";
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
- StringIdRecord &String) {
- Name = String.getString();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
- auto Indices = Args.getIndices();
- uint32_t Size = Indices.size();
- Name = "(";
- for (uint32_t I = 0; I < Size; ++I) {
+#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
+#include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+namespace {
+class TypeNameComputer : public TypeVisitorCallbacks {
+ /// The type collection. Used to calculate names of nested types.
+ TypeCollection &Types;
+ TypeIndex CurrentTypeIndex = TypeIndex::None();
+
+ /// Name of the current type. Only valid before visitTypeEnd.
+ SmallString<256> Name;
+
+public:
+ explicit TypeNameComputer(TypeCollection &Types) : Types(Types) {}
+
+ StringRef name() const { return Name; }
+
+ /// Paired begin/end actions for all types. Receives all record data,
+ /// including the fixed-length record prefix.
+ Error visitTypeBegin(CVType &Record) override;
+ Error visitTypeBegin(CVType &Record, TypeIndex Index) override;
+ Error visitTypeEnd(CVType &Record) override;
+
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVType &CVR, Name##Record &Record) override;
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+};
+} // namespace
+
+Error TypeNameComputer::visitTypeBegin(CVType &Record) {
+ llvm_unreachable("Must call visitTypeBegin with a TypeIndex!");
+ return Error::success();
+}
+
+Error TypeNameComputer::visitTypeBegin(CVType &Record, TypeIndex Index) {
+ // Reset Name to the empty string. If the visitor sets it, we know it.
+ Name = "";
+ CurrentTypeIndex = Index;
+ return Error::success();
+}
+
+Error TypeNameComputer::visitTypeEnd(CVType &CVR) { return Error::success(); }
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ FieldListRecord &FieldList) {
+ Name = "<field list>";
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVRecord<TypeLeafKind> &CVR,
+ StringIdRecord &String) {
+ Name = String.getString();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
+ auto Indices = Args.getIndices();
+ uint32_t Size = Indices.size();
+ Name = "(";
+ for (uint32_t I = 0; I < Size; ++I) {
if (Indices[I] < CurrentTypeIndex)
Name.append(Types.getTypeName(Indices[I]));
else
Name.append("<unknown 0x" + utohexstr(Indices[I].getIndex()) + ">");
- if (I + 1 != Size)
- Name.append(", ");
- }
- Name.push_back(')');
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- StringListRecord &Strings) {
- auto Indices = Strings.getIndices();
- uint32_t Size = Indices.size();
- Name = "\"";
- for (uint32_t I = 0; I < Size; ++I) {
- Name.append(Types.getTypeName(Indices[I]));
- if (I + 1 != Size)
- Name.append("\" \"");
- }
- Name.push_back('\"');
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
- Name = Class.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
- Name = Union.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
- Name = Enum.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
- Name = AT.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
- Name = VFT.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
- Name = Id.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
- StringRef Ret = Types.getTypeName(Proc.getReturnType());
- StringRef Params = Types.getTypeName(Proc.getArgumentList());
- Name = formatv("{0} {1}", Ret, Params).sstr<256>();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- MemberFunctionRecord &MF) {
- StringRef Ret = Types.getTypeName(MF.getReturnType());
- StringRef Class = Types.getTypeName(MF.getClassType());
- StringRef Params = Types.getTypeName(MF.getArgumentList());
- Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
- Name = Func.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
- Name = TS.getName();
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
-
- if (Ptr.isPointerToMember()) {
- const MemberPointerInfo &MI = Ptr.getMemberInfo();
-
- StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
- StringRef Class = Types.getTypeName(MI.getContainingType());
- Name = formatv("{0} {1}::*", Pointee, Class);
- } else {
- Name.append(Types.getTypeName(Ptr.getReferentType()));
-
- if (Ptr.getMode() == PointerMode::LValueReference)
- Name.append("&");
- else if (Ptr.getMode() == PointerMode::RValueReference)
- Name.append("&&");
- else if (Ptr.getMode() == PointerMode::Pointer)
- Name.append("*");
-
- // Qualifiers in pointer records apply to the pointer, not the pointee, so
- // they go on the right.
- if (Ptr.isConst())
- Name.append(" const");
- if (Ptr.isVolatile())
- Name.append(" volatile");
- if (Ptr.isUnaligned())
- Name.append(" __unaligned");
- if (Ptr.isRestrict())
- Name.append(" __restrict");
- }
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
- uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
-
- if (Mods & uint16_t(ModifierOptions::Const))
- Name.append("const ");
- if (Mods & uint16_t(ModifierOptions::Volatile))
- Name.append("volatile ");
- if (Mods & uint16_t(ModifierOptions::Unaligned))
- Name.append("__unaligned ");
- Name.append(Types.getTypeName(Mod.getModifiedType()));
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- VFTableShapeRecord &Shape) {
- Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(
- CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- UdtSourceLineRecord &SourceLine) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- MethodOverloadListRecord &Overloads) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- PrecompRecord &Precomp) {
- return Error::success();
-}
-
-Error TypeNameComputer::visitKnownRecord(CVType &CVR,
- EndPrecompRecord &EndPrecomp) {
- return Error::success();
-}
-
-std::string llvm::codeview::computeTypeName(TypeCollection &Types,
- TypeIndex Index) {
- TypeNameComputer Computer(Types);
- CVType Record = Types.getType(Index);
- if (auto EC = visitTypeRecord(Record, Index, Computer)) {
- consumeError(std::move(EC));
- return "<unknown UDT>";
- }
- return std::string(Computer.name());
-}
-
-static int getSymbolNameOffset(CVSymbol Sym) {
- switch (Sym.kind()) {
- // See ProcSym
- 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:
- return 35;
- // See Thunk32Sym
- case SymbolKind::S_THUNK32:
- return 21;
- // See SectionSym
- case SymbolKind::S_SECTION:
- return 16;
- // See CoffGroupSym
- case SymbolKind::S_COFFGROUP:
- return 14;
- // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
- case SymbolKind::S_PUB32:
- case SymbolKind::S_FILESTATIC:
- case SymbolKind::S_REGREL32:
- case SymbolKind::S_GDATA32:
- case SymbolKind::S_LDATA32:
- case SymbolKind::S_LMANDATA:
- case SymbolKind::S_GMANDATA:
- case SymbolKind::S_LTHREAD32:
- case SymbolKind::S_GTHREAD32:
- case SymbolKind::S_PROCREF:
- case SymbolKind::S_LPROCREF:
- return 10;
- // See RegisterSym and LocalSym
- case SymbolKind::S_REGISTER:
- case SymbolKind::S_LOCAL:
- return 6;
- // See BlockSym
- case SymbolKind::S_BLOCK32:
- return 18;
- // See LabelSym
- case SymbolKind::S_LABEL32:
- return 7;
- // See ObjNameSym, ExportSym, and UDTSym
- case SymbolKind::S_OBJNAME:
- case SymbolKind::S_EXPORT:
- case SymbolKind::S_UDT:
- return 4;
- // See BPRelativeSym
- case SymbolKind::S_BPREL32:
- return 8;
- // See UsingNamespaceSym
- case SymbolKind::S_UNAMESPACE:
- return 0;
- default:
- return -1;
- }
-}
-
-StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
- if (Sym.kind() == SymbolKind::S_CONSTANT) {
- // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
- // have to do a full deserialization.
- BinaryStreamReader Reader(Sym.content(), llvm::support::little);
- // The container doesn't matter for single records.
- SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
- ConstantSym Const(SymbolKind::S_CONSTANT);
- cantFail(Mapping.visitSymbolBegin(Sym));
- cantFail(Mapping.visitKnownRecord(Sym, Const));
- cantFail(Mapping.visitSymbolEnd(Sym));
- return Const.Name;
- }
-
- int Offset = getSymbolNameOffset(Sym);
- if (Offset == -1)
- return StringRef();
-
- StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
- return StringData.split('\0').first;
-}
+ if (I + 1 != Size)
+ Name.append(", ");
+ }
+ Name.push_back(')');
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ StringListRecord &Strings) {
+ auto Indices = Strings.getIndices();
+ uint32_t Size = Indices.size();
+ Name = "\"";
+ for (uint32_t I = 0; I < Size; ++I) {
+ Name.append(Types.getTypeName(Indices[I]));
+ if (I + 1 != Size)
+ Name.append("\" \"");
+ }
+ Name.push_back('\"');
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
+ Name = Class.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
+ Name = Union.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
+ Name = Enum.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
+ Name = AT.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
+ Name = VFT.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
+ Name = Id.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
+ StringRef Ret = Types.getTypeName(Proc.getReturnType());
+ StringRef Params = Types.getTypeName(Proc.getArgumentList());
+ Name = formatv("{0} {1}", Ret, Params).sstr<256>();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ MemberFunctionRecord &MF) {
+ StringRef Ret = Types.getTypeName(MF.getReturnType());
+ StringRef Class = Types.getTypeName(MF.getClassType());
+ StringRef Params = Types.getTypeName(MF.getArgumentList());
+ Name = formatv("{0} {1}::{2}", Ret, Class, Params).sstr<256>();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
+ Name = Func.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
+ Name = TS.getName();
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
+
+ if (Ptr.isPointerToMember()) {
+ const MemberPointerInfo &MI = Ptr.getMemberInfo();
+
+ StringRef Pointee = Types.getTypeName(Ptr.getReferentType());
+ StringRef Class = Types.getTypeName(MI.getContainingType());
+ Name = formatv("{0} {1}::*", Pointee, Class);
+ } else {
+ Name.append(Types.getTypeName(Ptr.getReferentType()));
+
+ if (Ptr.getMode() == PointerMode::LValueReference)
+ Name.append("&");
+ else if (Ptr.getMode() == PointerMode::RValueReference)
+ Name.append("&&");
+ else if (Ptr.getMode() == PointerMode::Pointer)
+ Name.append("*");
+
+ // Qualifiers in pointer records apply to the pointer, not the pointee, so
+ // they go on the right.
+ if (Ptr.isConst())
+ Name.append(" const");
+ if (Ptr.isVolatile())
+ Name.append(" volatile");
+ if (Ptr.isUnaligned())
+ Name.append(" __unaligned");
+ if (Ptr.isRestrict())
+ Name.append(" __restrict");
+ }
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
+ uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
+
+ if (Mods & uint16_t(ModifierOptions::Const))
+ Name.append("const ");
+ if (Mods & uint16_t(ModifierOptions::Volatile))
+ Name.append("volatile ");
+ if (Mods & uint16_t(ModifierOptions::Unaligned))
+ Name.append("__unaligned ");
+ Name.append(Types.getTypeName(Mod.getModifiedType()));
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ VFTableShapeRecord &Shape) {
+ Name = formatv("<vftable {0} methods>", Shape.getEntryCount());
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(
+ CVType &CVR, UdtModSourceLineRecord &ModSourceLine) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ UdtSourceLineRecord &SourceLine) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, BitFieldRecord &BF) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ MethodOverloadListRecord &Overloads) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, BuildInfoRecord &BI) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR, LabelRecord &R) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ PrecompRecord &Precomp) {
+ return Error::success();
+}
+
+Error TypeNameComputer::visitKnownRecord(CVType &CVR,
+ EndPrecompRecord &EndPrecomp) {
+ return Error::success();
+}
+
+std::string llvm::codeview::computeTypeName(TypeCollection &Types,
+ TypeIndex Index) {
+ TypeNameComputer Computer(Types);
+ CVType Record = Types.getType(Index);
+ if (auto EC = visitTypeRecord(Record, Index, Computer)) {
+ consumeError(std::move(EC));
+ return "<unknown UDT>";
+ }
+ return std::string(Computer.name());
+}
+
+static int getSymbolNameOffset(CVSymbol Sym) {
+ switch (Sym.kind()) {
+ // See ProcSym
+ 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:
+ return 35;
+ // See Thunk32Sym
+ case SymbolKind::S_THUNK32:
+ return 21;
+ // See SectionSym
+ case SymbolKind::S_SECTION:
+ return 16;
+ // See CoffGroupSym
+ case SymbolKind::S_COFFGROUP:
+ return 14;
+ // See PublicSym32, FileStaticSym, RegRelativeSym, DataSym, ThreadLocalDataSym
+ case SymbolKind::S_PUB32:
+ case SymbolKind::S_FILESTATIC:
+ case SymbolKind::S_REGREL32:
+ case SymbolKind::S_GDATA32:
+ case SymbolKind::S_LDATA32:
+ case SymbolKind::S_LMANDATA:
+ case SymbolKind::S_GMANDATA:
+ case SymbolKind::S_LTHREAD32:
+ case SymbolKind::S_GTHREAD32:
+ case SymbolKind::S_PROCREF:
+ case SymbolKind::S_LPROCREF:
+ return 10;
+ // See RegisterSym and LocalSym
+ case SymbolKind::S_REGISTER:
+ case SymbolKind::S_LOCAL:
+ return 6;
+ // See BlockSym
+ case SymbolKind::S_BLOCK32:
+ return 18;
+ // See LabelSym
+ case SymbolKind::S_LABEL32:
+ return 7;
+ // See ObjNameSym, ExportSym, and UDTSym
+ case SymbolKind::S_OBJNAME:
+ case SymbolKind::S_EXPORT:
+ case SymbolKind::S_UDT:
+ return 4;
+ // See BPRelativeSym
+ case SymbolKind::S_BPREL32:
+ return 8;
+ // See UsingNamespaceSym
+ case SymbolKind::S_UNAMESPACE:
+ return 0;
+ default:
+ return -1;
+ }
+}
+
+StringRef llvm::codeview::getSymbolName(CVSymbol Sym) {
+ if (Sym.kind() == SymbolKind::S_CONSTANT) {
+ // S_CONSTANT is preceded by an APSInt, which has a variable length. So we
+ // have to do a full deserialization.
+ BinaryStreamReader Reader(Sym.content(), llvm::support::little);
+ // The container doesn't matter for single records.
+ SymbolRecordMapping Mapping(Reader, CodeViewContainer::ObjectFile);
+ ConstantSym Const(SymbolKind::S_CONSTANT);
+ cantFail(Mapping.visitSymbolBegin(Sym));
+ cantFail(Mapping.visitKnownRecord(Sym, Const));
+ cantFail(Mapping.visitSymbolEnd(Sym));
+ return Const.Name;
+ }
+
+ int Offset = getSymbolNameOffset(Sym);
+ if (Offset == -1)
+ return StringRef();
+
+ StringRef StringData = toStringRef(Sym.content()).drop_front(Offset);
+ return StringData.split('\0').first;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp
index 63ce302a4e..ff364069ee 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/RecordSerialization.cpp
@@ -1,154 +1,154 @@
-//===-- RecordSerialization.cpp -------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Utilities for serializing and deserializing CodeView records.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
-#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/APSInt.h"
-#include "llvm/DebugInfo/CodeView/CodeViewError.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/Support/BinaryByteStream.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::support;
-
-/// Reinterpret a byte array as an array of characters. Does not interpret as
-/// a C string, as StringRef has several helpers (split) that make that easy.
-StringRef llvm::codeview::getBytesAsCharacters(ArrayRef<uint8_t> LeafData) {
- return StringRef(reinterpret_cast<const char *>(LeafData.data()),
- LeafData.size());
-}
-
-StringRef llvm::codeview::getBytesAsCString(ArrayRef<uint8_t> LeafData) {
- return getBytesAsCharacters(LeafData).split('\0').first;
-}
-
-Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
+//===-- RecordSerialization.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Utilities for serializing and deserializing CodeView records.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/RecordSerialization.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
+#include "llvm/DebugInfo/CodeView/CodeViewError.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/BinaryByteStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::support;
+
+/// Reinterpret a byte array as an array of characters. Does not interpret as
+/// a C string, as StringRef has several helpers (split) that make that easy.
+StringRef llvm::codeview::getBytesAsCharacters(ArrayRef<uint8_t> LeafData) {
+ return StringRef(reinterpret_cast<const char *>(LeafData.data()),
+ LeafData.size());
+}
+
+StringRef llvm::codeview::getBytesAsCString(ArrayRef<uint8_t> LeafData) {
+ return getBytesAsCharacters(LeafData).split('\0').first;
+}
+
+Error llvm::codeview::consume(BinaryStreamReader &Reader, APSInt &Num) {
// Used to avoid overload ambiguity on APInt constructor.
- bool FalseVal = false;
- uint16_t Short;
- if (auto EC = Reader.readInteger(Short))
- return EC;
-
- if (Short < LF_NUMERIC) {
- Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
- /*isUnsigned=*/true);
- return Error::success();
- }
-
- switch (Short) {
- case LF_CHAR: {
- int8_t N;
- if (auto EC = Reader.readInteger(N))
- return EC;
- Num = APSInt(APInt(8, N, true), false);
- return Error::success();
- }
- case LF_SHORT: {
- int16_t N;
- if (auto EC = Reader.readInteger(N))
- return EC;
- Num = APSInt(APInt(16, N, true), false);
- return Error::success();
- }
- case LF_USHORT: {
- uint16_t N;
- if (auto EC = Reader.readInteger(N))
- return EC;
- Num = APSInt(APInt(16, N, false), true);
- return Error::success();
- }
- case LF_LONG: {
- int32_t N;
- if (auto EC = Reader.readInteger(N))
- return EC;
- Num = APSInt(APInt(32, N, true), false);
- return Error::success();
- }
- case LF_ULONG: {
- uint32_t N;
- if (auto EC = Reader.readInteger(N))
- return EC;
- Num = APSInt(APInt(32, N, FalseVal), true);
- return Error::success();
- }
- case LF_QUADWORD: {
- int64_t N;
- if (auto EC = Reader.readInteger(N))
- return EC;
- Num = APSInt(APInt(64, N, true), false);
- return Error::success();
- }
- case LF_UQUADWORD: {
- uint64_t N;
- if (auto EC = Reader.readInteger(N))
- return EC;
- Num = APSInt(APInt(64, N, false), true);
- return Error::success();
- }
- }
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Buffer contains invalid APSInt type");
-}
-
-Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
- ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
- BinaryByteStream S(Bytes, llvm::support::little);
- BinaryStreamReader SR(S);
- auto EC = consume(SR, Num);
- Data = Data.take_back(SR.bytesRemaining());
- return EC;
-}
-
-/// Decode a numeric leaf value that is known to be a uint64_t.
-Error llvm::codeview::consume_numeric(BinaryStreamReader &Reader,
- uint64_t &Num) {
- APSInt N;
- if (auto EC = consume(Reader, N))
- return EC;
- if (N.isSigned() || !N.isIntN(64))
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Data is not a numeric value!");
- Num = N.getLimitedValue();
- return Error::success();
-}
-
-Error llvm::codeview::consume(BinaryStreamReader &Reader, uint32_t &Item) {
- return Reader.readInteger(Item);
-}
-
-Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
- ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
- BinaryByteStream S(Bytes, llvm::support::little);
- BinaryStreamReader SR(S);
- auto EC = consume(SR, Item);
- Data = Data.take_back(SR.bytesRemaining());
- return EC;
-}
-
-Error llvm::codeview::consume(BinaryStreamReader &Reader, int32_t &Item) {
- return Reader.readInteger(Item);
-}
-
-Error llvm::codeview::consume(BinaryStreamReader &Reader, StringRef &Item) {
- if (Reader.empty())
- return make_error<CodeViewError>(cv_error_code::corrupt_record,
- "Null terminated string buffer is empty!");
-
- return Reader.readCString(Item);
-}
-
-Expected<CVSymbol> llvm::codeview::readSymbolFromStream(BinaryStreamRef Stream,
- uint32_t Offset) {
- return readCVRecordFromStream<SymbolKind>(Stream, Offset);
-}
+ bool FalseVal = false;
+ uint16_t Short;
+ if (auto EC = Reader.readInteger(Short))
+ return EC;
+
+ if (Short < LF_NUMERIC) {
+ Num = APSInt(APInt(/*numBits=*/16, Short, /*isSigned=*/false),
+ /*isUnsigned=*/true);
+ return Error::success();
+ }
+
+ switch (Short) {
+ case LF_CHAR: {
+ int8_t N;
+ if (auto EC = Reader.readInteger(N))
+ return EC;
+ Num = APSInt(APInt(8, N, true), false);
+ return Error::success();
+ }
+ case LF_SHORT: {
+ int16_t N;
+ if (auto EC = Reader.readInteger(N))
+ return EC;
+ Num = APSInt(APInt(16, N, true), false);
+ return Error::success();
+ }
+ case LF_USHORT: {
+ uint16_t N;
+ if (auto EC = Reader.readInteger(N))
+ return EC;
+ Num = APSInt(APInt(16, N, false), true);
+ return Error::success();
+ }
+ case LF_LONG: {
+ int32_t N;
+ if (auto EC = Reader.readInteger(N))
+ return EC;
+ Num = APSInt(APInt(32, N, true), false);
+ return Error::success();
+ }
+ case LF_ULONG: {
+ uint32_t N;
+ if (auto EC = Reader.readInteger(N))
+ return EC;
+ Num = APSInt(APInt(32, N, FalseVal), true);
+ return Error::success();
+ }
+ case LF_QUADWORD: {
+ int64_t N;
+ if (auto EC = Reader.readInteger(N))
+ return EC;
+ Num = APSInt(APInt(64, N, true), false);
+ return Error::success();
+ }
+ case LF_UQUADWORD: {
+ uint64_t N;
+ if (auto EC = Reader.readInteger(N))
+ return EC;
+ Num = APSInt(APInt(64, N, false), true);
+ return Error::success();
+ }
+ }
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Buffer contains invalid APSInt type");
+}
+
+Error llvm::codeview::consume(StringRef &Data, APSInt &Num) {
+ ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
+ BinaryByteStream S(Bytes, llvm::support::little);
+ BinaryStreamReader SR(S);
+ auto EC = consume(SR, Num);
+ Data = Data.take_back(SR.bytesRemaining());
+ return EC;
+}
+
+/// Decode a numeric leaf value that is known to be a uint64_t.
+Error llvm::codeview::consume_numeric(BinaryStreamReader &Reader,
+ uint64_t &Num) {
+ APSInt N;
+ if (auto EC = consume(Reader, N))
+ return EC;
+ if (N.isSigned() || !N.isIntN(64))
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Data is not a numeric value!");
+ Num = N.getLimitedValue();
+ return Error::success();
+}
+
+Error llvm::codeview::consume(BinaryStreamReader &Reader, uint32_t &Item) {
+ return Reader.readInteger(Item);
+}
+
+Error llvm::codeview::consume(StringRef &Data, uint32_t &Item) {
+ ArrayRef<uint8_t> Bytes(Data.bytes_begin(), Data.bytes_end());
+ BinaryByteStream S(Bytes, llvm::support::little);
+ BinaryStreamReader SR(S);
+ auto EC = consume(SR, Item);
+ Data = Data.take_back(SR.bytesRemaining());
+ return EC;
+}
+
+Error llvm::codeview::consume(BinaryStreamReader &Reader, int32_t &Item) {
+ return Reader.readInteger(Item);
+}
+
+Error llvm::codeview::consume(BinaryStreamReader &Reader, StringRef &Item) {
+ if (Reader.empty())
+ return make_error<CodeViewError>(cv_error_code::corrupt_record,
+ "Null terminated string buffer is empty!");
+
+ return Reader.readCString(Item);
+}
+
+Expected<CVSymbol> llvm::codeview::readSymbolFromStream(BinaryStreamRef Stream,
+ uint32_t Offset) {
+ return readCVRecordFromStream<SymbolKind>(Stream, Offset);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp
index ac3b301759..dd542a142d 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SimpleTypeSerializer.cpp
@@ -1,67 +1,67 @@
-//===- SimpleTypeSerializer.cpp -----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-static void addPadding(BinaryStreamWriter &Writer) {
- uint32_t Align = Writer.getOffset() % 4;
- if (Align == 0)
- return;
-
- int PaddingBytes = 4 - Align;
- while (PaddingBytes > 0) {
- uint8_t Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
- cantFail(Writer.writeInteger(Pad));
- --PaddingBytes;
- }
-}
-
-SimpleTypeSerializer::SimpleTypeSerializer() : ScratchBuffer(MaxRecordLength) {}
-
-SimpleTypeSerializer::~SimpleTypeSerializer() {}
-
-template <typename T>
-ArrayRef<uint8_t> SimpleTypeSerializer::serialize(T &Record) {
- BinaryStreamWriter Writer(ScratchBuffer, support::little);
- TypeRecordMapping Mapping(Writer);
-
- // Write the record prefix first with a dummy length but real kind.
- RecordPrefix DummyPrefix(uint16_t(Record.getKind()));
- cantFail(Writer.writeObject(DummyPrefix));
-
- RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(ScratchBuffer.data());
- CVType CVT(Prefix, sizeof(RecordPrefix));
-
- cantFail(Mapping.visitTypeBegin(CVT));
- cantFail(Mapping.visitKnownRecord(CVT, Record));
- cantFail(Mapping.visitTypeEnd(CVT));
-
- addPadding(Writer);
-
- // Update the size and kind after serialization.
- Prefix->RecordKind = CVT.kind();
- Prefix->RecordLen = Writer.getOffset() - sizeof(uint16_t);
-
- return {ScratchBuffer.data(), Writer.getOffset()};
-}
-
-// Explicitly instantiate the member function for each known type so that we can
-// implement this in the cpp file.
-#define TYPE_RECORD(EnumName, EnumVal, Name) \
- template ArrayRef<uint8_t> llvm::codeview::SimpleTypeSerializer::serialize( \
- Name##Record &Record);
-#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#define MEMBER_RECORD(EnumName, EnumVal, Name)
-#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+//===- SimpleTypeSerializer.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/SimpleTypeSerializer.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+static void addPadding(BinaryStreamWriter &Writer) {
+ uint32_t Align = Writer.getOffset() % 4;
+ if (Align == 0)
+ return;
+
+ int PaddingBytes = 4 - Align;
+ while (PaddingBytes > 0) {
+ uint8_t Pad = static_cast<uint8_t>(LF_PAD0 + PaddingBytes);
+ cantFail(Writer.writeInteger(Pad));
+ --PaddingBytes;
+ }
+}
+
+SimpleTypeSerializer::SimpleTypeSerializer() : ScratchBuffer(MaxRecordLength) {}
+
+SimpleTypeSerializer::~SimpleTypeSerializer() {}
+
+template <typename T>
+ArrayRef<uint8_t> SimpleTypeSerializer::serialize(T &Record) {
+ BinaryStreamWriter Writer(ScratchBuffer, support::little);
+ TypeRecordMapping Mapping(Writer);
+
+ // Write the record prefix first with a dummy length but real kind.
+ RecordPrefix DummyPrefix(uint16_t(Record.getKind()));
+ cantFail(Writer.writeObject(DummyPrefix));
+
+ RecordPrefix *Prefix = reinterpret_cast<RecordPrefix *>(ScratchBuffer.data());
+ CVType CVT(Prefix, sizeof(RecordPrefix));
+
+ cantFail(Mapping.visitTypeBegin(CVT));
+ cantFail(Mapping.visitKnownRecord(CVT, Record));
+ cantFail(Mapping.visitTypeEnd(CVT));
+
+ addPadding(Writer);
+
+ // Update the size and kind after serialization.
+ Prefix->RecordKind = CVT.kind();
+ Prefix->RecordLen = Writer.getOffset() - sizeof(uint16_t);
+
+ return {ScratchBuffer.data(), Writer.getOffset()};
+}
+
+// Explicitly instantiate the member function for each known type so that we can
+// implement this in the cpp file.
+#define TYPE_RECORD(EnumName, EnumVal, Name) \
+ template ArrayRef<uint8_t> llvm::codeview::SimpleTypeSerializer::serialize( \
+ Name##Record &Record);
+#define TYPE_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#define MEMBER_RECORD(EnumName, EnumVal, Name)
+#define MEMBER_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/StringsAndChecksums.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
index 9e204eec86..3f11d2775b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/StringsAndChecksums.cpp
@@ -1,80 +1,80 @@
-//===- StringsAndChecksums.cpp --------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-StringsAndChecksumsRef::StringsAndChecksumsRef() = default;
-
-StringsAndChecksumsRef::StringsAndChecksumsRef(
- const DebugStringTableSubsectionRef &Strings)
- : Strings(&Strings) {}
-
-StringsAndChecksumsRef::StringsAndChecksumsRef(
- const DebugStringTableSubsectionRef &Strings,
- const DebugChecksumsSubsectionRef &Checksums)
- : Strings(&Strings), Checksums(&Checksums) {}
-
-void StringsAndChecksumsRef::initializeStrings(
- const DebugSubsectionRecord &SR) {
- assert(SR.kind() == DebugSubsectionKind::StringTable);
- assert(!Strings && "Found a string table even though we already have one!");
-
- OwnedStrings = std::make_shared<DebugStringTableSubsectionRef>();
- consumeError(OwnedStrings->initialize(SR.getRecordData()));
- Strings = OwnedStrings.get();
-}
-
-void StringsAndChecksumsRef::reset() {
- resetStrings();
- resetChecksums();
-}
-
-void StringsAndChecksumsRef::resetStrings() {
- OwnedStrings.reset();
- Strings = nullptr;
-}
-
-void StringsAndChecksumsRef::resetChecksums() {
- OwnedChecksums.reset();
- Checksums = nullptr;
-}
-
-void StringsAndChecksumsRef::setStrings(
- const DebugStringTableSubsectionRef &StringsRef) {
- OwnedStrings = std::make_shared<DebugStringTableSubsectionRef>();
- *OwnedStrings = StringsRef;
- Strings = OwnedStrings.get();
-}
-
-void StringsAndChecksumsRef::setChecksums(
- const DebugChecksumsSubsectionRef &CS) {
- OwnedChecksums = std::make_shared<DebugChecksumsSubsectionRef>();
- *OwnedChecksums = CS;
- Checksums = OwnedChecksums.get();
-}
-
-void StringsAndChecksumsRef::initializeChecksums(
- const DebugSubsectionRecord &FCR) {
- assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
- if (Checksums)
- return;
-
- OwnedChecksums = std::make_shared<DebugChecksumsSubsectionRef>();
- consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
- Checksums = OwnedChecksums.get();
-}
+//===- StringsAndChecksums.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/StringsAndChecksums.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+StringsAndChecksumsRef::StringsAndChecksumsRef() = default;
+
+StringsAndChecksumsRef::StringsAndChecksumsRef(
+ const DebugStringTableSubsectionRef &Strings)
+ : Strings(&Strings) {}
+
+StringsAndChecksumsRef::StringsAndChecksumsRef(
+ const DebugStringTableSubsectionRef &Strings,
+ const DebugChecksumsSubsectionRef &Checksums)
+ : Strings(&Strings), Checksums(&Checksums) {}
+
+void StringsAndChecksumsRef::initializeStrings(
+ const DebugSubsectionRecord &SR) {
+ assert(SR.kind() == DebugSubsectionKind::StringTable);
+ assert(!Strings && "Found a string table even though we already have one!");
+
+ OwnedStrings = std::make_shared<DebugStringTableSubsectionRef>();
+ consumeError(OwnedStrings->initialize(SR.getRecordData()));
+ Strings = OwnedStrings.get();
+}
+
+void StringsAndChecksumsRef::reset() {
+ resetStrings();
+ resetChecksums();
+}
+
+void StringsAndChecksumsRef::resetStrings() {
+ OwnedStrings.reset();
+ Strings = nullptr;
+}
+
+void StringsAndChecksumsRef::resetChecksums() {
+ OwnedChecksums.reset();
+ Checksums = nullptr;
+}
+
+void StringsAndChecksumsRef::setStrings(
+ const DebugStringTableSubsectionRef &StringsRef) {
+ OwnedStrings = std::make_shared<DebugStringTableSubsectionRef>();
+ *OwnedStrings = StringsRef;
+ Strings = OwnedStrings.get();
+}
+
+void StringsAndChecksumsRef::setChecksums(
+ const DebugChecksumsSubsectionRef &CS) {
+ OwnedChecksums = std::make_shared<DebugChecksumsSubsectionRef>();
+ *OwnedChecksums = CS;
+ Checksums = OwnedChecksums.get();
+}
+
+void StringsAndChecksumsRef::initializeChecksums(
+ const DebugSubsectionRecord &FCR) {
+ assert(FCR.kind() == DebugSubsectionKind::FileChecksums);
+ if (Checksums)
+ return;
+
+ OwnedChecksums = std::make_shared<DebugChecksumsSubsectionRef>();
+ consumeError(OwnedChecksums->initialize(FCR.getRecordData()));
+ Checksums = OwnedChecksums.get();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolDumper.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolDumper.cpp
index 45b63983be..e130f8b3d2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolDumper.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolDumper.cpp
@@ -1,679 +1,679 @@
-//===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
-#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
-#include "llvm/DebugInfo/CodeView/EnumTables.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
-#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-#include <system_error>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-namespace {
-/// Use this private dumper implementation to keep implementation details about
-/// the visitor out of SymbolDumper.h.
-class CVSymbolDumperImpl : public SymbolVisitorCallbacks {
-public:
- CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate,
- ScopedPrinter &W, CPUType CPU, bool PrintRecordBytes)
- : Types(Types), ObjDelegate(ObjDelegate), W(W), CompilationCPUType(CPU),
- PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
-
-/// CVSymbolVisitor overrides.
-#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
-#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
-#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
-
- Error visitSymbolBegin(CVSymbol &Record) override;
- Error visitSymbolEnd(CVSymbol &Record) override;
- Error visitUnknownSymbol(CVSymbol &Record) override;
-
- CPUType getCompilationCPUType() const { return CompilationCPUType; }
-
-private:
- void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
- uint32_t RelocationOffset);
- void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
- void printTypeIndex(StringRef FieldName, TypeIndex TI);
-
- TypeCollection &Types;
- SymbolDumpDelegate *ObjDelegate;
- ScopedPrinter &W;
-
- /// Save the machine or CPU type when dumping a compile symbols.
- CPUType CompilationCPUType = CPUType::X64;
-
- bool PrintRecordBytes;
- bool InFunctionScope;
-};
-}
-
-static StringRef getSymbolKindName(SymbolKind Kind) {
- switch (Kind) {
-#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
- case EnumName: \
- return #Name;
-#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
- default:
- break;
- }
- return "UnknownSym";
-}
-
-void CVSymbolDumperImpl::printLocalVariableAddrRange(
- const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
- DictScope S(W, "LocalVariableAddrRange");
- if (ObjDelegate)
- ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
- Range.OffsetStart);
- W.printHex("ISectStart", Range.ISectStart);
- W.printHex("Range", Range.Range);
-}
-
-void CVSymbolDumperImpl::printLocalVariableAddrGap(
- ArrayRef<LocalVariableAddrGap> Gaps) {
- for (auto &Gap : Gaps) {
- ListScope S(W, "LocalVariableAddrGap");
- W.printHex("GapStartOffset", Gap.GapStartOffset);
- W.printHex("Range", Gap.Range);
- }
-}
-
-void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
- codeview::printTypeIndex(W, FieldName, TI, Types);
-}
-
-Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
- W.startLine() << getSymbolKindName(CVR.kind());
- W.getOStream() << " {\n";
- W.indent();
- W.printEnum("Kind", unsigned(CVR.kind()), getSymbolTypeNames());
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) {
- if (PrintRecordBytes && ObjDelegate)
- ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content());
-
- W.unindent();
- W.startLine() << "}\n";
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
- StringRef LinkageName;
- W.printHex("PtrParent", Block.Parent);
- W.printHex("PtrEnd", Block.End);
- W.printHex("CodeSize", Block.CodeSize);
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
- Block.CodeOffset, &LinkageName);
- }
- W.printHex("Segment", Block.Segment);
- W.printString("BlockName", Block.Name);
- W.printString("LinkageName", LinkageName);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
- W.printString("Name", Thunk.Name);
- W.printNumber("Parent", Thunk.Parent);
- W.printNumber("End", Thunk.End);
- W.printNumber("Next", Thunk.Next);
- W.printNumber("Off", Thunk.Offset);
- W.printNumber("Seg", Thunk.Segment);
- W.printNumber("Len", Thunk.Length);
- W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames());
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- TrampolineSym &Tramp) {
- W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames());
- W.printNumber("Size", Tramp.Size);
- W.printNumber("ThunkOff", Tramp.ThunkOffset);
- W.printNumber("TargetOff", Tramp.TargetOffset);
- W.printNumber("ThunkSection", Tramp.ThunkSection);
- W.printNumber("TargetSection", Tramp.TargetSection);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) {
- W.printNumber("SectionNumber", Section.SectionNumber);
- W.printNumber("Alignment", Section.Alignment);
- W.printNumber("Rva", Section.Rva);
- W.printNumber("Length", Section.Length);
- W.printFlags("Characteristics", Section.Characteristics,
- getImageSectionCharacteristicNames(),
- COFF::SectionCharacteristics(0x00F00000));
-
- W.printString("Name", Section.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- CoffGroupSym &CoffGroup) {
- W.printNumber("Size", CoffGroup.Size);
- W.printFlags("Characteristics", CoffGroup.Characteristics,
- getImageSectionCharacteristicNames(),
- COFF::SectionCharacteristics(0x00F00000));
- W.printNumber("Offset", CoffGroup.Offset);
- W.printNumber("Segment", CoffGroup.Segment);
- W.printString("Name", CoffGroup.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- BPRelativeSym &BPRel) {
- W.printNumber("Offset", BPRel.Offset);
- printTypeIndex("Type", BPRel.Type);
- W.printString("VarName", BPRel.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- BuildInfoSym &BuildInfo) {
- printTypeIndex("BuildId", BuildInfo.BuildId);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- CallSiteInfoSym &CallSiteInfo) {
- StringRef LinkageName;
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("CodeOffset",
- CallSiteInfo.getRelocationOffset(),
- CallSiteInfo.CodeOffset, &LinkageName);
- }
- W.printHex("Segment", CallSiteInfo.Segment);
- printTypeIndex("Type", CallSiteInfo.Type);
- if (!LinkageName.empty())
- W.printString("LinkageName", LinkageName);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- EnvBlockSym &EnvBlock) {
- ListScope L(W, "Entries");
- for (auto Entry : EnvBlock.Fields) {
- W.printString(Entry);
- }
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- FileStaticSym &FileStatic) {
- printTypeIndex("Index", FileStatic.Index);
- W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);
- W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());
- W.printString("Name", FileStatic.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
- W.printNumber("Ordinal", Export.Ordinal);
- W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames());
- W.printString("Name", Export.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- Compile2Sym &Compile2) {
- W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames());
- W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames());
- W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
- CompilationCPUType = Compile2.Machine;
- std::string FrontendVersion;
- {
- raw_string_ostream Out(FrontendVersion);
- Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor
- << '.' << Compile2.VersionFrontendBuild;
- }
- std::string BackendVersion;
- {
- raw_string_ostream Out(BackendVersion);
- Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor
- << '.' << Compile2.VersionBackendBuild;
- }
- W.printString("FrontendVersion", FrontendVersion);
- W.printString("BackendVersion", BackendVersion);
- W.printString("VersionName", Compile2.Version);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- Compile3Sym &Compile3) {
- W.printEnum("Language", uint8_t(Compile3.getLanguage()), getSourceLanguageNames());
- W.printFlags("Flags", uint32_t(Compile3.getFlags()),
- getCompileSym3FlagNames());
- W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
- CompilationCPUType = Compile3.Machine;
- std::string FrontendVersion;
- {
- raw_string_ostream Out(FrontendVersion);
- Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor
- << '.' << Compile3.VersionFrontendBuild << '.'
- << Compile3.VersionFrontendQFE;
- }
- std::string BackendVersion;
- {
- raw_string_ostream Out(BackendVersion);
- Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor
- << '.' << Compile3.VersionBackendBuild << '.'
- << Compile3.VersionBackendQFE;
- }
- W.printString("FrontendVersion", FrontendVersion);
- W.printString("BackendVersion", BackendVersion);
- W.printString("VersionName", Compile3.Version);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- ConstantSym &Constant) {
- printTypeIndex("Type", Constant.Type);
- W.printNumber("Value", Constant.Value);
- W.printString("Name", Constant.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
- StringRef LinkageName;
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
- Data.DataOffset, &LinkageName);
- }
- printTypeIndex("Type", Data.Type);
- W.printString("DisplayName", Data.Name);
- if (!LinkageName.empty())
- W.printString("LinkageName", LinkageName);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(
- CVSymbol &CVR,
- DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
- W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(
- CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
- W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
- printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
- DefRangeFramePointerRel.getRelocationOffset());
- printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(
- CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
- W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register),
- getRegisterNames(CompilationCPUType));
- W.printBoolean("HasSpilledUDTMember",
- DefRangeRegisterRel.hasSpilledUDTMember());
- W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
- W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset);
- printLocalVariableAddrRange(DefRangeRegisterRel.Range,
- DefRangeRegisterRel.getRelocationOffset());
- printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(
- CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
- W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
- getRegisterNames(CompilationCPUType));
- W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
- printLocalVariableAddrRange(DefRangeRegister.Range,
- DefRangeRegister.getRelocationOffset());
- printLocalVariableAddrGap(DefRangeRegister.Gaps);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(
- CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
- W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
- getRegisterNames(CompilationCPUType));
- W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
- W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);
- printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
- DefRangeSubfieldRegister.getRelocationOffset());
- printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(
- CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
- if (ObjDelegate) {
- DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
- auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
- if (!ExpectedProgram) {
- consumeError(ExpectedProgram.takeError());
- return llvm::make_error<CodeViewError>(
- "String table offset outside of bounds of String Table!");
- }
- W.printString("Program", *ExpectedProgram);
- }
- W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
- printLocalVariableAddrRange(DefRangeSubfield.Range,
- DefRangeSubfield.getRelocationOffset());
- printLocalVariableAddrGap(DefRangeSubfield.Gaps);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- DefRangeSym &DefRange) {
- if (ObjDelegate) {
- DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
- auto ExpectedProgram = Strings.getString(DefRange.Program);
- if (!ExpectedProgram) {
- consumeError(ExpectedProgram.takeError());
- return llvm::make_error<CodeViewError>(
- "String table offset outside of bounds of String Table!");
- }
- W.printString("Program", *ExpectedProgram);
- }
- printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
- printLocalVariableAddrGap(DefRange.Gaps);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- FrameCookieSym &FrameCookie) {
- StringRef LinkageName;
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("CodeOffset",
- FrameCookie.getRelocationOffset(),
- FrameCookie.CodeOffset, &LinkageName);
- }
- W.printEnum("Register", uint16_t(FrameCookie.Register),
- getRegisterNames(CompilationCPUType));
- W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),
- getFrameCookieKindNames());
- W.printHex("Flags", FrameCookie.Flags);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- FrameProcSym &FrameProc) {
- W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);
- W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
- W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);
- W.printHex("BytesOfCalleeSavedRegisters",
- FrameProc.BytesOfCalleeSavedRegisters);
- W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);
- W.printHex("SectionIdOfExceptionHandler",
- FrameProc.SectionIdOfExceptionHandler);
- W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),
- getFrameProcSymFlagNames());
- W.printEnum("LocalFramePtrReg",
- uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)),
- getRegisterNames(CompilationCPUType));
- W.printEnum("ParamFramePtrReg",
- uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)),
- getRegisterNames(CompilationCPUType));
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(
- CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
- StringRef LinkageName;
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("CodeOffset",
- HeapAllocSite.getRelocationOffset(),
- HeapAllocSite.CodeOffset, &LinkageName);
- }
- W.printHex("Segment", HeapAllocSite.Segment);
- W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);
- printTypeIndex("Type", HeapAllocSite.Type);
- if (!LinkageName.empty())
- W.printString("LinkageName", LinkageName);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- InlineSiteSym &InlineSite) {
- W.printHex("PtrParent", InlineSite.Parent);
- W.printHex("PtrEnd", InlineSite.End);
- printTypeIndex("Inlinee", InlineSite.Inlinee);
-
- ListScope BinaryAnnotations(W, "BinaryAnnotations");
- for (auto &Annotation : InlineSite.annotations()) {
- switch (Annotation.OpCode) {
- case BinaryAnnotationsOpCode::Invalid:
- W.printString("(Annotation Padding)");
- break;
- case BinaryAnnotationsOpCode::CodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeOffset:
- case BinaryAnnotationsOpCode::ChangeCodeLength:
- W.printHex(Annotation.Name, Annotation.U1);
- break;
- case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
- case BinaryAnnotationsOpCode::ChangeLineEndDelta:
- case BinaryAnnotationsOpCode::ChangeRangeKind:
- case BinaryAnnotationsOpCode::ChangeColumnStart:
- case BinaryAnnotationsOpCode::ChangeColumnEnd:
- W.printNumber(Annotation.Name, Annotation.U1);
- break;
- case BinaryAnnotationsOpCode::ChangeLineOffset:
- case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
- W.printNumber(Annotation.Name, Annotation.S1);
- break;
- case BinaryAnnotationsOpCode::ChangeFile:
- if (ObjDelegate) {
- W.printHex("ChangeFile",
- ObjDelegate->getFileNameForFileOffset(Annotation.U1),
- Annotation.U1);
- } else {
- W.printHex("ChangeFile", Annotation.U1);
- }
-
- break;
- case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
- W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
- << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
- << "}\n";
- break;
- }
- case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
- W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
- << W.hex(Annotation.U2)
- << ", Length: " << W.hex(Annotation.U1) << "}\n";
- break;
- }
- }
- }
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- RegisterSym &Register) {
- printTypeIndex("Type", Register.Index);
- W.printEnum("Seg", uint16_t(Register.Register),
- getRegisterNames(CompilationCPUType));
- W.printString("Name", Register.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
- W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames());
- W.printNumber("Seg", Public.Segment);
- W.printNumber("Off", Public.Offset);
- W.printString("Name", Public.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {
- W.printNumber("SumName", ProcRef.SumName);
- W.printNumber("SymOffset", ProcRef.SymOffset);
- W.printNumber("Mod", ProcRef.Module);
- W.printString("Name", ProcRef.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
- StringRef LinkageName;
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
- Label.CodeOffset, &LinkageName);
- }
- W.printHex("Segment", Label.Segment);
- W.printHex("Flags", uint8_t(Label.Flags));
- W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());
- W.printString("DisplayName", Label.Name);
- if (!LinkageName.empty())
- W.printString("LinkageName", LinkageName);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
- printTypeIndex("Type", Local.Type);
- W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
- W.printString("VarName", Local.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {
- W.printHex("Signature", ObjName.Signature);
- W.printString("ObjectName", ObjName.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
- if (InFunctionScope)
- return llvm::make_error<CodeViewError>(
- "Visiting a ProcSym while inside function scope!");
-
- InFunctionScope = true;
-
- StringRef LinkageName;
- W.printHex("PtrParent", Proc.Parent);
- W.printHex("PtrEnd", Proc.End);
- W.printHex("PtrNext", Proc.Next);
- W.printHex("CodeSize", Proc.CodeSize);
- W.printHex("DbgStart", Proc.DbgStart);
- W.printHex("DbgEnd", Proc.DbgEnd);
- printTypeIndex("FunctionType", Proc.FunctionType);
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
- Proc.CodeOffset, &LinkageName);
- }
- W.printHex("Segment", Proc.Segment);
- W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
- getProcSymFlagNames());
- W.printString("DisplayName", Proc.Name);
- if (!LinkageName.empty())
- W.printString("LinkageName", LinkageName);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- ScopeEndSym &ScopeEnd) {
- InFunctionScope = false;
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
- ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
- for (auto FuncID : Caller.Indices)
- printTypeIndex("FuncID", FuncID);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- RegRelativeSym &RegRel) {
- W.printHex("Offset", RegRel.Offset);
- printTypeIndex("Type", RegRel.Type);
- W.printEnum("Register", uint16_t(RegRel.Register),
- getRegisterNames(CompilationCPUType));
- W.printString("VarName", RegRel.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- ThreadLocalDataSym &Data) {
- StringRef LinkageName;
- if (ObjDelegate) {
- ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
- Data.DataOffset, &LinkageName);
- }
- printTypeIndex("Type", Data.Type);
- W.printString("DisplayName", Data.Name);
- if (!LinkageName.empty())
- W.printString("LinkageName", LinkageName);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
- printTypeIndex("Type", UDT.Type);
- W.printString("UDTName", UDT.Name);
- return Error::success();
-}
-
-Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
- UsingNamespaceSym &UN) {
- W.printString("Namespace", UN.Name);
- 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();
-}
-
-Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {
- SymbolVisitorCallbackPipeline Pipeline;
- SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
- CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
- PrintRecordBytes);
-
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(Dumper);
- CVSymbolVisitor Visitor(Pipeline);
- auto Err = Visitor.visitSymbolRecord(Record);
- CompilationCPUType = Dumper.getCompilationCPUType();
- return Err;
-}
-
-Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
- SymbolVisitorCallbackPipeline Pipeline;
- SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
- CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
- PrintRecordBytes);
-
- Pipeline.addCallbackToPipeline(Deserializer);
- Pipeline.addCallbackToPipeline(Dumper);
- CVSymbolVisitor Visitor(Pipeline);
- auto Err = Visitor.visitSymbolStream(Symbols);
- CompilationCPUType = Dumper.getCompilationCPUType();
- return Err;
-}
+//===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
+#include "llvm/DebugInfo/CodeView/DebugStringTableSubsection.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbackPipeline.h"
+#include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+#include <system_error>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+namespace {
+/// Use this private dumper implementation to keep implementation details about
+/// the visitor out of SymbolDumper.h.
+class CVSymbolDumperImpl : public SymbolVisitorCallbacks {
+public:
+ CVSymbolDumperImpl(TypeCollection &Types, SymbolDumpDelegate *ObjDelegate,
+ ScopedPrinter &W, CPUType CPU, bool PrintRecordBytes)
+ : Types(Types), ObjDelegate(ObjDelegate), W(W), CompilationCPUType(CPU),
+ PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
+
+/// CVSymbolVisitor overrides.
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ Error visitKnownRecord(CVSymbol &CVR, Name &Record) override;
+#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
+
+ Error visitSymbolBegin(CVSymbol &Record) override;
+ Error visitSymbolEnd(CVSymbol &Record) override;
+ Error visitUnknownSymbol(CVSymbol &Record) override;
+
+ CPUType getCompilationCPUType() const { return CompilationCPUType; }
+
+private:
+ void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
+ uint32_t RelocationOffset);
+ void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
+ void printTypeIndex(StringRef FieldName, TypeIndex TI);
+
+ TypeCollection &Types;
+ SymbolDumpDelegate *ObjDelegate;
+ ScopedPrinter &W;
+
+ /// Save the machine or CPU type when dumping a compile symbols.
+ CPUType CompilationCPUType = CPUType::X64;
+
+ bool PrintRecordBytes;
+ bool InFunctionScope;
+};
+}
+
+static StringRef getSymbolKindName(SymbolKind Kind) {
+ switch (Kind) {
+#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
+ case EnumName: \
+ return #Name;
+#include "llvm/DebugInfo/CodeView/CodeViewSymbols.def"
+ default:
+ break;
+ }
+ return "UnknownSym";
+}
+
+void CVSymbolDumperImpl::printLocalVariableAddrRange(
+ const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
+ DictScope S(W, "LocalVariableAddrRange");
+ if (ObjDelegate)
+ ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
+ Range.OffsetStart);
+ W.printHex("ISectStart", Range.ISectStart);
+ W.printHex("Range", Range.Range);
+}
+
+void CVSymbolDumperImpl::printLocalVariableAddrGap(
+ ArrayRef<LocalVariableAddrGap> Gaps) {
+ for (auto &Gap : Gaps) {
+ ListScope S(W, "LocalVariableAddrGap");
+ W.printHex("GapStartOffset", Gap.GapStartOffset);
+ W.printHex("Range", Gap.Range);
+ }
+}
+
+void CVSymbolDumperImpl::printTypeIndex(StringRef FieldName, TypeIndex TI) {
+ codeview::printTypeIndex(W, FieldName, TI, Types);
+}
+
+Error CVSymbolDumperImpl::visitSymbolBegin(CVSymbol &CVR) {
+ W.startLine() << getSymbolKindName(CVR.kind());
+ W.getOStream() << " {\n";
+ W.indent();
+ W.printEnum("Kind", unsigned(CVR.kind()), getSymbolTypeNames());
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitSymbolEnd(CVSymbol &CVR) {
+ if (PrintRecordBytes && ObjDelegate)
+ ObjDelegate->printBinaryBlockWithRelocs("SymData", CVR.content());
+
+ W.unindent();
+ W.startLine() << "}\n";
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
+ StringRef LinkageName;
+ W.printHex("PtrParent", Block.Parent);
+ W.printHex("PtrEnd", Block.End);
+ W.printHex("CodeSize", Block.CodeSize);
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
+ Block.CodeOffset, &LinkageName);
+ }
+ W.printHex("Segment", Block.Segment);
+ W.printString("BlockName", Block.Name);
+ W.printString("LinkageName", LinkageName);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
+ W.printString("Name", Thunk.Name);
+ W.printNumber("Parent", Thunk.Parent);
+ W.printNumber("End", Thunk.End);
+ W.printNumber("Next", Thunk.Next);
+ W.printNumber("Off", Thunk.Offset);
+ W.printNumber("Seg", Thunk.Segment);
+ W.printNumber("Len", Thunk.Length);
+ W.printEnum("Ordinal", uint8_t(Thunk.Thunk), getThunkOrdinalNames());
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ TrampolineSym &Tramp) {
+ W.printEnum("Type", uint16_t(Tramp.Type), getTrampolineNames());
+ W.printNumber("Size", Tramp.Size);
+ W.printNumber("ThunkOff", Tramp.ThunkOffset);
+ W.printNumber("TargetOff", Tramp.TargetOffset);
+ W.printNumber("ThunkSection", Tramp.ThunkSection);
+ W.printNumber("TargetSection", Tramp.TargetSection);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, SectionSym &Section) {
+ W.printNumber("SectionNumber", Section.SectionNumber);
+ W.printNumber("Alignment", Section.Alignment);
+ W.printNumber("Rva", Section.Rva);
+ W.printNumber("Length", Section.Length);
+ W.printFlags("Characteristics", Section.Characteristics,
+ getImageSectionCharacteristicNames(),
+ COFF::SectionCharacteristics(0x00F00000));
+
+ W.printString("Name", Section.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ CoffGroupSym &CoffGroup) {
+ W.printNumber("Size", CoffGroup.Size);
+ W.printFlags("Characteristics", CoffGroup.Characteristics,
+ getImageSectionCharacteristicNames(),
+ COFF::SectionCharacteristics(0x00F00000));
+ W.printNumber("Offset", CoffGroup.Offset);
+ W.printNumber("Segment", CoffGroup.Segment);
+ W.printString("Name", CoffGroup.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ BPRelativeSym &BPRel) {
+ W.printNumber("Offset", BPRel.Offset);
+ printTypeIndex("Type", BPRel.Type);
+ W.printString("VarName", BPRel.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ BuildInfoSym &BuildInfo) {
+ printTypeIndex("BuildId", BuildInfo.BuildId);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ CallSiteInfoSym &CallSiteInfo) {
+ StringRef LinkageName;
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("CodeOffset",
+ CallSiteInfo.getRelocationOffset(),
+ CallSiteInfo.CodeOffset, &LinkageName);
+ }
+ W.printHex("Segment", CallSiteInfo.Segment);
+ printTypeIndex("Type", CallSiteInfo.Type);
+ if (!LinkageName.empty())
+ W.printString("LinkageName", LinkageName);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ EnvBlockSym &EnvBlock) {
+ ListScope L(W, "Entries");
+ for (auto Entry : EnvBlock.Fields) {
+ W.printString(Entry);
+ }
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ FileStaticSym &FileStatic) {
+ printTypeIndex("Index", FileStatic.Index);
+ W.printNumber("ModFilenameOffset", FileStatic.ModFilenameOffset);
+ W.printFlags("Flags", uint16_t(FileStatic.Flags), getLocalFlagNames());
+ W.printString("Name", FileStatic.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
+ W.printNumber("Ordinal", Export.Ordinal);
+ W.printFlags("Flags", uint16_t(Export.Flags), getExportSymFlagNames());
+ W.printString("Name", Export.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ Compile2Sym &Compile2) {
+ W.printEnum("Language", Compile2.getLanguage(), getSourceLanguageNames());
+ W.printFlags("Flags", Compile2.getFlags(), getCompileSym2FlagNames());
+ W.printEnum("Machine", unsigned(Compile2.Machine), getCPUTypeNames());
+ CompilationCPUType = Compile2.Machine;
+ std::string FrontendVersion;
+ {
+ raw_string_ostream Out(FrontendVersion);
+ Out << Compile2.VersionFrontendMajor << '.' << Compile2.VersionFrontendMinor
+ << '.' << Compile2.VersionFrontendBuild;
+ }
+ std::string BackendVersion;
+ {
+ raw_string_ostream Out(BackendVersion);
+ Out << Compile2.VersionBackendMajor << '.' << Compile2.VersionBackendMinor
+ << '.' << Compile2.VersionBackendBuild;
+ }
+ W.printString("FrontendVersion", FrontendVersion);
+ W.printString("BackendVersion", BackendVersion);
+ W.printString("VersionName", Compile2.Version);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ Compile3Sym &Compile3) {
+ W.printEnum("Language", uint8_t(Compile3.getLanguage()), getSourceLanguageNames());
+ W.printFlags("Flags", uint32_t(Compile3.getFlags()),
+ getCompileSym3FlagNames());
+ W.printEnum("Machine", unsigned(Compile3.Machine), getCPUTypeNames());
+ CompilationCPUType = Compile3.Machine;
+ std::string FrontendVersion;
+ {
+ raw_string_ostream Out(FrontendVersion);
+ Out << Compile3.VersionFrontendMajor << '.' << Compile3.VersionFrontendMinor
+ << '.' << Compile3.VersionFrontendBuild << '.'
+ << Compile3.VersionFrontendQFE;
+ }
+ std::string BackendVersion;
+ {
+ raw_string_ostream Out(BackendVersion);
+ Out << Compile3.VersionBackendMajor << '.' << Compile3.VersionBackendMinor
+ << '.' << Compile3.VersionBackendBuild << '.'
+ << Compile3.VersionBackendQFE;
+ }
+ W.printString("FrontendVersion", FrontendVersion);
+ W.printString("BackendVersion", BackendVersion);
+ W.printString("VersionName", Compile3.Version);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ ConstantSym &Constant) {
+ printTypeIndex("Type", Constant.Type);
+ W.printNumber("Value", Constant.Value);
+ W.printString("Name", Constant.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
+ StringRef LinkageName;
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
+ Data.DataOffset, &LinkageName);
+ }
+ printTypeIndex("Type", Data.Type);
+ W.printString("DisplayName", Data.Name);
+ if (!LinkageName.empty())
+ W.printString("LinkageName", LinkageName);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(
+ CVSymbol &CVR,
+ DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
+ W.printNumber("Offset", DefRangeFramePointerRelFullScope.Offset);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(
+ CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
+ W.printNumber("Offset", DefRangeFramePointerRel.Hdr.Offset);
+ printLocalVariableAddrRange(DefRangeFramePointerRel.Range,
+ DefRangeFramePointerRel.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(
+ CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
+ W.printEnum("BaseRegister", uint16_t(DefRangeRegisterRel.Hdr.Register),
+ getRegisterNames(CompilationCPUType));
+ W.printBoolean("HasSpilledUDTMember",
+ DefRangeRegisterRel.hasSpilledUDTMember());
+ W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
+ W.printNumber("BasePointerOffset", DefRangeRegisterRel.Hdr.BasePointerOffset);
+ printLocalVariableAddrRange(DefRangeRegisterRel.Range,
+ DefRangeRegisterRel.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(
+ CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
+ W.printEnum("Register", uint16_t(DefRangeRegister.Hdr.Register),
+ getRegisterNames(CompilationCPUType));
+ W.printNumber("MayHaveNoName", DefRangeRegister.Hdr.MayHaveNoName);
+ printLocalVariableAddrRange(DefRangeRegister.Range,
+ DefRangeRegister.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeRegister.Gaps);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(
+ CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
+ W.printEnum("Register", uint16_t(DefRangeSubfieldRegister.Hdr.Register),
+ getRegisterNames(CompilationCPUType));
+ W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Hdr.MayHaveNoName);
+ W.printNumber("OffsetInParent", DefRangeSubfieldRegister.Hdr.OffsetInParent);
+ printLocalVariableAddrRange(DefRangeSubfieldRegister.Range,
+ DefRangeSubfieldRegister.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(
+ CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
+ if (ObjDelegate) {
+ DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
+ auto ExpectedProgram = Strings.getString(DefRangeSubfield.Program);
+ if (!ExpectedProgram) {
+ consumeError(ExpectedProgram.takeError());
+ return llvm::make_error<CodeViewError>(
+ "String table offset outside of bounds of String Table!");
+ }
+ W.printString("Program", *ExpectedProgram);
+ }
+ W.printNumber("OffsetInParent", DefRangeSubfield.OffsetInParent);
+ printLocalVariableAddrRange(DefRangeSubfield.Range,
+ DefRangeSubfield.getRelocationOffset());
+ printLocalVariableAddrGap(DefRangeSubfield.Gaps);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ DefRangeSym &DefRange) {
+ if (ObjDelegate) {
+ DebugStringTableSubsectionRef Strings = ObjDelegate->getStringTable();
+ auto ExpectedProgram = Strings.getString(DefRange.Program);
+ if (!ExpectedProgram) {
+ consumeError(ExpectedProgram.takeError());
+ return llvm::make_error<CodeViewError>(
+ "String table offset outside of bounds of String Table!");
+ }
+ W.printString("Program", *ExpectedProgram);
+ }
+ printLocalVariableAddrRange(DefRange.Range, DefRange.getRelocationOffset());
+ printLocalVariableAddrGap(DefRange.Gaps);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ FrameCookieSym &FrameCookie) {
+ StringRef LinkageName;
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("CodeOffset",
+ FrameCookie.getRelocationOffset(),
+ FrameCookie.CodeOffset, &LinkageName);
+ }
+ W.printEnum("Register", uint16_t(FrameCookie.Register),
+ getRegisterNames(CompilationCPUType));
+ W.printEnum("CookieKind", uint16_t(FrameCookie.CookieKind),
+ getFrameCookieKindNames());
+ W.printHex("Flags", FrameCookie.Flags);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ FrameProcSym &FrameProc) {
+ W.printHex("TotalFrameBytes", FrameProc.TotalFrameBytes);
+ W.printHex("PaddingFrameBytes", FrameProc.PaddingFrameBytes);
+ W.printHex("OffsetToPadding", FrameProc.OffsetToPadding);
+ W.printHex("BytesOfCalleeSavedRegisters",
+ FrameProc.BytesOfCalleeSavedRegisters);
+ W.printHex("OffsetOfExceptionHandler", FrameProc.OffsetOfExceptionHandler);
+ W.printHex("SectionIdOfExceptionHandler",
+ FrameProc.SectionIdOfExceptionHandler);
+ W.printFlags("Flags", static_cast<uint32_t>(FrameProc.Flags),
+ getFrameProcSymFlagNames());
+ W.printEnum("LocalFramePtrReg",
+ uint16_t(FrameProc.getLocalFramePtrReg(CompilationCPUType)),
+ getRegisterNames(CompilationCPUType));
+ W.printEnum("ParamFramePtrReg",
+ uint16_t(FrameProc.getParamFramePtrReg(CompilationCPUType)),
+ getRegisterNames(CompilationCPUType));
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(
+ CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
+ StringRef LinkageName;
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("CodeOffset",
+ HeapAllocSite.getRelocationOffset(),
+ HeapAllocSite.CodeOffset, &LinkageName);
+ }
+ W.printHex("Segment", HeapAllocSite.Segment);
+ W.printHex("CallInstructionSize", HeapAllocSite.CallInstructionSize);
+ printTypeIndex("Type", HeapAllocSite.Type);
+ if (!LinkageName.empty())
+ W.printString("LinkageName", LinkageName);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ InlineSiteSym &InlineSite) {
+ W.printHex("PtrParent", InlineSite.Parent);
+ W.printHex("PtrEnd", InlineSite.End);
+ printTypeIndex("Inlinee", InlineSite.Inlinee);
+
+ ListScope BinaryAnnotations(W, "BinaryAnnotations");
+ for (auto &Annotation : InlineSite.annotations()) {
+ switch (Annotation.OpCode) {
+ case BinaryAnnotationsOpCode::Invalid:
+ W.printString("(Annotation Padding)");
+ break;
+ case BinaryAnnotationsOpCode::CodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeOffset:
+ case BinaryAnnotationsOpCode::ChangeCodeLength:
+ W.printHex(Annotation.Name, Annotation.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
+ case BinaryAnnotationsOpCode::ChangeLineEndDelta:
+ case BinaryAnnotationsOpCode::ChangeRangeKind:
+ case BinaryAnnotationsOpCode::ChangeColumnStart:
+ case BinaryAnnotationsOpCode::ChangeColumnEnd:
+ W.printNumber(Annotation.Name, Annotation.U1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeLineOffset:
+ case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
+ W.printNumber(Annotation.Name, Annotation.S1);
+ break;
+ case BinaryAnnotationsOpCode::ChangeFile:
+ if (ObjDelegate) {
+ W.printHex("ChangeFile",
+ ObjDelegate->getFileNameForFileOffset(Annotation.U1),
+ Annotation.U1);
+ } else {
+ W.printHex("ChangeFile", Annotation.U1);
+ }
+
+ break;
+ case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
+ W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
+ << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
+ << "}\n";
+ break;
+ }
+ case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
+ W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
+ << W.hex(Annotation.U2)
+ << ", Length: " << W.hex(Annotation.U1) << "}\n";
+ break;
+ }
+ }
+ }
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ RegisterSym &Register) {
+ printTypeIndex("Type", Register.Index);
+ W.printEnum("Seg", uint16_t(Register.Register),
+ getRegisterNames(CompilationCPUType));
+ W.printString("Name", Register.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, PublicSym32 &Public) {
+ W.printFlags("Flags", uint32_t(Public.Flags), getPublicSymFlagNames());
+ W.printNumber("Seg", Public.Segment);
+ W.printNumber("Off", Public.Offset);
+ W.printString("Name", Public.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcRefSym &ProcRef) {
+ W.printNumber("SumName", ProcRef.SumName);
+ W.printNumber("SymOffset", ProcRef.SymOffset);
+ W.printNumber("Mod", ProcRef.Module);
+ W.printString("Name", ProcRef.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
+ StringRef LinkageName;
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
+ Label.CodeOffset, &LinkageName);
+ }
+ W.printHex("Segment", Label.Segment);
+ W.printHex("Flags", uint8_t(Label.Flags));
+ W.printFlags("Flags", uint8_t(Label.Flags), getProcSymFlagNames());
+ W.printString("DisplayName", Label.Name);
+ if (!LinkageName.empty())
+ W.printString("LinkageName", LinkageName);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
+ printTypeIndex("Type", Local.Type);
+ W.printFlags("Flags", uint16_t(Local.Flags), getLocalFlagNames());
+ W.printString("VarName", Local.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ObjNameSym &ObjName) {
+ W.printHex("Signature", ObjName.Signature);
+ W.printString("ObjectName", ObjName.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
+ if (InFunctionScope)
+ return llvm::make_error<CodeViewError>(
+ "Visiting a ProcSym while inside function scope!");
+
+ InFunctionScope = true;
+
+ StringRef LinkageName;
+ W.printHex("PtrParent", Proc.Parent);
+ W.printHex("PtrEnd", Proc.End);
+ W.printHex("PtrNext", Proc.Next);
+ W.printHex("CodeSize", Proc.CodeSize);
+ W.printHex("DbgStart", Proc.DbgStart);
+ W.printHex("DbgEnd", Proc.DbgEnd);
+ printTypeIndex("FunctionType", Proc.FunctionType);
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
+ Proc.CodeOffset, &LinkageName);
+ }
+ W.printHex("Segment", Proc.Segment);
+ W.printFlags("Flags", static_cast<uint8_t>(Proc.Flags),
+ getProcSymFlagNames());
+ W.printString("DisplayName", Proc.Name);
+ if (!LinkageName.empty())
+ W.printString("LinkageName", LinkageName);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ ScopeEndSym &ScopeEnd) {
+ InFunctionScope = false;
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
+ ListScope S(W, CVR.kind() == S_CALLEES ? "Callees" : "Callers");
+ for (auto FuncID : Caller.Indices)
+ printTypeIndex("FuncID", FuncID);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ RegRelativeSym &RegRel) {
+ W.printHex("Offset", RegRel.Offset);
+ printTypeIndex("Type", RegRel.Type);
+ W.printEnum("Register", uint16_t(RegRel.Register),
+ getRegisterNames(CompilationCPUType));
+ W.printString("VarName", RegRel.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ ThreadLocalDataSym &Data) {
+ StringRef LinkageName;
+ if (ObjDelegate) {
+ ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
+ Data.DataOffset, &LinkageName);
+ }
+ printTypeIndex("Type", Data.Type);
+ W.printString("DisplayName", Data.Name);
+ if (!LinkageName.empty())
+ W.printString("LinkageName", LinkageName);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
+ printTypeIndex("Type", UDT.Type);
+ W.printString("UDTName", UDT.Name);
+ return Error::success();
+}
+
+Error CVSymbolDumperImpl::visitKnownRecord(CVSymbol &CVR,
+ UsingNamespaceSym &UN) {
+ W.printString("Namespace", UN.Name);
+ 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();
+}
+
+Error CVSymbolDumper::dump(CVRecord<SymbolKind> &Record) {
+ SymbolVisitorCallbackPipeline Pipeline;
+ SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
+ CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
+ PrintRecordBytes);
+
+ Pipeline.addCallbackToPipeline(Deserializer);
+ Pipeline.addCallbackToPipeline(Dumper);
+ CVSymbolVisitor Visitor(Pipeline);
+ auto Err = Visitor.visitSymbolRecord(Record);
+ CompilationCPUType = Dumper.getCompilationCPUType();
+ return Err;
+}
+
+Error CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
+ SymbolVisitorCallbackPipeline Pipeline;
+ SymbolDeserializer Deserializer(ObjDelegate.get(), Container);
+ CVSymbolDumperImpl Dumper(Types, ObjDelegate.get(), W, CompilationCPUType,
+ PrintRecordBytes);
+
+ Pipeline.addCallbackToPipeline(Deserializer);
+ Pipeline.addCallbackToPipeline(Dumper);
+ CVSymbolVisitor Visitor(Pipeline);
+ auto Err = Visitor.visitSymbolStream(Symbols);
+ CompilationCPUType = Dumper.getCompilationCPUType();
+ return Err;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
index 2562c633bb..a4d3a4068e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp
@@ -1,93 +1,93 @@
-//===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-template <typename RecordT> static RecordT createRecord(const CVSymbol &sym) {
- RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
- cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
- return record;
-}
-
-uint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) {
- assert(symbolOpensScope(Sym.kind()));
- switch (Sym.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: {
- ProcSym Proc = createRecord<ProcSym>(Sym);
- return Proc.End;
- }
- case SymbolKind::S_BLOCK32: {
- BlockSym Block = createRecord<BlockSym>(Sym);
- return Block.End;
- }
- case SymbolKind::S_THUNK32: {
- Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
- return Thunk.End;
- }
- case SymbolKind::S_INLINESITE: {
- InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
- return Site.End;
- }
- default:
- assert(false && "Unknown record type");
- return 0;
- }
-}
-
-uint32_t
-llvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) {
- assert(symbolOpensScope(Sym.kind()));
- switch (Sym.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: {
- ProcSym Proc = createRecord<ProcSym>(Sym);
- return Proc.Parent;
- }
- case SymbolKind::S_BLOCK32: {
- BlockSym Block = createRecord<BlockSym>(Sym);
- return Block.Parent;
- }
- case SymbolKind::S_THUNK32: {
- Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
- return Thunk.Parent;
- }
- case SymbolKind::S_INLINESITE: {
- InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
- return Site.Parent;
- }
- default:
- assert(false && "Unknown record type");
- return 0;
- }
-}
-
-CVSymbolArray
-llvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols,
- uint32_t ScopeBegin) {
- CVSymbol Opener = *Symbols.at(ScopeBegin);
- assert(symbolOpensScope(Opener.kind()));
- uint32_t EndOffset = getScopeEndOffset(Opener);
- CVSymbol Closer = *Symbols.at(EndOffset);
- EndOffset += Closer.RecordData.size();
- return Symbols.substream(ScopeBegin, EndOffset);
-}
+//===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+template <typename RecordT> static RecordT createRecord(const CVSymbol &sym) {
+ RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
+ cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
+ return record;
+}
+
+uint32_t llvm::codeview::getScopeEndOffset(const CVSymbol &Sym) {
+ assert(symbolOpensScope(Sym.kind()));
+ switch (Sym.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: {
+ ProcSym Proc = createRecord<ProcSym>(Sym);
+ return Proc.End;
+ }
+ case SymbolKind::S_BLOCK32: {
+ BlockSym Block = createRecord<BlockSym>(Sym);
+ return Block.End;
+ }
+ case SymbolKind::S_THUNK32: {
+ Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
+ return Thunk.End;
+ }
+ case SymbolKind::S_INLINESITE: {
+ InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
+ return Site.End;
+ }
+ default:
+ assert(false && "Unknown record type");
+ return 0;
+ }
+}
+
+uint32_t
+llvm::codeview::getScopeParentOffset(const llvm::codeview::CVSymbol &Sym) {
+ assert(symbolOpensScope(Sym.kind()));
+ switch (Sym.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: {
+ ProcSym Proc = createRecord<ProcSym>(Sym);
+ return Proc.Parent;
+ }
+ case SymbolKind::S_BLOCK32: {
+ BlockSym Block = createRecord<BlockSym>(Sym);
+ return Block.Parent;
+ }
+ case SymbolKind::S_THUNK32: {
+ Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
+ return Thunk.Parent;
+ }
+ case SymbolKind::S_INLINESITE: {
+ InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
+ return Site.Parent;
+ }
+ default:
+ assert(false && "Unknown record type");
+ return 0;
+ }
+}
+
+CVSymbolArray
+llvm::codeview::limitSymbolArrayToScope(const CVSymbolArray &Symbols,
+ uint32_t ScopeBegin) {
+ CVSymbol Opener = *Symbols.at(ScopeBegin);
+ assert(symbolOpensScope(Opener.kind()));
+ uint32_t EndOffset = getScopeEndOffset(Opener);
+ CVSymbol Closer = *Symbols.at(EndOffset);
+ EndOffset += Closer.RecordData.size();
+ return Symbols.substream(ScopeBegin, EndOffset);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
index 3b627930e2..a2d37c26d4 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolRecordMapping.cpp
@@ -1,558 +1,558 @@
-//===- SymbolRecordMapping.cpp -----------------------------------*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-#define error(X) \
- if (auto EC = X) \
- return EC;
-
-namespace {
-struct MapGap {
- Error operator()(CodeViewRecordIO &IO, LocalVariableAddrGap &Gap) const {
- error(IO.mapInteger(Gap.GapStartOffset));
- error(IO.mapInteger(Gap.Range));
- return Error::success();
- }
-};
-}
-
-static Error mapLocalVariableAddrRange(CodeViewRecordIO &IO,
- LocalVariableAddrRange &Range) {
- error(IO.mapInteger(Range.OffsetStart));
- error(IO.mapInteger(Range.ISectStart));
- error(IO.mapInteger(Range.Range));
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitSymbolBegin(CVSymbol &Record) {
- error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix)));
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitSymbolEnd(CVSymbol &Record) {
- error(IO.padToAlignment(alignOf(Container)));
- error(IO.endRecord());
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
-
- error(IO.mapInteger(Block.Parent));
- error(IO.mapInteger(Block.End));
- error(IO.mapInteger(Block.CodeSize));
- error(IO.mapInteger(Block.CodeOffset));
- error(IO.mapInteger(Block.Segment));
- error(IO.mapStringZ(Block.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
-
- error(IO.mapInteger(Thunk.Parent));
- error(IO.mapInteger(Thunk.End));
- error(IO.mapInteger(Thunk.Next));
- error(IO.mapInteger(Thunk.Offset));
- error(IO.mapInteger(Thunk.Segment));
- error(IO.mapInteger(Thunk.Length));
- error(IO.mapEnum(Thunk.Thunk));
- error(IO.mapStringZ(Thunk.Name));
- error(IO.mapByteVectorTail(Thunk.VariantData));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- TrampolineSym &Tramp) {
-
- error(IO.mapEnum(Tramp.Type));
- error(IO.mapInteger(Tramp.Size));
- error(IO.mapInteger(Tramp.ThunkOffset));
- error(IO.mapInteger(Tramp.TargetOffset));
- error(IO.mapInteger(Tramp.ThunkSection));
- error(IO.mapInteger(Tramp.TargetSection));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- SectionSym &Section) {
- uint8_t Padding = 0;
-
- error(IO.mapInteger(Section.SectionNumber));
- error(IO.mapInteger(Section.Alignment));
- error(IO.mapInteger(Padding));
- error(IO.mapInteger(Section.Rva));
- error(IO.mapInteger(Section.Length));
- error(IO.mapInteger(Section.Characteristics));
- error(IO.mapStringZ(Section.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- CoffGroupSym &CoffGroup) {
-
- error(IO.mapInteger(CoffGroup.Size));
- error(IO.mapInteger(CoffGroup.Characteristics));
- error(IO.mapInteger(CoffGroup.Offset));
- error(IO.mapInteger(CoffGroup.Segment));
- error(IO.mapStringZ(CoffGroup.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- BPRelativeSym &BPRel) {
-
- error(IO.mapInteger(BPRel.Offset));
- error(IO.mapInteger(BPRel.Type));
- error(IO.mapStringZ(BPRel.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- BuildInfoSym &BuildInfo) {
-
- error(IO.mapInteger(BuildInfo.BuildId));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- CallSiteInfoSym &CallSiteInfo) {
- uint16_t Padding = 0;
-
- error(IO.mapInteger(CallSiteInfo.CodeOffset));
- error(IO.mapInteger(CallSiteInfo.Segment));
- error(IO.mapInteger(Padding));
- error(IO.mapInteger(CallSiteInfo.Type));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- EnvBlockSym &EnvBlock) {
-
- uint8_t Reserved = 0;
- error(IO.mapInteger(Reserved));
- error(IO.mapStringZVectorZ(EnvBlock.Fields));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- FileStaticSym &FileStatic) {
-
- error(IO.mapInteger(FileStatic.Index));
- error(IO.mapInteger(FileStatic.ModFilenameOffset));
- error(IO.mapEnum(FileStatic.Flags));
- error(IO.mapStringZ(FileStatic.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
-
- error(IO.mapInteger(Export.Ordinal));
- error(IO.mapEnum(Export.Flags));
- error(IO.mapStringZ(Export.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- Compile2Sym &Compile2) {
-
- error(IO.mapEnum(Compile2.Flags));
- error(IO.mapEnum(Compile2.Machine));
- error(IO.mapInteger(Compile2.VersionFrontendMajor));
- error(IO.mapInteger(Compile2.VersionFrontendMinor));
- error(IO.mapInteger(Compile2.VersionFrontendBuild));
- error(IO.mapInteger(Compile2.VersionBackendMajor));
- error(IO.mapInteger(Compile2.VersionBackendMinor));
- error(IO.mapInteger(Compile2.VersionBackendBuild));
- error(IO.mapStringZ(Compile2.Version));
- error(IO.mapStringZVectorZ(Compile2.ExtraStrings));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- Compile3Sym &Compile3) {
-
- error(IO.mapEnum(Compile3.Flags));
- error(IO.mapEnum(Compile3.Machine));
- error(IO.mapInteger(Compile3.VersionFrontendMajor));
- error(IO.mapInteger(Compile3.VersionFrontendMinor));
- error(IO.mapInteger(Compile3.VersionFrontendBuild));
- error(IO.mapInteger(Compile3.VersionFrontendQFE));
- error(IO.mapInteger(Compile3.VersionBackendMajor));
- error(IO.mapInteger(Compile3.VersionBackendMinor));
- error(IO.mapInteger(Compile3.VersionBackendBuild));
- error(IO.mapInteger(Compile3.VersionBackendQFE));
- error(IO.mapStringZ(Compile3.Version));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- ConstantSym &Constant) {
-
- error(IO.mapInteger(Constant.Type));
- error(IO.mapEncodedInteger(Constant.Value));
- error(IO.mapStringZ(Constant.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
-
- error(IO.mapInteger(Data.Type));
- error(IO.mapInteger(Data.DataOffset));
- error(IO.mapInteger(Data.Segment));
- error(IO.mapStringZ(Data.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(
- CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
-
- error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset));
- error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range));
- error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap()));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(
- CVSymbol &CVR,
- DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
-
- error(IO.mapInteger(DefRangeFramePointerRelFullScope.Offset));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(
- CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
-
- error(IO.mapObject(DefRangeRegisterRel.Hdr.Register));
- error(IO.mapObject(DefRangeRegisterRel.Hdr.Flags));
- error(IO.mapObject(DefRangeRegisterRel.Hdr.BasePointerOffset));
- error(mapLocalVariableAddrRange(IO, DefRangeRegisterRel.Range));
- error(IO.mapVectorTail(DefRangeRegisterRel.Gaps, MapGap()));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(
- CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
-
- error(IO.mapObject(DefRangeRegister.Hdr.Register));
- error(IO.mapObject(DefRangeRegister.Hdr.MayHaveNoName));
- error(mapLocalVariableAddrRange(IO, DefRangeRegister.Range));
- error(IO.mapVectorTail(DefRangeRegister.Gaps, MapGap()));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(
- CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
-
- error(IO.mapObject(DefRangeSubfieldRegister.Hdr.Register));
- error(IO.mapObject(DefRangeSubfieldRegister.Hdr.MayHaveNoName));
- error(IO.mapObject(DefRangeSubfieldRegister.Hdr.OffsetInParent));
- error(mapLocalVariableAddrRange(IO, DefRangeSubfieldRegister.Range));
- error(IO.mapVectorTail(DefRangeSubfieldRegister.Gaps, MapGap()));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(
- CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
-
- error(IO.mapInteger(DefRangeSubfield.Program));
- error(IO.mapInteger(DefRangeSubfield.OffsetInParent));
- error(mapLocalVariableAddrRange(IO, DefRangeSubfield.Range));
- error(IO.mapVectorTail(DefRangeSubfield.Gaps, MapGap()));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- DefRangeSym &DefRange) {
-
- error(IO.mapInteger(DefRange.Program));
- error(mapLocalVariableAddrRange(IO, DefRange.Range));
- error(IO.mapVectorTail(DefRange.Gaps, MapGap()));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- FrameCookieSym &FrameCookie) {
-
- error(IO.mapInteger(FrameCookie.CodeOffset));
- error(IO.mapInteger(FrameCookie.Register));
- error(IO.mapEnum(FrameCookie.CookieKind));
- error(IO.mapInteger(FrameCookie.Flags));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- FrameProcSym &FrameProc) {
- error(IO.mapInteger(FrameProc.TotalFrameBytes));
- error(IO.mapInteger(FrameProc.PaddingFrameBytes));
- error(IO.mapInteger(FrameProc.OffsetToPadding));
- error(IO.mapInteger(FrameProc.BytesOfCalleeSavedRegisters));
- error(IO.mapInteger(FrameProc.OffsetOfExceptionHandler));
- error(IO.mapInteger(FrameProc.SectionIdOfExceptionHandler));
- error(IO.mapEnum(FrameProc.Flags));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(
- CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
-
- error(IO.mapInteger(HeapAllocSite.CodeOffset));
- error(IO.mapInteger(HeapAllocSite.Segment));
- error(IO.mapInteger(HeapAllocSite.CallInstructionSize));
- error(IO.mapInteger(HeapAllocSite.Type));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- InlineSiteSym &InlineSite) {
-
- error(IO.mapInteger(InlineSite.Parent));
- error(IO.mapInteger(InlineSite.End));
- error(IO.mapInteger(InlineSite.Inlinee));
- error(IO.mapByteVectorTail(InlineSite.AnnotationData));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- RegisterSym &Register) {
-
- error(IO.mapInteger(Register.Index));
- error(IO.mapEnum(Register.Register));
- error(IO.mapStringZ(Register.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- PublicSym32 &Public) {
-
- error(IO.mapEnum(Public.Flags));
- error(IO.mapInteger(Public.Offset));
- error(IO.mapInteger(Public.Segment));
- error(IO.mapStringZ(Public.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- ProcRefSym &ProcRef) {
-
- error(IO.mapInteger(ProcRef.SumName));
- error(IO.mapInteger(ProcRef.SymOffset));
- error(IO.mapInteger(ProcRef.Module));
- error(IO.mapStringZ(ProcRef.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
-
- error(IO.mapInteger(Label.CodeOffset));
- error(IO.mapInteger(Label.Segment));
- error(IO.mapEnum(Label.Flags));
- error(IO.mapStringZ(Label.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
- error(IO.mapInteger(Local.Type));
- error(IO.mapEnum(Local.Flags));
- error(IO.mapStringZ(Local.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- ObjNameSym &ObjName) {
-
- error(IO.mapInteger(ObjName.Signature));
- error(IO.mapStringZ(ObjName.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
- error(IO.mapInteger(Proc.Parent));
- error(IO.mapInteger(Proc.End));
- error(IO.mapInteger(Proc.Next));
- error(IO.mapInteger(Proc.CodeSize));
- error(IO.mapInteger(Proc.DbgStart));
- error(IO.mapInteger(Proc.DbgEnd));
- error(IO.mapInteger(Proc.FunctionType));
- error(IO.mapInteger(Proc.CodeOffset));
- error(IO.mapInteger(Proc.Segment));
- error(IO.mapEnum(Proc.Flags));
- error(IO.mapStringZ(Proc.Name));
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- ScopeEndSym &ScopeEnd) {
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
- error(IO.mapVectorN<uint32_t>(
- Caller.Indices,
- [](CodeViewRecordIO &IO, TypeIndex &N) { return IO.mapInteger(N); }));
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- RegRelativeSym &RegRel) {
-
- error(IO.mapInteger(RegRel.Offset));
- error(IO.mapInteger(RegRel.Type));
- error(IO.mapEnum(RegRel.Register));
- error(IO.mapStringZ(RegRel.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- ThreadLocalDataSym &Data) {
-
- error(IO.mapInteger(Data.Type));
- error(IO.mapInteger(Data.DataOffset));
- error(IO.mapInteger(Data.Segment));
- error(IO.mapStringZ(Data.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
-
- error(IO.mapInteger(UDT.Type));
- error(IO.mapStringZ(UDT.Name));
-
- return Error::success();
-}
-
-Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
- UsingNamespaceSym &UN) {
-
- error(IO.mapStringZ(UN.Name));
-
- 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);
- switch (CPU) {
- // FIXME: Add ARM and AArch64 variants here.
- default:
- break;
- case CPUType::Intel8080:
- case CPUType::Intel8086:
- case CPUType::Intel80286:
- case CPUType::Intel80386:
- case CPUType::Intel80486:
- case CPUType::Pentium:
- case CPUType::PentiumPro:
- case CPUType::Pentium3:
- switch (EncodedReg) {
- case EncodedFramePtrReg::None: return RegisterId::NONE;
- case EncodedFramePtrReg::StackPtr: return RegisterId::VFRAME;
- case EncodedFramePtrReg::FramePtr: return RegisterId::EBP;
- case EncodedFramePtrReg::BasePtr: return RegisterId::EBX;
- }
- llvm_unreachable("bad encoding");
- case CPUType::X64:
- switch (EncodedReg) {
- case EncodedFramePtrReg::None: return RegisterId::NONE;
- case EncodedFramePtrReg::StackPtr: return RegisterId::RSP;
- case EncodedFramePtrReg::FramePtr: return RegisterId::RBP;
- case EncodedFramePtrReg::BasePtr: return RegisterId::R13;
- }
- llvm_unreachable("bad encoding");
- }
- return RegisterId::NONE;
-}
-
-EncodedFramePtrReg codeview::encodeFramePtrReg(RegisterId Reg, CPUType CPU) {
- switch (CPU) {
- // FIXME: Add ARM and AArch64 variants here.
- default:
- break;
- case CPUType::Intel8080:
- case CPUType::Intel8086:
- case CPUType::Intel80286:
- case CPUType::Intel80386:
- case CPUType::Intel80486:
- case CPUType::Pentium:
- case CPUType::PentiumPro:
- case CPUType::Pentium3:
- switch (Reg) {
- case RegisterId::VFRAME:
- return EncodedFramePtrReg::StackPtr;
- case RegisterId::EBP:
- return EncodedFramePtrReg::FramePtr;
- case RegisterId::EBX:
- return EncodedFramePtrReg::BasePtr;
- default:
- break;
- }
- break;
- case CPUType::X64:
- switch (Reg) {
- case RegisterId::RSP:
- return EncodedFramePtrReg::StackPtr;
- case RegisterId::RBP:
- return EncodedFramePtrReg::FramePtr;
- case RegisterId::R13:
- return EncodedFramePtrReg::BasePtr;
- default:
- break;
- }
- break;
- }
- return EncodedFramePtrReg::None;
-}
+//===- SymbolRecordMapping.cpp -----------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+#define error(X) \
+ if (auto EC = X) \
+ return EC;
+
+namespace {
+struct MapGap {
+ Error operator()(CodeViewRecordIO &IO, LocalVariableAddrGap &Gap) const {
+ error(IO.mapInteger(Gap.GapStartOffset));
+ error(IO.mapInteger(Gap.Range));
+ return Error::success();
+ }
+};
+}
+
+static Error mapLocalVariableAddrRange(CodeViewRecordIO &IO,
+ LocalVariableAddrRange &Range) {
+ error(IO.mapInteger(Range.OffsetStart));
+ error(IO.mapInteger(Range.ISectStart));
+ error(IO.mapInteger(Range.Range));
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitSymbolBegin(CVSymbol &Record) {
+ error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix)));
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitSymbolEnd(CVSymbol &Record) {
+ error(IO.padToAlignment(alignOf(Container)));
+ error(IO.endRecord());
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
+
+ error(IO.mapInteger(Block.Parent));
+ error(IO.mapInteger(Block.End));
+ error(IO.mapInteger(Block.CodeSize));
+ error(IO.mapInteger(Block.CodeOffset));
+ error(IO.mapInteger(Block.Segment));
+ error(IO.mapStringZ(Block.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
+
+ error(IO.mapInteger(Thunk.Parent));
+ error(IO.mapInteger(Thunk.End));
+ error(IO.mapInteger(Thunk.Next));
+ error(IO.mapInteger(Thunk.Offset));
+ error(IO.mapInteger(Thunk.Segment));
+ error(IO.mapInteger(Thunk.Length));
+ error(IO.mapEnum(Thunk.Thunk));
+ error(IO.mapStringZ(Thunk.Name));
+ error(IO.mapByteVectorTail(Thunk.VariantData));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ TrampolineSym &Tramp) {
+
+ error(IO.mapEnum(Tramp.Type));
+ error(IO.mapInteger(Tramp.Size));
+ error(IO.mapInteger(Tramp.ThunkOffset));
+ error(IO.mapInteger(Tramp.TargetOffset));
+ error(IO.mapInteger(Tramp.ThunkSection));
+ error(IO.mapInteger(Tramp.TargetSection));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ SectionSym &Section) {
+ uint8_t Padding = 0;
+
+ error(IO.mapInteger(Section.SectionNumber));
+ error(IO.mapInteger(Section.Alignment));
+ error(IO.mapInteger(Padding));
+ error(IO.mapInteger(Section.Rva));
+ error(IO.mapInteger(Section.Length));
+ error(IO.mapInteger(Section.Characteristics));
+ error(IO.mapStringZ(Section.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ CoffGroupSym &CoffGroup) {
+
+ error(IO.mapInteger(CoffGroup.Size));
+ error(IO.mapInteger(CoffGroup.Characteristics));
+ error(IO.mapInteger(CoffGroup.Offset));
+ error(IO.mapInteger(CoffGroup.Segment));
+ error(IO.mapStringZ(CoffGroup.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ BPRelativeSym &BPRel) {
+
+ error(IO.mapInteger(BPRel.Offset));
+ error(IO.mapInteger(BPRel.Type));
+ error(IO.mapStringZ(BPRel.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ BuildInfoSym &BuildInfo) {
+
+ error(IO.mapInteger(BuildInfo.BuildId));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ CallSiteInfoSym &CallSiteInfo) {
+ uint16_t Padding = 0;
+
+ error(IO.mapInteger(CallSiteInfo.CodeOffset));
+ error(IO.mapInteger(CallSiteInfo.Segment));
+ error(IO.mapInteger(Padding));
+ error(IO.mapInteger(CallSiteInfo.Type));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ EnvBlockSym &EnvBlock) {
+
+ uint8_t Reserved = 0;
+ error(IO.mapInteger(Reserved));
+ error(IO.mapStringZVectorZ(EnvBlock.Fields));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ FileStaticSym &FileStatic) {
+
+ error(IO.mapInteger(FileStatic.Index));
+ error(IO.mapInteger(FileStatic.ModFilenameOffset));
+ error(IO.mapEnum(FileStatic.Flags));
+ error(IO.mapStringZ(FileStatic.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
+
+ error(IO.mapInteger(Export.Ordinal));
+ error(IO.mapEnum(Export.Flags));
+ error(IO.mapStringZ(Export.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ Compile2Sym &Compile2) {
+
+ error(IO.mapEnum(Compile2.Flags));
+ error(IO.mapEnum(Compile2.Machine));
+ error(IO.mapInteger(Compile2.VersionFrontendMajor));
+ error(IO.mapInteger(Compile2.VersionFrontendMinor));
+ error(IO.mapInteger(Compile2.VersionFrontendBuild));
+ error(IO.mapInteger(Compile2.VersionBackendMajor));
+ error(IO.mapInteger(Compile2.VersionBackendMinor));
+ error(IO.mapInteger(Compile2.VersionBackendBuild));
+ error(IO.mapStringZ(Compile2.Version));
+ error(IO.mapStringZVectorZ(Compile2.ExtraStrings));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ Compile3Sym &Compile3) {
+
+ error(IO.mapEnum(Compile3.Flags));
+ error(IO.mapEnum(Compile3.Machine));
+ error(IO.mapInteger(Compile3.VersionFrontendMajor));
+ error(IO.mapInteger(Compile3.VersionFrontendMinor));
+ error(IO.mapInteger(Compile3.VersionFrontendBuild));
+ error(IO.mapInteger(Compile3.VersionFrontendQFE));
+ error(IO.mapInteger(Compile3.VersionBackendMajor));
+ error(IO.mapInteger(Compile3.VersionBackendMinor));
+ error(IO.mapInteger(Compile3.VersionBackendBuild));
+ error(IO.mapInteger(Compile3.VersionBackendQFE));
+ error(IO.mapStringZ(Compile3.Version));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ ConstantSym &Constant) {
+
+ error(IO.mapInteger(Constant.Type));
+ error(IO.mapEncodedInteger(Constant.Value));
+ error(IO.mapStringZ(Constant.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
+
+ error(IO.mapInteger(Data.Type));
+ error(IO.mapInteger(Data.DataOffset));
+ error(IO.mapInteger(Data.Segment));
+ error(IO.mapStringZ(Data.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(
+ CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
+
+ error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset));
+ error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range));
+ error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap()));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(
+ CVSymbol &CVR,
+ DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
+
+ error(IO.mapInteger(DefRangeFramePointerRelFullScope.Offset));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(
+ CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
+
+ error(IO.mapObject(DefRangeRegisterRel.Hdr.Register));
+ error(IO.mapObject(DefRangeRegisterRel.Hdr.Flags));
+ error(IO.mapObject(DefRangeRegisterRel.Hdr.BasePointerOffset));
+ error(mapLocalVariableAddrRange(IO, DefRangeRegisterRel.Range));
+ error(IO.mapVectorTail(DefRangeRegisterRel.Gaps, MapGap()));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(
+ CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
+
+ error(IO.mapObject(DefRangeRegister.Hdr.Register));
+ error(IO.mapObject(DefRangeRegister.Hdr.MayHaveNoName));
+ error(mapLocalVariableAddrRange(IO, DefRangeRegister.Range));
+ error(IO.mapVectorTail(DefRangeRegister.Gaps, MapGap()));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(
+ CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
+
+ error(IO.mapObject(DefRangeSubfieldRegister.Hdr.Register));
+ error(IO.mapObject(DefRangeSubfieldRegister.Hdr.MayHaveNoName));
+ error(IO.mapObject(DefRangeSubfieldRegister.Hdr.OffsetInParent));
+ error(mapLocalVariableAddrRange(IO, DefRangeSubfieldRegister.Range));
+ error(IO.mapVectorTail(DefRangeSubfieldRegister.Gaps, MapGap()));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(
+ CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
+
+ error(IO.mapInteger(DefRangeSubfield.Program));
+ error(IO.mapInteger(DefRangeSubfield.OffsetInParent));
+ error(mapLocalVariableAddrRange(IO, DefRangeSubfield.Range));
+ error(IO.mapVectorTail(DefRangeSubfield.Gaps, MapGap()));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ DefRangeSym &DefRange) {
+
+ error(IO.mapInteger(DefRange.Program));
+ error(mapLocalVariableAddrRange(IO, DefRange.Range));
+ error(IO.mapVectorTail(DefRange.Gaps, MapGap()));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ FrameCookieSym &FrameCookie) {
+
+ error(IO.mapInteger(FrameCookie.CodeOffset));
+ error(IO.mapInteger(FrameCookie.Register));
+ error(IO.mapEnum(FrameCookie.CookieKind));
+ error(IO.mapInteger(FrameCookie.Flags));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ FrameProcSym &FrameProc) {
+ error(IO.mapInteger(FrameProc.TotalFrameBytes));
+ error(IO.mapInteger(FrameProc.PaddingFrameBytes));
+ error(IO.mapInteger(FrameProc.OffsetToPadding));
+ error(IO.mapInteger(FrameProc.BytesOfCalleeSavedRegisters));
+ error(IO.mapInteger(FrameProc.OffsetOfExceptionHandler));
+ error(IO.mapInteger(FrameProc.SectionIdOfExceptionHandler));
+ error(IO.mapEnum(FrameProc.Flags));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(
+ CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
+
+ error(IO.mapInteger(HeapAllocSite.CodeOffset));
+ error(IO.mapInteger(HeapAllocSite.Segment));
+ error(IO.mapInteger(HeapAllocSite.CallInstructionSize));
+ error(IO.mapInteger(HeapAllocSite.Type));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ InlineSiteSym &InlineSite) {
+
+ error(IO.mapInteger(InlineSite.Parent));
+ error(IO.mapInteger(InlineSite.End));
+ error(IO.mapInteger(InlineSite.Inlinee));
+ error(IO.mapByteVectorTail(InlineSite.AnnotationData));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ RegisterSym &Register) {
+
+ error(IO.mapInteger(Register.Index));
+ error(IO.mapEnum(Register.Register));
+ error(IO.mapStringZ(Register.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ PublicSym32 &Public) {
+
+ error(IO.mapEnum(Public.Flags));
+ error(IO.mapInteger(Public.Offset));
+ error(IO.mapInteger(Public.Segment));
+ error(IO.mapStringZ(Public.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ ProcRefSym &ProcRef) {
+
+ error(IO.mapInteger(ProcRef.SumName));
+ error(IO.mapInteger(ProcRef.SymOffset));
+ error(IO.mapInteger(ProcRef.Module));
+ error(IO.mapStringZ(ProcRef.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
+
+ error(IO.mapInteger(Label.CodeOffset));
+ error(IO.mapInteger(Label.Segment));
+ error(IO.mapEnum(Label.Flags));
+ error(IO.mapStringZ(Label.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
+ error(IO.mapInteger(Local.Type));
+ error(IO.mapEnum(Local.Flags));
+ error(IO.mapStringZ(Local.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ ObjNameSym &ObjName) {
+
+ error(IO.mapInteger(ObjName.Signature));
+ error(IO.mapStringZ(ObjName.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
+ error(IO.mapInteger(Proc.Parent));
+ error(IO.mapInteger(Proc.End));
+ error(IO.mapInteger(Proc.Next));
+ error(IO.mapInteger(Proc.CodeSize));
+ error(IO.mapInteger(Proc.DbgStart));
+ error(IO.mapInteger(Proc.DbgEnd));
+ error(IO.mapInteger(Proc.FunctionType));
+ error(IO.mapInteger(Proc.CodeOffset));
+ error(IO.mapInteger(Proc.Segment));
+ error(IO.mapEnum(Proc.Flags));
+ error(IO.mapStringZ(Proc.Name));
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ ScopeEndSym &ScopeEnd) {
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
+ error(IO.mapVectorN<uint32_t>(
+ Caller.Indices,
+ [](CodeViewRecordIO &IO, TypeIndex &N) { return IO.mapInteger(N); }));
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ RegRelativeSym &RegRel) {
+
+ error(IO.mapInteger(RegRel.Offset));
+ error(IO.mapInteger(RegRel.Type));
+ error(IO.mapEnum(RegRel.Register));
+ error(IO.mapStringZ(RegRel.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ ThreadLocalDataSym &Data) {
+
+ error(IO.mapInteger(Data.Type));
+ error(IO.mapInteger(Data.DataOffset));
+ error(IO.mapInteger(Data.Segment));
+ error(IO.mapStringZ(Data.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
+
+ error(IO.mapInteger(UDT.Type));
+ error(IO.mapStringZ(UDT.Name));
+
+ return Error::success();
+}
+
+Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
+ UsingNamespaceSym &UN) {
+
+ error(IO.mapStringZ(UN.Name));
+
+ 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);
+ switch (CPU) {
+ // FIXME: Add ARM and AArch64 variants here.
+ default:
+ break;
+ case CPUType::Intel8080:
+ case CPUType::Intel8086:
+ case CPUType::Intel80286:
+ case CPUType::Intel80386:
+ case CPUType::Intel80486:
+ case CPUType::Pentium:
+ case CPUType::PentiumPro:
+ case CPUType::Pentium3:
+ switch (EncodedReg) {
+ case EncodedFramePtrReg::None: return RegisterId::NONE;
+ case EncodedFramePtrReg::StackPtr: return RegisterId::VFRAME;
+ case EncodedFramePtrReg::FramePtr: return RegisterId::EBP;
+ case EncodedFramePtrReg::BasePtr: return RegisterId::EBX;
+ }
+ llvm_unreachable("bad encoding");
+ case CPUType::X64:
+ switch (EncodedReg) {
+ case EncodedFramePtrReg::None: return RegisterId::NONE;
+ case EncodedFramePtrReg::StackPtr: return RegisterId::RSP;
+ case EncodedFramePtrReg::FramePtr: return RegisterId::RBP;
+ case EncodedFramePtrReg::BasePtr: return RegisterId::R13;
+ }
+ llvm_unreachable("bad encoding");
+ }
+ return RegisterId::NONE;
+}
+
+EncodedFramePtrReg codeview::encodeFramePtrReg(RegisterId Reg, CPUType CPU) {
+ switch (CPU) {
+ // FIXME: Add ARM and AArch64 variants here.
+ default:
+ break;
+ case CPUType::Intel8080:
+ case CPUType::Intel8086:
+ case CPUType::Intel80286:
+ case CPUType::Intel80386:
+ case CPUType::Intel80486:
+ case CPUType::Pentium:
+ case CPUType::PentiumPro:
+ case CPUType::Pentium3:
+ switch (Reg) {
+ case RegisterId::VFRAME:
+ return EncodedFramePtrReg::StackPtr;
+ case RegisterId::EBP:
+ return EncodedFramePtrReg::FramePtr;
+ case RegisterId::EBX:
+ return EncodedFramePtrReg::BasePtr;
+ default:
+ break;
+ }
+ break;
+ case CPUType::X64:
+ switch (Reg) {
+ case RegisterId::RSP:
+ return EncodedFramePtrReg::StackPtr;
+ case RegisterId::RBP:
+ return EncodedFramePtrReg::FramePtr;
+ case RegisterId::R13:
+ return EncodedFramePtrReg::BasePtr;
+ default:
+ break;
+ }
+ break;
+ }
+ return EncodedFramePtrReg::None;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolSerializer.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolSerializer.cpp
index de9bb42b17..170897257c 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolSerializer.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/SymbolSerializer.cpp
@@ -1,59 +1,59 @@
-//===- SymbolSerializer.cpp -----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-SymbolSerializer::SymbolSerializer(BumpPtrAllocator &Allocator,
- CodeViewContainer Container)
- : Storage(Allocator), Stream(RecordBuffer, support::little), Writer(Stream),
- Mapping(Writer, Container) {}
-
-Error SymbolSerializer::visitSymbolBegin(CVSymbol &Record) {
- assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
-
- Writer.setOffset(0);
-
- if (auto EC = writeRecordPrefix(Record.kind()))
- return EC;
-
- CurrentSymbol = Record.kind();
- if (auto EC = Mapping.visitSymbolBegin(Record))
- return EC;
-
- return Error::success();
-}
-
-Error SymbolSerializer::visitSymbolEnd(CVSymbol &Record) {
- assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
-
- if (auto EC = Mapping.visitSymbolEnd(Record))
- return EC;
-
- uint32_t RecordEnd = Writer.getOffset();
- uint16_t Length = RecordEnd - 2;
- Writer.setOffset(0);
- if (auto EC = Writer.writeInteger(Length))
- return EC;
-
- uint8_t *StableStorage = Storage.Allocate<uint8_t>(RecordEnd);
- ::memcpy(StableStorage, &RecordBuffer[0], RecordEnd);
- Record.RecordData = ArrayRef<uint8_t>(StableStorage, RecordEnd);
- CurrentSymbol.reset();
-
- return Error::success();
-}
+//===- SymbolSerializer.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+SymbolSerializer::SymbolSerializer(BumpPtrAllocator &Allocator,
+ CodeViewContainer Container)
+ : Storage(Allocator), Stream(RecordBuffer, support::little), Writer(Stream),
+ Mapping(Writer, Container) {}
+
+Error SymbolSerializer::visitSymbolBegin(CVSymbol &Record) {
+ assert(!CurrentSymbol.hasValue() && "Already in a symbol mapping!");
+
+ Writer.setOffset(0);
+
+ if (auto EC = writeRecordPrefix(Record.kind()))
+ return EC;
+
+ CurrentSymbol = Record.kind();
+ if (auto EC = Mapping.visitSymbolBegin(Record))
+ return EC;
+
+ return Error::success();
+}
+
+Error SymbolSerializer::visitSymbolEnd(CVSymbol &Record) {
+ assert(CurrentSymbol.hasValue() && "Not in a symbol mapping!");
+
+ if (auto EC = Mapping.visitSymbolEnd(Record))
+ return EC;
+
+ uint32_t RecordEnd = Writer.getOffset();
+ uint16_t Length = RecordEnd - 2;
+ Writer.setOffset(0);
+ if (auto EC = Writer.writeInteger(Length))
+ return EC;
+
+ uint8_t *StableStorage = Storage.Allocate<uint8_t>(RecordEnd);
+ ::memcpy(StableStorage, &RecordBuffer[0], RecordEnd);
+ Record.RecordData = ArrayRef<uint8_t>(StableStorage, RecordEnd);
+ CurrentSymbol.reset();
+
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
index d5fea5ee5e..5886d33a4a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
@@ -1,570 +1,570 @@
-//===-- TypeDumpVisitor.cpp - CodeView type info dumper ----------*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
-
-#include "llvm/ADT/SmallString.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/Formatters.h"
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
-#define CV_TYPE(enum, val) {#enum, enum},
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
-};
-
-#define ENUM_ENTRY(enum_class, enum) \
- { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
-
-static const EnumEntry<uint16_t> ClassOptionNames[] = {
- ENUM_ENTRY(ClassOptions, Packed),
- ENUM_ENTRY(ClassOptions, HasConstructorOrDestructor),
- ENUM_ENTRY(ClassOptions, HasOverloadedOperator),
- ENUM_ENTRY(ClassOptions, Nested),
- ENUM_ENTRY(ClassOptions, ContainsNestedClass),
- ENUM_ENTRY(ClassOptions, HasOverloadedAssignmentOperator),
- ENUM_ENTRY(ClassOptions, HasConversionOperator),
- ENUM_ENTRY(ClassOptions, ForwardReference),
- ENUM_ENTRY(ClassOptions, Scoped),
- ENUM_ENTRY(ClassOptions, HasUniqueName),
- ENUM_ENTRY(ClassOptions, Sealed),
- ENUM_ENTRY(ClassOptions, Intrinsic),
-};
-
-static const EnumEntry<uint8_t> MemberAccessNames[] = {
- ENUM_ENTRY(MemberAccess, None), ENUM_ENTRY(MemberAccess, Private),
- ENUM_ENTRY(MemberAccess, Protected), ENUM_ENTRY(MemberAccess, Public),
-};
-
-static const EnumEntry<uint16_t> MethodOptionNames[] = {
- ENUM_ENTRY(MethodOptions, Pseudo),
- ENUM_ENTRY(MethodOptions, NoInherit),
- ENUM_ENTRY(MethodOptions, NoConstruct),
- ENUM_ENTRY(MethodOptions, CompilerGenerated),
- ENUM_ENTRY(MethodOptions, Sealed),
-};
-
-static const EnumEntry<uint16_t> MemberKindNames[] = {
- ENUM_ENTRY(MethodKind, Vanilla),
- ENUM_ENTRY(MethodKind, Virtual),
- ENUM_ENTRY(MethodKind, Static),
- ENUM_ENTRY(MethodKind, Friend),
- ENUM_ENTRY(MethodKind, IntroducingVirtual),
- ENUM_ENTRY(MethodKind, PureVirtual),
- ENUM_ENTRY(MethodKind, PureIntroducingVirtual),
-};
-
-static const EnumEntry<uint8_t> PtrKindNames[] = {
- ENUM_ENTRY(PointerKind, Near16),
- ENUM_ENTRY(PointerKind, Far16),
- ENUM_ENTRY(PointerKind, Huge16),
- ENUM_ENTRY(PointerKind, BasedOnSegment),
- ENUM_ENTRY(PointerKind, BasedOnValue),
- ENUM_ENTRY(PointerKind, BasedOnSegmentValue),
- ENUM_ENTRY(PointerKind, BasedOnAddress),
- ENUM_ENTRY(PointerKind, BasedOnSegmentAddress),
- ENUM_ENTRY(PointerKind, BasedOnType),
- ENUM_ENTRY(PointerKind, BasedOnSelf),
- ENUM_ENTRY(PointerKind, Near32),
- ENUM_ENTRY(PointerKind, Far32),
- ENUM_ENTRY(PointerKind, Near64),
-};
-
-static const EnumEntry<uint8_t> PtrModeNames[] = {
- ENUM_ENTRY(PointerMode, Pointer),
- ENUM_ENTRY(PointerMode, LValueReference),
- ENUM_ENTRY(PointerMode, PointerToDataMember),
- ENUM_ENTRY(PointerMode, PointerToMemberFunction),
- ENUM_ENTRY(PointerMode, RValueReference),
-};
-
-static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
- ENUM_ENTRY(PointerToMemberRepresentation, Unknown),
- ENUM_ENTRY(PointerToMemberRepresentation, SingleInheritanceData),
- ENUM_ENTRY(PointerToMemberRepresentation, MultipleInheritanceData),
- ENUM_ENTRY(PointerToMemberRepresentation, VirtualInheritanceData),
- ENUM_ENTRY(PointerToMemberRepresentation, GeneralData),
- ENUM_ENTRY(PointerToMemberRepresentation, SingleInheritanceFunction),
- ENUM_ENTRY(PointerToMemberRepresentation, MultipleInheritanceFunction),
- ENUM_ENTRY(PointerToMemberRepresentation, VirtualInheritanceFunction),
- ENUM_ENTRY(PointerToMemberRepresentation, GeneralFunction),
-};
-
-static const EnumEntry<uint16_t> TypeModifierNames[] = {
- ENUM_ENTRY(ModifierOptions, Const), ENUM_ENTRY(ModifierOptions, Volatile),
- ENUM_ENTRY(ModifierOptions, Unaligned),
-};
-
-static const EnumEntry<uint8_t> CallingConventions[] = {
- ENUM_ENTRY(CallingConvention, NearC),
- ENUM_ENTRY(CallingConvention, FarC),
- ENUM_ENTRY(CallingConvention, NearPascal),
- ENUM_ENTRY(CallingConvention, FarPascal),
- ENUM_ENTRY(CallingConvention, NearFast),
- ENUM_ENTRY(CallingConvention, FarFast),
- ENUM_ENTRY(CallingConvention, NearStdCall),
- ENUM_ENTRY(CallingConvention, FarStdCall),
- ENUM_ENTRY(CallingConvention, NearSysCall),
- ENUM_ENTRY(CallingConvention, FarSysCall),
- ENUM_ENTRY(CallingConvention, ThisCall),
- ENUM_ENTRY(CallingConvention, MipsCall),
- ENUM_ENTRY(CallingConvention, Generic),
- ENUM_ENTRY(CallingConvention, AlphaCall),
- ENUM_ENTRY(CallingConvention, PpcCall),
- ENUM_ENTRY(CallingConvention, SHCall),
- ENUM_ENTRY(CallingConvention, ArmCall),
- ENUM_ENTRY(CallingConvention, AM33Call),
- ENUM_ENTRY(CallingConvention, TriCall),
- ENUM_ENTRY(CallingConvention, SH5Call),
- ENUM_ENTRY(CallingConvention, M32RCall),
- ENUM_ENTRY(CallingConvention, ClrCall),
- ENUM_ENTRY(CallingConvention, Inline),
- ENUM_ENTRY(CallingConvention, NearVector),
-};
-
-static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
- ENUM_ENTRY(FunctionOptions, CxxReturnUdt),
- ENUM_ENTRY(FunctionOptions, Constructor),
- ENUM_ENTRY(FunctionOptions, ConstructorWithVirtualBases),
-};
-
-static const EnumEntry<uint16_t> LabelTypeEnum[] = {
- ENUM_ENTRY(LabelType, Near), ENUM_ENTRY(LabelType, Far),
-};
-
-#undef ENUM_ENTRY
-
-static StringRef getLeafTypeName(TypeLeafKind LT) {
- switch (LT) {
-#define TYPE_RECORD(ename, value, name) \
- case ename: \
- return #name;
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
- default:
- break;
- }
- return "UnknownLeaf";
-}
-
-void TypeDumpVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
- codeview::printTypeIndex(*W, FieldName, TI, TpiTypes);
-}
-
-void TypeDumpVisitor::printItemIndex(StringRef FieldName, TypeIndex TI) const {
- codeview::printTypeIndex(*W, FieldName, TI, getSourceTypes());
-}
-
-Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
- return visitTypeBegin(Record, TypeIndex::fromArrayIndex(TpiTypes.size()));
-}
-
-Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
- W->startLine() << getLeafTypeName(Record.kind());
- W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
- W->getOStream() << " {\n";
- W->indent();
- W->printEnum("TypeLeafKind", unsigned(Record.kind()),
- makeArrayRef(LeafTypeNames));
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitTypeEnd(CVType &Record) {
- if (PrintRecordBytes)
- W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.content()));
-
- W->unindent();
- W->startLine() << "}\n";
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitMemberBegin(CVMemberRecord &Record) {
- W->startLine() << getLeafTypeName(Record.Kind);
- W->getOStream() << " {\n";
- W->indent();
- W->printEnum("TypeLeafKind", unsigned(Record.Kind),
- makeArrayRef(LeafTypeNames));
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitMemberEnd(CVMemberRecord &Record) {
- if (PrintRecordBytes)
- W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));
-
- W->unindent();
- W->startLine() << "}\n";
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
- FieldListRecord &FieldList) {
- if (auto EC = codeview::visitMemberRecordStream(FieldList.Data, *this))
- return EC;
-
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringIdRecord &String) {
- printItemIndex("Id", String.getId());
- W->printString("StringData", String.getString());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
- auto Indices = Args.getIndices();
- uint32_t Size = Indices.size();
- W->printNumber("NumArgs", Size);
- ListScope Arguments(*W, "Arguments");
- for (uint32_t I = 0; I < Size; ++I) {
- printTypeIndex("ArgType", Indices[I]);
- }
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringListRecord &Strs) {
- auto Indices = Strs.getIndices();
- uint32_t Size = Indices.size();
- W->printNumber("NumStrings", Size);
- ListScope Arguments(*W, "Strings");
- for (uint32_t I = 0; I < Size; ++I) {
- printItemIndex("String", Indices[I]);
- }
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
- uint16_t Props = static_cast<uint16_t>(Class.getOptions());
- W->printNumber("MemberCount", Class.getMemberCount());
- W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
- printTypeIndex("FieldList", Class.getFieldList());
- printTypeIndex("DerivedFrom", Class.getDerivationList());
- printTypeIndex("VShape", Class.getVTableShape());
- W->printNumber("SizeOf", Class.getSize());
- W->printString("Name", Class.getName());
- if (Props & uint16_t(ClassOptions::HasUniqueName))
- W->printString("LinkageName", Class.getUniqueName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
- uint16_t Props = static_cast<uint16_t>(Union.getOptions());
- W->printNumber("MemberCount", Union.getMemberCount());
- W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
- printTypeIndex("FieldList", Union.getFieldList());
- W->printNumber("SizeOf", Union.getSize());
- W->printString("Name", Union.getName());
- if (Props & uint16_t(ClassOptions::HasUniqueName))
- W->printString("LinkageName", Union.getUniqueName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
- uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
- W->printNumber("NumEnumerators", Enum.getMemberCount());
- W->printFlags("Properties", uint16_t(Enum.getOptions()),
- makeArrayRef(ClassOptionNames));
- printTypeIndex("UnderlyingType", Enum.getUnderlyingType());
- printTypeIndex("FieldListType", Enum.getFieldList());
- W->printString("Name", Enum.getName());
- if (Props & uint16_t(ClassOptions::HasUniqueName))
- W->printString("LinkageName", Enum.getUniqueName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
- printTypeIndex("ElementType", AT.getElementType());
- printTypeIndex("IndexType", AT.getIndexType());
- W->printNumber("SizeOf", AT.getSize());
- W->printString("Name", AT.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
- printTypeIndex("CompleteClass", VFT.getCompleteClass());
- printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
- W->printHex("VFPtrOffset", VFT.getVFPtrOffset());
- W->printString("VFTableName", VFT.getName());
- for (auto N : VFT.getMethodNames())
- W->printString("MethodName", N);
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
- printTypeIndex("ClassType", Id.getClassType());
- printTypeIndex("FunctionType", Id.getFunctionType());
- W->printString("Name", Id.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
- printTypeIndex("ReturnType", Proc.getReturnType());
- W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
- makeArrayRef(CallingConventions));
- W->printFlags("FunctionOptions", uint8_t(Proc.getOptions()),
- makeArrayRef(FunctionOptionEnum));
- W->printNumber("NumParameters", Proc.getParameterCount());
- printTypeIndex("ArgListType", Proc.getArgumentList());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFunctionRecord &MF) {
- printTypeIndex("ReturnType", MF.getReturnType());
- printTypeIndex("ClassType", MF.getClassType());
- printTypeIndex("ThisType", MF.getThisType());
- W->printEnum("CallingConvention", uint8_t(MF.getCallConv()),
- makeArrayRef(CallingConventions));
- W->printFlags("FunctionOptions", uint8_t(MF.getOptions()),
- makeArrayRef(FunctionOptionEnum));
- W->printNumber("NumParameters", MF.getParameterCount());
- printTypeIndex("ArgListType", MF.getArgumentList());
- W->printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
- MethodOverloadListRecord &MethodList) {
- for (auto &M : MethodList.getMethods()) {
- ListScope S(*W, "Method");
- printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions());
- printTypeIndex("Type", M.getType());
- if (M.isIntroducingVirtual())
- W->printHex("VFTableOffset", M.getVFTableOffset());
- }
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
- printItemIndex("ParentScope", Func.getParentScope());
- printTypeIndex("FunctionType", Func.getFunctionType());
- W->printString("Name", Func.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
- W->printString("Guid", formatv("{0}", TS.getGuid()).str());
- W->printNumber("Age", TS.getAge());
- W->printString("Name", TS.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
- printTypeIndex("PointeeType", Ptr.getReferentType());
- W->printEnum("PtrType", unsigned(Ptr.getPointerKind()),
- makeArrayRef(PtrKindNames));
- W->printEnum("PtrMode", unsigned(Ptr.getMode()), makeArrayRef(PtrModeNames));
-
- W->printNumber("IsFlat", Ptr.isFlat());
- W->printNumber("IsConst", Ptr.isConst());
- W->printNumber("IsVolatile", Ptr.isVolatile());
- W->printNumber("IsUnaligned", Ptr.isUnaligned());
- W->printNumber("IsRestrict", Ptr.isRestrict());
- W->printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());
- W->printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());
- W->printNumber("SizeOf", Ptr.getSize());
-
- if (Ptr.isPointerToMember()) {
- const MemberPointerInfo &MI = Ptr.getMemberInfo();
-
- printTypeIndex("ClassType", MI.getContainingType());
- W->printEnum("Representation", uint16_t(MI.getRepresentation()),
- makeArrayRef(PtrMemberRepNames));
- }
-
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
- uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
- printTypeIndex("ModifiedType", Mod.getModifiedType());
- W->printFlags("Modifiers", Mods, makeArrayRef(TypeModifierNames));
-
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BitFieldRecord &BitField) {
- printTypeIndex("Type", BitField.getType());
- W->printNumber("BitSize", BitField.getBitSize());
- W->printNumber("BitOffset", BitField.getBitOffset());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
- VFTableShapeRecord &Shape) {
- W->printNumber("VFEntryCount", Shape.getEntryCount());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
- UdtSourceLineRecord &Line) {
- printTypeIndex("UDT", Line.getUDT());
- printItemIndex("SourceFile", Line.getSourceFile());
- W->printNumber("LineNumber", Line.getLineNumber());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
- UdtModSourceLineRecord &Line) {
- printTypeIndex("UDT", Line.getUDT());
- printItemIndex("SourceFile", Line.getSourceFile());
- W->printNumber("LineNumber", Line.getLineNumber());
- W->printNumber("Module", Line.getModule());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &Args) {
- W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
-
- ListScope Arguments(*W, "Arguments");
- for (auto Arg : Args.getArgs()) {
- printItemIndex("ArgType", Arg);
- }
- return Error::success();
-}
-
-void TypeDumpVisitor::printMemberAttributes(MemberAttributes Attrs) {
- return printMemberAttributes(Attrs.getAccess(), Attrs.getMethodKind(),
- Attrs.getFlags());
-}
-
-void TypeDumpVisitor::printMemberAttributes(MemberAccess Access,
- MethodKind Kind,
- MethodOptions Options) {
- W->printEnum("AccessSpecifier", uint8_t(Access),
- makeArrayRef(MemberAccessNames));
- // Data members will be vanilla. Don't try to print a method kind for them.
- if (Kind != MethodKind::Vanilla)
- W->printEnum("MethodKind", unsigned(Kind), makeArrayRef(MemberKindNames));
- if (Options != MethodOptions::None) {
- W->printFlags("MethodOptions", unsigned(Options),
- makeArrayRef(MethodOptionNames));
- }
-}
-
-Error TypeDumpVisitor::visitUnknownMember(CVMemberRecord &Record) {
- W->printHex("UnknownMember", unsigned(Record.Kind));
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitUnknownType(CVType &Record) {
- W->printEnum("Kind", uint16_t(Record.kind()), makeArrayRef(LeafTypeNames));
- W->printNumber("Length", uint32_t(Record.content().size()));
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- NestedTypeRecord &Nested) {
- printTypeIndex("Type", Nested.getNestedType());
- W->printString("Name", Nested.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- OneMethodRecord &Method) {
- MethodKind K = Method.getMethodKind();
- printMemberAttributes(Method.getAccess(), K, Method.getOptions());
- printTypeIndex("Type", Method.getType());
- // If virtual, then read the vftable offset.
- if (Method.isIntroducingVirtual())
- W->printHex("VFTableOffset", Method.getVFTableOffset());
- W->printString("Name", Method.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- OverloadedMethodRecord &Method) {
- W->printHex("MethodCount", Method.getNumOverloads());
- printTypeIndex("MethodListIndex", Method.getMethodList());
- W->printString("Name", Method.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- DataMemberRecord &Field) {
- printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
- MethodOptions::None);
- printTypeIndex("Type", Field.getType());
- W->printHex("FieldOffset", Field.getFieldOffset());
- W->printString("Name", Field.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- StaticDataMemberRecord &Field) {
- printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
- MethodOptions::None);
- printTypeIndex("Type", Field.getType());
- W->printString("Name", Field.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- VFPtrRecord &VFTable) {
- printTypeIndex("Type", VFTable.getType());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- EnumeratorRecord &Enum) {
- printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
- MethodOptions::None);
- W->printNumber("EnumValue", Enum.getValue());
- W->printString("Name", Enum.getName());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- BaseClassRecord &Base) {
- printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
- MethodOptions::None);
- printTypeIndex("BaseType", Base.getBaseType());
- W->printHex("BaseOffset", Base.getBaseOffset());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- VirtualBaseClassRecord &Base) {
- printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
- MethodOptions::None);
- printTypeIndex("BaseType", Base.getBaseType());
- printTypeIndex("VBPtrType", Base.getVBPtrType());
- W->printHex("VBPtrOffset", Base.getVBPtrOffset());
- W->printHex("VBTableIndex", Base.getVTableIndex());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
- ListContinuationRecord &Cont) {
- printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &LR) {
- W->printEnum("Mode", uint16_t(LR.Mode), makeArrayRef(LabelTypeEnum));
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
- PrecompRecord &Precomp) {
- W->printHex("StartIndex", Precomp.getStartTypeIndex());
- W->printHex("Count", Precomp.getTypesCount());
- W->printHex("Signature", Precomp.getSignature());
- W->printString("PrecompFile", Precomp.getPrecompFilePath());
- return Error::success();
-}
-
-Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
- EndPrecompRecord &EndPrecomp) {
- W->printHex("Signature", EndPrecomp.getSignature());
- return Error::success();
-}
+//===-- TypeDumpVisitor.cpp - CodeView type info dumper ----------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
+
+#include "llvm/ADT/SmallString.h"
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/Formatters.h"
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
+#define CV_TYPE(enum, val) {#enum, enum},
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+};
+
+#define ENUM_ENTRY(enum_class, enum) \
+ { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
+
+static const EnumEntry<uint16_t> ClassOptionNames[] = {
+ ENUM_ENTRY(ClassOptions, Packed),
+ ENUM_ENTRY(ClassOptions, HasConstructorOrDestructor),
+ ENUM_ENTRY(ClassOptions, HasOverloadedOperator),
+ ENUM_ENTRY(ClassOptions, Nested),
+ ENUM_ENTRY(ClassOptions, ContainsNestedClass),
+ ENUM_ENTRY(ClassOptions, HasOverloadedAssignmentOperator),
+ ENUM_ENTRY(ClassOptions, HasConversionOperator),
+ ENUM_ENTRY(ClassOptions, ForwardReference),
+ ENUM_ENTRY(ClassOptions, Scoped),
+ ENUM_ENTRY(ClassOptions, HasUniqueName),
+ ENUM_ENTRY(ClassOptions, Sealed),
+ ENUM_ENTRY(ClassOptions, Intrinsic),
+};
+
+static const EnumEntry<uint8_t> MemberAccessNames[] = {
+ ENUM_ENTRY(MemberAccess, None), ENUM_ENTRY(MemberAccess, Private),
+ ENUM_ENTRY(MemberAccess, Protected), ENUM_ENTRY(MemberAccess, Public),
+};
+
+static const EnumEntry<uint16_t> MethodOptionNames[] = {
+ ENUM_ENTRY(MethodOptions, Pseudo),
+ ENUM_ENTRY(MethodOptions, NoInherit),
+ ENUM_ENTRY(MethodOptions, NoConstruct),
+ ENUM_ENTRY(MethodOptions, CompilerGenerated),
+ ENUM_ENTRY(MethodOptions, Sealed),
+};
+
+static const EnumEntry<uint16_t> MemberKindNames[] = {
+ ENUM_ENTRY(MethodKind, Vanilla),
+ ENUM_ENTRY(MethodKind, Virtual),
+ ENUM_ENTRY(MethodKind, Static),
+ ENUM_ENTRY(MethodKind, Friend),
+ ENUM_ENTRY(MethodKind, IntroducingVirtual),
+ ENUM_ENTRY(MethodKind, PureVirtual),
+ ENUM_ENTRY(MethodKind, PureIntroducingVirtual),
+};
+
+static const EnumEntry<uint8_t> PtrKindNames[] = {
+ ENUM_ENTRY(PointerKind, Near16),
+ ENUM_ENTRY(PointerKind, Far16),
+ ENUM_ENTRY(PointerKind, Huge16),
+ ENUM_ENTRY(PointerKind, BasedOnSegment),
+ ENUM_ENTRY(PointerKind, BasedOnValue),
+ ENUM_ENTRY(PointerKind, BasedOnSegmentValue),
+ ENUM_ENTRY(PointerKind, BasedOnAddress),
+ ENUM_ENTRY(PointerKind, BasedOnSegmentAddress),
+ ENUM_ENTRY(PointerKind, BasedOnType),
+ ENUM_ENTRY(PointerKind, BasedOnSelf),
+ ENUM_ENTRY(PointerKind, Near32),
+ ENUM_ENTRY(PointerKind, Far32),
+ ENUM_ENTRY(PointerKind, Near64),
+};
+
+static const EnumEntry<uint8_t> PtrModeNames[] = {
+ ENUM_ENTRY(PointerMode, Pointer),
+ ENUM_ENTRY(PointerMode, LValueReference),
+ ENUM_ENTRY(PointerMode, PointerToDataMember),
+ ENUM_ENTRY(PointerMode, PointerToMemberFunction),
+ ENUM_ENTRY(PointerMode, RValueReference),
+};
+
+static const EnumEntry<uint16_t> PtrMemberRepNames[] = {
+ ENUM_ENTRY(PointerToMemberRepresentation, Unknown),
+ ENUM_ENTRY(PointerToMemberRepresentation, SingleInheritanceData),
+ ENUM_ENTRY(PointerToMemberRepresentation, MultipleInheritanceData),
+ ENUM_ENTRY(PointerToMemberRepresentation, VirtualInheritanceData),
+ ENUM_ENTRY(PointerToMemberRepresentation, GeneralData),
+ ENUM_ENTRY(PointerToMemberRepresentation, SingleInheritanceFunction),
+ ENUM_ENTRY(PointerToMemberRepresentation, MultipleInheritanceFunction),
+ ENUM_ENTRY(PointerToMemberRepresentation, VirtualInheritanceFunction),
+ ENUM_ENTRY(PointerToMemberRepresentation, GeneralFunction),
+};
+
+static const EnumEntry<uint16_t> TypeModifierNames[] = {
+ ENUM_ENTRY(ModifierOptions, Const), ENUM_ENTRY(ModifierOptions, Volatile),
+ ENUM_ENTRY(ModifierOptions, Unaligned),
+};
+
+static const EnumEntry<uint8_t> CallingConventions[] = {
+ ENUM_ENTRY(CallingConvention, NearC),
+ ENUM_ENTRY(CallingConvention, FarC),
+ ENUM_ENTRY(CallingConvention, NearPascal),
+ ENUM_ENTRY(CallingConvention, FarPascal),
+ ENUM_ENTRY(CallingConvention, NearFast),
+ ENUM_ENTRY(CallingConvention, FarFast),
+ ENUM_ENTRY(CallingConvention, NearStdCall),
+ ENUM_ENTRY(CallingConvention, FarStdCall),
+ ENUM_ENTRY(CallingConvention, NearSysCall),
+ ENUM_ENTRY(CallingConvention, FarSysCall),
+ ENUM_ENTRY(CallingConvention, ThisCall),
+ ENUM_ENTRY(CallingConvention, MipsCall),
+ ENUM_ENTRY(CallingConvention, Generic),
+ ENUM_ENTRY(CallingConvention, AlphaCall),
+ ENUM_ENTRY(CallingConvention, PpcCall),
+ ENUM_ENTRY(CallingConvention, SHCall),
+ ENUM_ENTRY(CallingConvention, ArmCall),
+ ENUM_ENTRY(CallingConvention, AM33Call),
+ ENUM_ENTRY(CallingConvention, TriCall),
+ ENUM_ENTRY(CallingConvention, SH5Call),
+ ENUM_ENTRY(CallingConvention, M32RCall),
+ ENUM_ENTRY(CallingConvention, ClrCall),
+ ENUM_ENTRY(CallingConvention, Inline),
+ ENUM_ENTRY(CallingConvention, NearVector),
+};
+
+static const EnumEntry<uint8_t> FunctionOptionEnum[] = {
+ ENUM_ENTRY(FunctionOptions, CxxReturnUdt),
+ ENUM_ENTRY(FunctionOptions, Constructor),
+ ENUM_ENTRY(FunctionOptions, ConstructorWithVirtualBases),
+};
+
+static const EnumEntry<uint16_t> LabelTypeEnum[] = {
+ ENUM_ENTRY(LabelType, Near), ENUM_ENTRY(LabelType, Far),
+};
+
+#undef ENUM_ENTRY
+
+static StringRef getLeafTypeName(TypeLeafKind LT) {
+ switch (LT) {
+#define TYPE_RECORD(ename, value, name) \
+ case ename: \
+ return #name;
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ default:
+ break;
+ }
+ return "UnknownLeaf";
+}
+
+void TypeDumpVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
+ codeview::printTypeIndex(*W, FieldName, TI, TpiTypes);
+}
+
+void TypeDumpVisitor::printItemIndex(StringRef FieldName, TypeIndex TI) const {
+ codeview::printTypeIndex(*W, FieldName, TI, getSourceTypes());
+}
+
+Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
+ return visitTypeBegin(Record, TypeIndex::fromArrayIndex(TpiTypes.size()));
+}
+
+Error TypeDumpVisitor::visitTypeBegin(CVType &Record, TypeIndex Index) {
+ W->startLine() << getLeafTypeName(Record.kind());
+ W->getOStream() << " (" << HexNumber(Index.getIndex()) << ")";
+ W->getOStream() << " {\n";
+ W->indent();
+ W->printEnum("TypeLeafKind", unsigned(Record.kind()),
+ makeArrayRef(LeafTypeNames));
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitTypeEnd(CVType &Record) {
+ if (PrintRecordBytes)
+ W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.content()));
+
+ W->unindent();
+ W->startLine() << "}\n";
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitMemberBegin(CVMemberRecord &Record) {
+ W->startLine() << getLeafTypeName(Record.Kind);
+ W->getOStream() << " {\n";
+ W->indent();
+ W->printEnum("TypeLeafKind", unsigned(Record.Kind),
+ makeArrayRef(LeafTypeNames));
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitMemberEnd(CVMemberRecord &Record) {
+ if (PrintRecordBytes)
+ W->printBinaryBlock("LeafData", getBytesAsCharacters(Record.Data));
+
+ W->unindent();
+ W->startLine() << "}\n";
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ FieldListRecord &FieldList) {
+ if (auto EC = codeview::visitMemberRecordStream(FieldList.Data, *this))
+ return EC;
+
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringIdRecord &String) {
+ printItemIndex("Id", String.getId());
+ W->printString("StringData", String.getString());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArgListRecord &Args) {
+ auto Indices = Args.getIndices();
+ uint32_t Size = Indices.size();
+ W->printNumber("NumArgs", Size);
+ ListScope Arguments(*W, "Arguments");
+ for (uint32_t I = 0; I < Size; ++I) {
+ printTypeIndex("ArgType", Indices[I]);
+ }
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringListRecord &Strs) {
+ auto Indices = Strs.getIndices();
+ uint32_t Size = Indices.size();
+ W->printNumber("NumStrings", Size);
+ ListScope Arguments(*W, "Strings");
+ for (uint32_t I = 0; I < Size; ++I) {
+ printItemIndex("String", Indices[I]);
+ }
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ClassRecord &Class) {
+ uint16_t Props = static_cast<uint16_t>(Class.getOptions());
+ W->printNumber("MemberCount", Class.getMemberCount());
+ W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
+ printTypeIndex("FieldList", Class.getFieldList());
+ printTypeIndex("DerivedFrom", Class.getDerivationList());
+ printTypeIndex("VShape", Class.getVTableShape());
+ W->printNumber("SizeOf", Class.getSize());
+ W->printString("Name", Class.getName());
+ if (Props & uint16_t(ClassOptions::HasUniqueName))
+ W->printString("LinkageName", Class.getUniqueName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, UnionRecord &Union) {
+ uint16_t Props = static_cast<uint16_t>(Union.getOptions());
+ W->printNumber("MemberCount", Union.getMemberCount());
+ W->printFlags("Properties", Props, makeArrayRef(ClassOptionNames));
+ printTypeIndex("FieldList", Union.getFieldList());
+ W->printNumber("SizeOf", Union.getSize());
+ W->printString("Name", Union.getName());
+ if (Props & uint16_t(ClassOptions::HasUniqueName))
+ W->printString("LinkageName", Union.getUniqueName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, EnumRecord &Enum) {
+ uint16_t Props = static_cast<uint16_t>(Enum.getOptions());
+ W->printNumber("NumEnumerators", Enum.getMemberCount());
+ W->printFlags("Properties", uint16_t(Enum.getOptions()),
+ makeArrayRef(ClassOptionNames));
+ printTypeIndex("UnderlyingType", Enum.getUnderlyingType());
+ printTypeIndex("FieldListType", Enum.getFieldList());
+ W->printString("Name", Enum.getName());
+ if (Props & uint16_t(ClassOptions::HasUniqueName))
+ W->printString("LinkageName", Enum.getUniqueName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ArrayRecord &AT) {
+ printTypeIndex("ElementType", AT.getElementType());
+ printTypeIndex("IndexType", AT.getIndexType());
+ W->printNumber("SizeOf", AT.getSize());
+ W->printString("Name", AT.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, VFTableRecord &VFT) {
+ printTypeIndex("CompleteClass", VFT.getCompleteClass());
+ printTypeIndex("OverriddenVFTable", VFT.getOverriddenVTable());
+ W->printHex("VFPtrOffset", VFT.getVFPtrOffset());
+ W->printString("VFTableName", VFT.getName());
+ for (auto N : VFT.getMethodNames())
+ W->printString("MethodName", N);
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFuncIdRecord &Id) {
+ printTypeIndex("ClassType", Id.getClassType());
+ printTypeIndex("FunctionType", Id.getFunctionType());
+ W->printString("Name", Id.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ProcedureRecord &Proc) {
+ printTypeIndex("ReturnType", Proc.getReturnType());
+ W->printEnum("CallingConvention", uint8_t(Proc.getCallConv()),
+ makeArrayRef(CallingConventions));
+ W->printFlags("FunctionOptions", uint8_t(Proc.getOptions()),
+ makeArrayRef(FunctionOptionEnum));
+ W->printNumber("NumParameters", Proc.getParameterCount());
+ printTypeIndex("ArgListType", Proc.getArgumentList());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, MemberFunctionRecord &MF) {
+ printTypeIndex("ReturnType", MF.getReturnType());
+ printTypeIndex("ClassType", MF.getClassType());
+ printTypeIndex("ThisType", MF.getThisType());
+ W->printEnum("CallingConvention", uint8_t(MF.getCallConv()),
+ makeArrayRef(CallingConventions));
+ W->printFlags("FunctionOptions", uint8_t(MF.getOptions()),
+ makeArrayRef(FunctionOptionEnum));
+ W->printNumber("NumParameters", MF.getParameterCount());
+ printTypeIndex("ArgListType", MF.getArgumentList());
+ W->printNumber("ThisAdjustment", MF.getThisPointerAdjustment());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ MethodOverloadListRecord &MethodList) {
+ for (auto &M : MethodList.getMethods()) {
+ ListScope S(*W, "Method");
+ printMemberAttributes(M.getAccess(), M.getMethodKind(), M.getOptions());
+ printTypeIndex("Type", M.getType());
+ if (M.isIntroducingVirtual())
+ W->printHex("VFTableOffset", M.getVFTableOffset());
+ }
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
+ printItemIndex("ParentScope", Func.getParentScope());
+ printTypeIndex("FunctionType", Func.getFunctionType());
+ W->printString("Name", Func.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, TypeServer2Record &TS) {
+ W->printString("Guid", formatv("{0}", TS.getGuid()).str());
+ W->printNumber("Age", TS.getAge());
+ W->printString("Name", TS.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, PointerRecord &Ptr) {
+ printTypeIndex("PointeeType", Ptr.getReferentType());
+ W->printEnum("PtrType", unsigned(Ptr.getPointerKind()),
+ makeArrayRef(PtrKindNames));
+ W->printEnum("PtrMode", unsigned(Ptr.getMode()), makeArrayRef(PtrModeNames));
+
+ W->printNumber("IsFlat", Ptr.isFlat());
+ W->printNumber("IsConst", Ptr.isConst());
+ W->printNumber("IsVolatile", Ptr.isVolatile());
+ W->printNumber("IsUnaligned", Ptr.isUnaligned());
+ W->printNumber("IsRestrict", Ptr.isRestrict());
+ W->printNumber("IsThisPtr&", Ptr.isLValueReferenceThisPtr());
+ W->printNumber("IsThisPtr&&", Ptr.isRValueReferenceThisPtr());
+ W->printNumber("SizeOf", Ptr.getSize());
+
+ if (Ptr.isPointerToMember()) {
+ const MemberPointerInfo &MI = Ptr.getMemberInfo();
+
+ printTypeIndex("ClassType", MI.getContainingType());
+ W->printEnum("Representation", uint16_t(MI.getRepresentation()),
+ makeArrayRef(PtrMemberRepNames));
+ }
+
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, ModifierRecord &Mod) {
+ uint16_t Mods = static_cast<uint16_t>(Mod.getModifiers());
+ printTypeIndex("ModifiedType", Mod.getModifiedType());
+ W->printFlags("Modifiers", Mods, makeArrayRef(TypeModifierNames));
+
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BitFieldRecord &BitField) {
+ printTypeIndex("Type", BitField.getType());
+ W->printNumber("BitSize", BitField.getBitSize());
+ W->printNumber("BitOffset", BitField.getBitOffset());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ VFTableShapeRecord &Shape) {
+ W->printNumber("VFEntryCount", Shape.getEntryCount());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ UdtSourceLineRecord &Line) {
+ printTypeIndex("UDT", Line.getUDT());
+ printItemIndex("SourceFile", Line.getSourceFile());
+ W->printNumber("LineNumber", Line.getLineNumber());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ UdtModSourceLineRecord &Line) {
+ printTypeIndex("UDT", Line.getUDT());
+ printItemIndex("SourceFile", Line.getSourceFile());
+ W->printNumber("LineNumber", Line.getLineNumber());
+ W->printNumber("Module", Line.getModule());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &Args) {
+ W->printNumber("NumArgs", static_cast<uint32_t>(Args.getArgs().size()));
+
+ ListScope Arguments(*W, "Arguments");
+ for (auto Arg : Args.getArgs()) {
+ printItemIndex("ArgType", Arg);
+ }
+ return Error::success();
+}
+
+void TypeDumpVisitor::printMemberAttributes(MemberAttributes Attrs) {
+ return printMemberAttributes(Attrs.getAccess(), Attrs.getMethodKind(),
+ Attrs.getFlags());
+}
+
+void TypeDumpVisitor::printMemberAttributes(MemberAccess Access,
+ MethodKind Kind,
+ MethodOptions Options) {
+ W->printEnum("AccessSpecifier", uint8_t(Access),
+ makeArrayRef(MemberAccessNames));
+ // Data members will be vanilla. Don't try to print a method kind for them.
+ if (Kind != MethodKind::Vanilla)
+ W->printEnum("MethodKind", unsigned(Kind), makeArrayRef(MemberKindNames));
+ if (Options != MethodOptions::None) {
+ W->printFlags("MethodOptions", unsigned(Options),
+ makeArrayRef(MethodOptionNames));
+ }
+}
+
+Error TypeDumpVisitor::visitUnknownMember(CVMemberRecord &Record) {
+ W->printHex("UnknownMember", unsigned(Record.Kind));
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitUnknownType(CVType &Record) {
+ W->printEnum("Kind", uint16_t(Record.kind()), makeArrayRef(LeafTypeNames));
+ W->printNumber("Length", uint32_t(Record.content().size()));
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ NestedTypeRecord &Nested) {
+ printTypeIndex("Type", Nested.getNestedType());
+ W->printString("Name", Nested.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ OneMethodRecord &Method) {
+ MethodKind K = Method.getMethodKind();
+ printMemberAttributes(Method.getAccess(), K, Method.getOptions());
+ printTypeIndex("Type", Method.getType());
+ // If virtual, then read the vftable offset.
+ if (Method.isIntroducingVirtual())
+ W->printHex("VFTableOffset", Method.getVFTableOffset());
+ W->printString("Name", Method.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ OverloadedMethodRecord &Method) {
+ W->printHex("MethodCount", Method.getNumOverloads());
+ printTypeIndex("MethodListIndex", Method.getMethodList());
+ W->printString("Name", Method.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ DataMemberRecord &Field) {
+ printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
+ MethodOptions::None);
+ printTypeIndex("Type", Field.getType());
+ W->printHex("FieldOffset", Field.getFieldOffset());
+ W->printString("Name", Field.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ StaticDataMemberRecord &Field) {
+ printMemberAttributes(Field.getAccess(), MethodKind::Vanilla,
+ MethodOptions::None);
+ printTypeIndex("Type", Field.getType());
+ W->printString("Name", Field.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ VFPtrRecord &VFTable) {
+ printTypeIndex("Type", VFTable.getType());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ EnumeratorRecord &Enum) {
+ printMemberAttributes(Enum.getAccess(), MethodKind::Vanilla,
+ MethodOptions::None);
+ W->printNumber("EnumValue", Enum.getValue());
+ W->printString("Name", Enum.getName());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ BaseClassRecord &Base) {
+ printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
+ MethodOptions::None);
+ printTypeIndex("BaseType", Base.getBaseType());
+ W->printHex("BaseOffset", Base.getBaseOffset());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ VirtualBaseClassRecord &Base) {
+ printMemberAttributes(Base.getAccess(), MethodKind::Vanilla,
+ MethodOptions::None);
+ printTypeIndex("BaseType", Base.getBaseType());
+ printTypeIndex("VBPtrType", Base.getVBPtrType());
+ W->printHex("VBPtrOffset", Base.getVBPtrOffset());
+ W->printHex("VBTableIndex", Base.getVTableIndex());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownMember(CVMemberRecord &CVR,
+ ListContinuationRecord &Cont) {
+ printTypeIndex("ContinuationIndex", Cont.getContinuationIndex());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, LabelRecord &LR) {
+ W->printEnum("Mode", uint16_t(LR.Mode), makeArrayRef(LabelTypeEnum));
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ PrecompRecord &Precomp) {
+ W->printHex("StartIndex", Precomp.getStartTypeIndex());
+ W->printHex("Count", Precomp.getTypesCount());
+ W->printHex("Signature", Precomp.getSignature());
+ W->printString("PrecompFile", Precomp.getPrecompFilePath());
+ return Error::success();
+}
+
+Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
+ EndPrecompRecord &EndPrecomp) {
+ W->printHex("Signature", EndPrecomp.getSignature());
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeHashing.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeHashing.cpp
index 2dbc11a84f..797d80a450 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeHashing.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeHashing.cpp
@@ -1,80 +1,80 @@
-//===- TypeHashing.cpp -------------------------------------------*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeHashing.h"
-
-#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
-#include "llvm/Support/SHA1.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-LocallyHashedType DenseMapInfo<LocallyHashedType>::Empty{0, {}};
-LocallyHashedType DenseMapInfo<LocallyHashedType>::Tombstone{hash_code(-1), {}};
-
-static std::array<uint8_t, 8> EmptyHash = {
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
-static std::array<uint8_t, 8> TombstoneHash = {
- {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
-
-GloballyHashedType DenseMapInfo<GloballyHashedType>::Empty{EmptyHash};
-GloballyHashedType DenseMapInfo<GloballyHashedType>::Tombstone{TombstoneHash};
-
-LocallyHashedType LocallyHashedType::hashType(ArrayRef<uint8_t> RecordData) {
- return {llvm::hash_value(RecordData), RecordData};
-}
-
-GloballyHashedType
-GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
- ArrayRef<GloballyHashedType> PreviousTypes,
- ArrayRef<GloballyHashedType> PreviousIds) {
- SmallVector<TiReference, 4> Refs;
- discoverTypeIndices(RecordData, Refs);
- SHA1 S;
- S.init();
- uint32_t Off = 0;
- S.update(RecordData.take_front(sizeof(RecordPrefix)));
- RecordData = RecordData.drop_front(sizeof(RecordPrefix));
- for (const auto &Ref : Refs) {
- // Hash any data that comes before this TiRef.
- uint32_t PreLen = Ref.Offset - Off;
- ArrayRef<uint8_t> PreData = RecordData.slice(Off, PreLen);
- S.update(PreData);
- auto Prev = (Ref.Kind == TiRefKind::IndexRef) ? PreviousIds : PreviousTypes;
-
- auto RefData = RecordData.slice(Ref.Offset, Ref.Count * sizeof(TypeIndex));
- // For each type index referenced, add in the previously computed hash
- // value of that type.
- ArrayRef<TypeIndex> Indices(
- reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count);
- for (TypeIndex TI : Indices) {
- ArrayRef<uint8_t> BytesToHash;
- 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);
- }
-
- Off = Ref.Offset + Ref.Count * sizeof(TypeIndex);
- }
-
- // Don't forget to add in any trailing bytes.
- auto TrailingBytes = RecordData.drop_front(Off);
- S.update(TrailingBytes);
-
- return {S.final().take_back(8)};
-}
+//===- TypeHashing.cpp -------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeHashing.h"
+
+#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
+#include "llvm/Support/SHA1.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+LocallyHashedType DenseMapInfo<LocallyHashedType>::Empty{0, {}};
+LocallyHashedType DenseMapInfo<LocallyHashedType>::Tombstone{hash_code(-1), {}};
+
+static std::array<uint8_t, 8> EmptyHash = {
+ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+static std::array<uint8_t, 8> TombstoneHash = {
+ {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
+
+GloballyHashedType DenseMapInfo<GloballyHashedType>::Empty{EmptyHash};
+GloballyHashedType DenseMapInfo<GloballyHashedType>::Tombstone{TombstoneHash};
+
+LocallyHashedType LocallyHashedType::hashType(ArrayRef<uint8_t> RecordData) {
+ return {llvm::hash_value(RecordData), RecordData};
+}
+
+GloballyHashedType
+GloballyHashedType::hashType(ArrayRef<uint8_t> RecordData,
+ ArrayRef<GloballyHashedType> PreviousTypes,
+ ArrayRef<GloballyHashedType> PreviousIds) {
+ SmallVector<TiReference, 4> Refs;
+ discoverTypeIndices(RecordData, Refs);
+ SHA1 S;
+ S.init();
+ uint32_t Off = 0;
+ S.update(RecordData.take_front(sizeof(RecordPrefix)));
+ RecordData = RecordData.drop_front(sizeof(RecordPrefix));
+ for (const auto &Ref : Refs) {
+ // Hash any data that comes before this TiRef.
+ uint32_t PreLen = Ref.Offset - Off;
+ ArrayRef<uint8_t> PreData = RecordData.slice(Off, PreLen);
+ S.update(PreData);
+ auto Prev = (Ref.Kind == TiRefKind::IndexRef) ? PreviousIds : PreviousTypes;
+
+ auto RefData = RecordData.slice(Ref.Offset, Ref.Count * sizeof(TypeIndex));
+ // For each type index referenced, add in the previously computed hash
+ // value of that type.
+ ArrayRef<TypeIndex> Indices(
+ reinterpret_cast<const TypeIndex *>(RefData.data()), Ref.Count);
+ for (TypeIndex TI : Indices) {
+ ArrayRef<uint8_t> BytesToHash;
+ 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);
+ }
+
+ Off = Ref.Offset + Ref.Count * sizeof(TypeIndex);
+ }
+
+ // Don't forget to add in any trailing bytes.
+ auto TrailingBytes = RecordData.drop_front(Off);
+ S.update(TrailingBytes);
+
+ return {S.final().take_back(8)};
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndex.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndex.cpp
index 604d342448..201197a728 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndex.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndex.cpp
@@ -1,106 +1,106 @@
-//===-- TypeIndex.cpp - CodeView type index ---------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-
-#include "llvm/DebugInfo/CodeView/TypeCollection.h"
-#include "llvm/Support/ScopedPrinter.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-namespace {
-struct SimpleTypeEntry {
- StringRef Name;
- SimpleTypeKind Kind;
-};
-
-/// The names here all end in "*". If the simple type is a pointer type, we
-/// return the whole name. Otherwise we lop off the last character in our
-/// StringRef.
-static const SimpleTypeEntry SimpleTypeNames[] = {
- {"void*", SimpleTypeKind::Void},
- {"<not translated>*", SimpleTypeKind::NotTranslated},
- {"HRESULT*", SimpleTypeKind::HResult},
- {"signed char*", SimpleTypeKind::SignedCharacter},
- {"unsigned char*", SimpleTypeKind::UnsignedCharacter},
- {"char*", SimpleTypeKind::NarrowCharacter},
- {"wchar_t*", SimpleTypeKind::WideCharacter},
- {"char16_t*", SimpleTypeKind::Character16},
- {"char32_t*", SimpleTypeKind::Character32},
- {"__int8*", SimpleTypeKind::SByte},
- {"unsigned __int8*", SimpleTypeKind::Byte},
- {"short*", SimpleTypeKind::Int16Short},
- {"unsigned short*", SimpleTypeKind::UInt16Short},
- {"__int16*", SimpleTypeKind::Int16},
- {"unsigned __int16*", SimpleTypeKind::UInt16},
- {"long*", SimpleTypeKind::Int32Long},
- {"unsigned long*", SimpleTypeKind::UInt32Long},
- {"int*", SimpleTypeKind::Int32},
- {"unsigned*", SimpleTypeKind::UInt32},
- {"__int64*", SimpleTypeKind::Int64Quad},
- {"unsigned __int64*", SimpleTypeKind::UInt64Quad},
- {"__int64*", SimpleTypeKind::Int64},
- {"unsigned __int64*", SimpleTypeKind::UInt64},
- {"__int128*", SimpleTypeKind::Int128},
- {"unsigned __int128*", SimpleTypeKind::UInt128},
- {"__half*", SimpleTypeKind::Float16},
- {"float*", SimpleTypeKind::Float32},
- {"float*", SimpleTypeKind::Float32PartialPrecision},
- {"__float48*", SimpleTypeKind::Float48},
- {"double*", SimpleTypeKind::Float64},
- {"long double*", SimpleTypeKind::Float80},
- {"__float128*", SimpleTypeKind::Float128},
- {"_Complex float*", SimpleTypeKind::Complex32},
- {"_Complex double*", SimpleTypeKind::Complex64},
- {"_Complex long double*", SimpleTypeKind::Complex80},
- {"_Complex __float128*", SimpleTypeKind::Complex128},
- {"bool*", SimpleTypeKind::Boolean8},
- {"__bool16*", SimpleTypeKind::Boolean16},
- {"__bool32*", SimpleTypeKind::Boolean32},
- {"__bool64*", SimpleTypeKind::Boolean64},
-};
-} // namespace
-
-StringRef TypeIndex::simpleTypeName(TypeIndex TI) {
- assert(TI.isNoneType() || TI.isSimple());
-
- if (TI.isNoneType())
- return "<no type>";
-
- if (TI == TypeIndex::NullptrT())
- return "std::nullptr_t";
-
- // This is a simple type.
- for (const auto &SimpleTypeName : SimpleTypeNames) {
- if (SimpleTypeName.Kind == TI.getSimpleKind()) {
- if (TI.getSimpleMode() == SimpleTypeMode::Direct)
- return SimpleTypeName.Name.drop_back(1);
- // Otherwise, this is a pointer type. We gloss over the distinction
- // between near, far, 64, 32, etc, and just give a pointer type.
- return SimpleTypeName.Name;
- }
- }
- return "<unknown simple type>";
-}
-
-void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
- TypeIndex TI, TypeCollection &Types) {
- StringRef TypeName;
- if (!TI.isNoneType()) {
- if (TI.isSimple())
- TypeName = TypeIndex::simpleTypeName(TI);
- else
- TypeName = Types.getTypeName(TI);
- }
-
- if (!TypeName.empty())
- Printer.printHex(FieldName, TypeName, TI.getIndex());
- else
- Printer.printHex(FieldName, TI.getIndex());
-}
+//===-- TypeIndex.cpp - CodeView type index ---------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+
+#include "llvm/DebugInfo/CodeView/TypeCollection.h"
+#include "llvm/Support/ScopedPrinter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+namespace {
+struct SimpleTypeEntry {
+ StringRef Name;
+ SimpleTypeKind Kind;
+};
+
+/// The names here all end in "*". If the simple type is a pointer type, we
+/// return the whole name. Otherwise we lop off the last character in our
+/// StringRef.
+static const SimpleTypeEntry SimpleTypeNames[] = {
+ {"void*", SimpleTypeKind::Void},
+ {"<not translated>*", SimpleTypeKind::NotTranslated},
+ {"HRESULT*", SimpleTypeKind::HResult},
+ {"signed char*", SimpleTypeKind::SignedCharacter},
+ {"unsigned char*", SimpleTypeKind::UnsignedCharacter},
+ {"char*", SimpleTypeKind::NarrowCharacter},
+ {"wchar_t*", SimpleTypeKind::WideCharacter},
+ {"char16_t*", SimpleTypeKind::Character16},
+ {"char32_t*", SimpleTypeKind::Character32},
+ {"__int8*", SimpleTypeKind::SByte},
+ {"unsigned __int8*", SimpleTypeKind::Byte},
+ {"short*", SimpleTypeKind::Int16Short},
+ {"unsigned short*", SimpleTypeKind::UInt16Short},
+ {"__int16*", SimpleTypeKind::Int16},
+ {"unsigned __int16*", SimpleTypeKind::UInt16},
+ {"long*", SimpleTypeKind::Int32Long},
+ {"unsigned long*", SimpleTypeKind::UInt32Long},
+ {"int*", SimpleTypeKind::Int32},
+ {"unsigned*", SimpleTypeKind::UInt32},
+ {"__int64*", SimpleTypeKind::Int64Quad},
+ {"unsigned __int64*", SimpleTypeKind::UInt64Quad},
+ {"__int64*", SimpleTypeKind::Int64},
+ {"unsigned __int64*", SimpleTypeKind::UInt64},
+ {"__int128*", SimpleTypeKind::Int128},
+ {"unsigned __int128*", SimpleTypeKind::UInt128},
+ {"__half*", SimpleTypeKind::Float16},
+ {"float*", SimpleTypeKind::Float32},
+ {"float*", SimpleTypeKind::Float32PartialPrecision},
+ {"__float48*", SimpleTypeKind::Float48},
+ {"double*", SimpleTypeKind::Float64},
+ {"long double*", SimpleTypeKind::Float80},
+ {"__float128*", SimpleTypeKind::Float128},
+ {"_Complex float*", SimpleTypeKind::Complex32},
+ {"_Complex double*", SimpleTypeKind::Complex64},
+ {"_Complex long double*", SimpleTypeKind::Complex80},
+ {"_Complex __float128*", SimpleTypeKind::Complex128},
+ {"bool*", SimpleTypeKind::Boolean8},
+ {"__bool16*", SimpleTypeKind::Boolean16},
+ {"__bool32*", SimpleTypeKind::Boolean32},
+ {"__bool64*", SimpleTypeKind::Boolean64},
+};
+} // namespace
+
+StringRef TypeIndex::simpleTypeName(TypeIndex TI) {
+ assert(TI.isNoneType() || TI.isSimple());
+
+ if (TI.isNoneType())
+ return "<no type>";
+
+ if (TI == TypeIndex::NullptrT())
+ return "std::nullptr_t";
+
+ // This is a simple type.
+ for (const auto &SimpleTypeName : SimpleTypeNames) {
+ if (SimpleTypeName.Kind == TI.getSimpleKind()) {
+ if (TI.getSimpleMode() == SimpleTypeMode::Direct)
+ return SimpleTypeName.Name.drop_back(1);
+ // Otherwise, this is a pointer type. We gloss over the distinction
+ // between near, far, 64, 32, etc, and just give a pointer type.
+ return SimpleTypeName.Name;
+ }
+ }
+ return "<unknown simple type>";
+}
+
+void llvm::codeview::printTypeIndex(ScopedPrinter &Printer, StringRef FieldName,
+ TypeIndex TI, TypeCollection &Types) {
+ StringRef TypeName;
+ if (!TI.isNoneType()) {
+ if (TI.isSimple())
+ TypeName = TypeIndex::simpleTypeName(TI);
+ else
+ TypeName = Types.getTypeName(TI);
+ }
+
+ if (!TypeName.empty())
+ Printer.printHex(FieldName, TypeName, TI.getIndex());
+ else
+ Printer.printHex(FieldName, TI.getIndex());
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
index 682747a2b8..bc7759b12e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeIndexDiscovery.cpp
@@ -1,523 +1,523 @@
-//===- TypeIndexDiscovery.cpp -----------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
+//===- TypeIndexDiscovery.cpp -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/Endian.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-static inline MethodKind getMethodKind(uint16_t Attrs) {
- Attrs &= uint16_t(MethodOptions::MethodKindMask);
- Attrs >>= 2;
- return MethodKind(Attrs);
-}
-
-static inline bool isIntroVirtual(uint16_t Attrs) {
- MethodKind MK = getMethodKind(Attrs);
- return MK == MethodKind::IntroducingVirtual ||
- MK == MethodKind::PureIntroducingVirtual;
-}
-
-static inline PointerMode getPointerMode(uint32_t Attrs) {
- return static_cast<PointerMode>((Attrs >> PointerRecord::PointerModeShift) &
- PointerRecord::PointerModeMask);
-}
-
-static inline bool isMemberPointer(uint32_t Attrs) {
- PointerMode Mode = getPointerMode(Attrs);
- return Mode == PointerMode::PointerToDataMember ||
- Mode == PointerMode::PointerToMemberFunction;
-}
-
-static inline uint32_t getEncodedIntegerLength(ArrayRef<uint8_t> Data) {
- uint16_t N = support::endian::read16le(Data.data());
- if (N < LF_NUMERIC)
- return 2;
-
- assert(N <= LF_UQUADWORD);
-
- constexpr uint32_t Sizes[] = {
- 1, // LF_CHAR
- 2, // LF_SHORT
- 2, // LF_USHORT
- 4, // LF_LONG
- 4, // LF_ULONG
- 4, // LF_REAL32
- 8, // LF_REAL64
- 10, // LF_REAL80
- 16, // LF_REAL128
- 8, // LF_QUADWORD
- 8, // LF_UQUADWORD
- };
-
- return 2 + Sizes[N - LF_NUMERIC];
-}
-
-static inline uint32_t getCStringLength(ArrayRef<uint8_t> Data) {
- const char *S = reinterpret_cast<const char *>(Data.data());
- return strlen(S) + 1;
-}
-
-static void handleMethodOverloadList(ArrayRef<uint8_t> Content,
- SmallVectorImpl<TiReference> &Refs) {
- uint32_t Offset = 0;
-
- while (!Content.empty()) {
- // Array of:
- // 0: Attrs
- // 2: Padding
- // 4: TypeIndex
- // if (isIntroVirtual())
- // 8: VFTableOffset
-
- // At least 8 bytes are guaranteed. 4 extra bytes come iff function is an
- // intro virtual.
- uint32_t Len = 8;
-
- uint16_t Attrs = support::endian::read16le(Content.data());
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
-
- if (LLVM_UNLIKELY(isIntroVirtual(Attrs)))
- Len += 4;
- Offset += Len;
- Content = Content.drop_front(Len);
- }
-}
-
-static uint32_t handleBaseClass(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: TypeIndex
- // 8: Encoded Integer
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
- return 8 + getEncodedIntegerLength(Data.drop_front(8));
-}
-
-static uint32_t handleEnumerator(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: Encoded Integer
- // <next>: Name
- uint32_t Size = 4 + getEncodedIntegerLength(Data.drop_front(4));
- return Size + getCStringLength(Data.drop_front(Size));
-}
-
-static uint32_t handleDataMember(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: TypeIndex
- // 8: Encoded Integer
- // <next>: Name
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
- uint32_t Size = 8 + getEncodedIntegerLength(Data.drop_front(8));
- return Size + getCStringLength(Data.drop_front(Size));
-}
-
-static uint32_t handleOverloadedMethod(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: TypeIndex
- // 8: Name
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
- return 8 + getCStringLength(Data.drop_front(8));
-}
-
-static uint32_t handleOneMethod(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Attributes
- // 4: Type
- // if (isIntroVirtual)
- // 8: VFTableOffset
- // <next>: Name
- uint32_t Size = 8;
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
-
- uint16_t Attrs = support::endian::read16le(Data.drop_front(2).data());
- if (LLVM_UNLIKELY(isIntroVirtual(Attrs)))
- Size += 4;
-
- return Size + getCStringLength(Data.drop_front(Size));
-}
-
-static uint32_t handleNestedType(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: TypeIndex
- // 8: Name
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
- return 8 + getCStringLength(Data.drop_front(8));
-}
-
-static uint32_t handleStaticDataMember(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: TypeIndex
- // 8: Name
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
- return 8 + getCStringLength(Data.drop_front(8));
-}
-
-static uint32_t handleVirtualBaseClass(ArrayRef<uint8_t> Data, uint32_t Offset,
- bool IsIndirect,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Attrs
- // 4: TypeIndex
- // 8: TypeIndex
- // 12: Encoded Integer
- // <next>: Encoded Integer
- uint32_t Size = 12;
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 2});
- Size += getEncodedIntegerLength(Data.drop_front(Size));
- Size += getEncodedIntegerLength(Data.drop_front(Size));
- return Size;
-}
-
-static uint32_t handleVFPtr(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: TypeIndex
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
- return 8;
-}
-
-static uint32_t handleListContinuation(ArrayRef<uint8_t> Data, uint32_t Offset,
- SmallVectorImpl<TiReference> &Refs) {
- // 0: Kind
- // 2: Padding
- // 4: TypeIndex
- Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
- return 8;
-}
-
-static void handleFieldList(ArrayRef<uint8_t> Content,
- SmallVectorImpl<TiReference> &Refs) {
- uint32_t Offset = 0;
- uint32_t ThisLen = 0;
- while (!Content.empty()) {
- TypeLeafKind Kind =
- static_cast<TypeLeafKind>(support::endian::read16le(Content.data()));
- switch (Kind) {
- case LF_BCLASS:
- ThisLen = handleBaseClass(Content, Offset, Refs);
- break;
- case LF_ENUMERATE:
- ThisLen = handleEnumerator(Content, Offset, Refs);
- break;
- case LF_MEMBER:
- ThisLen = handleDataMember(Content, Offset, Refs);
- break;
- case LF_METHOD:
- ThisLen = handleOverloadedMethod(Content, Offset, Refs);
- break;
- case LF_ONEMETHOD:
- ThisLen = handleOneMethod(Content, Offset, Refs);
- break;
- case LF_NESTTYPE:
- ThisLen = handleNestedType(Content, Offset, Refs);
- break;
- case LF_STMEMBER:
- ThisLen = handleStaticDataMember(Content, Offset, Refs);
- break;
- case LF_VBCLASS:
- case LF_IVBCLASS:
- ThisLen =
- handleVirtualBaseClass(Content, Offset, Kind == LF_VBCLASS, Refs);
- break;
- case LF_VFUNCTAB:
- ThisLen = handleVFPtr(Content, Offset, Refs);
- break;
- case LF_INDEX:
- ThisLen = handleListContinuation(Content, Offset, Refs);
- break;
- default:
- return;
- }
- Content = Content.drop_front(ThisLen);
- Offset += ThisLen;
- if (!Content.empty()) {
- uint8_t Pad = Content.front();
- if (Pad >= LF_PAD0) {
- uint32_t Skip = Pad & 0x0F;
- Content = Content.drop_front(Skip);
- Offset += Skip;
- }
- }
- }
-}
-
-static void handlePointer(ArrayRef<uint8_t> Content,
- SmallVectorImpl<TiReference> &Refs) {
- Refs.push_back({TiRefKind::TypeRef, 0, 1});
-
- uint32_t Attrs = support::endian::read32le(Content.drop_front(4).data());
- if (isMemberPointer(Attrs))
- Refs.push_back({TiRefKind::TypeRef, 8, 1});
-}
-
-static void discoverTypeIndices(ArrayRef<uint8_t> Content, TypeLeafKind Kind,
- SmallVectorImpl<TiReference> &Refs) {
- uint32_t Count;
- // FIXME: In the future it would be nice if we could avoid hardcoding these
- // values. One idea is to define some structures representing these types
- // that would allow the use of offsetof().
- switch (Kind) {
- case TypeLeafKind::LF_FUNC_ID:
- Refs.push_back({TiRefKind::IndexRef, 0, 1});
- Refs.push_back({TiRefKind::TypeRef, 4, 1});
- break;
- case TypeLeafKind::LF_MFUNC_ID:
- Refs.push_back({TiRefKind::TypeRef, 0, 2});
- break;
- case TypeLeafKind::LF_STRING_ID:
- Refs.push_back({TiRefKind::IndexRef, 0, 1});
- break;
- case TypeLeafKind::LF_SUBSTR_LIST:
- Count = support::endian::read32le(Content.data());
- if (Count > 0)
- Refs.push_back({TiRefKind::IndexRef, 4, Count});
- break;
- case TypeLeafKind::LF_BUILDINFO:
- Count = support::endian::read16le(Content.data());
- if (Count > 0)
- Refs.push_back({TiRefKind::IndexRef, 2, Count});
- break;
- case TypeLeafKind::LF_UDT_SRC_LINE:
- Refs.push_back({TiRefKind::TypeRef, 0, 1});
- Refs.push_back({TiRefKind::IndexRef, 4, 1});
- break;
- case TypeLeafKind::LF_UDT_MOD_SRC_LINE:
- Refs.push_back({TiRefKind::TypeRef, 0, 1});
- break;
- case TypeLeafKind::LF_MODIFIER:
- Refs.push_back({TiRefKind::TypeRef, 0, 1});
- break;
- case TypeLeafKind::LF_PROCEDURE:
- Refs.push_back({TiRefKind::TypeRef, 0, 1});
- Refs.push_back({TiRefKind::TypeRef, 8, 1});
- break;
- case TypeLeafKind::LF_MFUNCTION:
- Refs.push_back({TiRefKind::TypeRef, 0, 3});
- Refs.push_back({TiRefKind::TypeRef, 16, 1});
- break;
- case TypeLeafKind::LF_ARGLIST:
- Count = support::endian::read32le(Content.data());
- if (Count > 0)
- Refs.push_back({TiRefKind::TypeRef, 4, Count});
- break;
- case TypeLeafKind::LF_ARRAY:
- Refs.push_back({TiRefKind::TypeRef, 0, 2});
- break;
- case TypeLeafKind::LF_CLASS:
- case TypeLeafKind::LF_STRUCTURE:
- case TypeLeafKind::LF_INTERFACE:
- Refs.push_back({TiRefKind::TypeRef, 4, 3});
- break;
- case TypeLeafKind::LF_UNION:
- Refs.push_back({TiRefKind::TypeRef, 4, 1});
- break;
- case TypeLeafKind::LF_ENUM:
- Refs.push_back({TiRefKind::TypeRef, 4, 2});
- break;
- case TypeLeafKind::LF_BITFIELD:
- Refs.push_back({TiRefKind::TypeRef, 0, 1});
- break;
- case TypeLeafKind::LF_VFTABLE:
- Refs.push_back({TiRefKind::TypeRef, 0, 2});
- break;
- case TypeLeafKind::LF_VTSHAPE:
- break;
- case TypeLeafKind::LF_METHODLIST:
- handleMethodOverloadList(Content, Refs);
- break;
- case TypeLeafKind::LF_FIELDLIST:
- handleFieldList(Content, Refs);
- break;
- case TypeLeafKind::LF_POINTER:
- handlePointer(Content, Refs);
- break;
- default:
- break;
- }
-}
-
-static bool discoverTypeIndices(ArrayRef<uint8_t> Content, SymbolKind Kind,
- SmallVectorImpl<TiReference> &Refs) {
- uint32_t Count;
- // FIXME: In the future it would be nice if we could avoid hardcoding these
- // values. One idea is to define some structures representing these types
- // that would allow the use of offsetof().
- switch (Kind) {
- 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;
- case SymbolKind::S_GDATA32:
- case SymbolKind::S_LDATA32:
- Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
- break;
- case SymbolKind::S_BUILDINFO:
- Refs.push_back({TiRefKind::IndexRef, 0, 1}); // Compile flags
- break;
- case SymbolKind::S_LTHREAD32:
- case SymbolKind::S_GTHREAD32:
- Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
- break;
- case SymbolKind::S_FILESTATIC:
- Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
- break;
- case SymbolKind::S_LOCAL:
- Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
- break;
- case SymbolKind::S_REGISTER:
- Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
- break;
- case SymbolKind::S_CONSTANT:
- Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
- break;
- case SymbolKind::S_BPREL32:
- case SymbolKind::S_REGREL32:
- Refs.push_back({TiRefKind::TypeRef, 4, 1}); // Type
- break;
- case SymbolKind::S_CALLSITEINFO:
- Refs.push_back({TiRefKind::TypeRef, 8, 1}); // Call signature
- break;
- case SymbolKind::S_CALLERS:
- case SymbolKind::S_CALLEES:
- case SymbolKind::S_INLINEES:
- // The record is a count followed by an array of type indices.
- Count = *reinterpret_cast<const ulittle32_t *>(Content.data());
- Refs.push_back({TiRefKind::IndexRef, 4, Count}); // Callees
- break;
- case SymbolKind::S_INLINESITE:
- Refs.push_back({TiRefKind::IndexRef, 8, 1}); // ID of inlinee
- break;
- case SymbolKind::S_HEAPALLOCSITE:
- Refs.push_back({TiRefKind::TypeRef, 8, 1}); // UDT allocated
- break;
-
- // Defranges don't have types, just registers and code offsets.
- case SymbolKind::S_DEFRANGE_REGISTER:
- case SymbolKind::S_DEFRANGE_REGISTER_REL:
- case SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL:
- case SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
- case SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER:
- case SymbolKind::S_DEFRANGE_SUBFIELD:
- break;
-
- // No type references.
- case SymbolKind::S_LABEL32:
- case SymbolKind::S_OBJNAME:
- case SymbolKind::S_COMPILE:
- case SymbolKind::S_COMPILE2:
- case SymbolKind::S_COMPILE3:
- case SymbolKind::S_ENVBLOCK:
- case SymbolKind::S_BLOCK32:
- case SymbolKind::S_FRAMEPROC:
- case SymbolKind::S_THUNK32:
- case SymbolKind::S_FRAMECOOKIE:
- case SymbolKind::S_UNAMESPACE:
- break;
- // Scope ending symbols.
- case SymbolKind::S_END:
- case SymbolKind::S_INLINESITE_END:
- case SymbolKind::S_PROC_ID_END:
- break;
- default:
- return false; // Unknown symbol.
- }
- return true;
-}
-
-void llvm::codeview::discoverTypeIndices(const CVType &Type,
- SmallVectorImpl<TiReference> &Refs) {
- ::discoverTypeIndices(Type.content(), Type.kind(), Refs);
-}
-
-static void resolveTypeIndexReferences(ArrayRef<uint8_t> RecordData,
- ArrayRef<TiReference> Refs,
- SmallVectorImpl<TypeIndex> &Indices) {
- Indices.clear();
-
- if (Refs.empty())
- return;
-
- RecordData = RecordData.drop_front(sizeof(RecordPrefix));
-
- BinaryStreamReader Reader(RecordData, support::little);
- for (const auto &Ref : Refs) {
- Reader.setOffset(Ref.Offset);
- FixedStreamArray<TypeIndex> Run;
- cantFail(Reader.readArray(Run, Ref.Count));
- Indices.append(Run.begin(), Run.end());
- }
-}
-
-void llvm::codeview::discoverTypeIndices(const CVType &Type,
- SmallVectorImpl<TypeIndex> &Indices) {
- return discoverTypeIndices(Type.RecordData, Indices);
-}
-
-void llvm::codeview::discoverTypeIndices(ArrayRef<uint8_t> RecordData,
- SmallVectorImpl<TypeIndex> &Indices) {
- SmallVector<TiReference, 4> Refs;
- discoverTypeIndices(RecordData, Refs);
- resolveTypeIndexReferences(RecordData, Refs, Indices);
-}
-
-void llvm::codeview::discoverTypeIndices(ArrayRef<uint8_t> RecordData,
- SmallVectorImpl<TiReference> &Refs) {
- const RecordPrefix *P =
- reinterpret_cast<const RecordPrefix *>(RecordData.data());
- TypeLeafKind K = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
- ::discoverTypeIndices(RecordData.drop_front(sizeof(RecordPrefix)), K, Refs);
-}
-
-bool llvm::codeview::discoverTypeIndicesInSymbol(
- const CVSymbol &Sym, SmallVectorImpl<TiReference> &Refs) {
- SymbolKind K = Sym.kind();
- return ::discoverTypeIndices(Sym.content(), K, Refs);
-}
-
-bool llvm::codeview::discoverTypeIndicesInSymbol(
- ArrayRef<uint8_t> RecordData, SmallVectorImpl<TiReference> &Refs) {
- const RecordPrefix *P =
- reinterpret_cast<const RecordPrefix *>(RecordData.data());
- SymbolKind K = static_cast<SymbolKind>(uint16_t(P->RecordKind));
- return ::discoverTypeIndices(RecordData.drop_front(sizeof(RecordPrefix)), K,
- Refs);
-}
-
-bool llvm::codeview::discoverTypeIndicesInSymbol(
- ArrayRef<uint8_t> RecordData, SmallVectorImpl<TypeIndex> &Indices) {
- SmallVector<TiReference, 2> Refs;
- if (!discoverTypeIndicesInSymbol(RecordData, Refs))
- return false;
- resolveTypeIndexReferences(RecordData, Refs, Indices);
- return true;
-}
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+static inline MethodKind getMethodKind(uint16_t Attrs) {
+ Attrs &= uint16_t(MethodOptions::MethodKindMask);
+ Attrs >>= 2;
+ return MethodKind(Attrs);
+}
+
+static inline bool isIntroVirtual(uint16_t Attrs) {
+ MethodKind MK = getMethodKind(Attrs);
+ return MK == MethodKind::IntroducingVirtual ||
+ MK == MethodKind::PureIntroducingVirtual;
+}
+
+static inline PointerMode getPointerMode(uint32_t Attrs) {
+ return static_cast<PointerMode>((Attrs >> PointerRecord::PointerModeShift) &
+ PointerRecord::PointerModeMask);
+}
+
+static inline bool isMemberPointer(uint32_t Attrs) {
+ PointerMode Mode = getPointerMode(Attrs);
+ return Mode == PointerMode::PointerToDataMember ||
+ Mode == PointerMode::PointerToMemberFunction;
+}
+
+static inline uint32_t getEncodedIntegerLength(ArrayRef<uint8_t> Data) {
+ uint16_t N = support::endian::read16le(Data.data());
+ if (N < LF_NUMERIC)
+ return 2;
+
+ assert(N <= LF_UQUADWORD);
+
+ constexpr uint32_t Sizes[] = {
+ 1, // LF_CHAR
+ 2, // LF_SHORT
+ 2, // LF_USHORT
+ 4, // LF_LONG
+ 4, // LF_ULONG
+ 4, // LF_REAL32
+ 8, // LF_REAL64
+ 10, // LF_REAL80
+ 16, // LF_REAL128
+ 8, // LF_QUADWORD
+ 8, // LF_UQUADWORD
+ };
+
+ return 2 + Sizes[N - LF_NUMERIC];
+}
+
+static inline uint32_t getCStringLength(ArrayRef<uint8_t> Data) {
+ const char *S = reinterpret_cast<const char *>(Data.data());
+ return strlen(S) + 1;
+}
+
+static void handleMethodOverloadList(ArrayRef<uint8_t> Content,
+ SmallVectorImpl<TiReference> &Refs) {
+ uint32_t Offset = 0;
+
+ while (!Content.empty()) {
+ // Array of:
+ // 0: Attrs
+ // 2: Padding
+ // 4: TypeIndex
+ // if (isIntroVirtual())
+ // 8: VFTableOffset
+
+ // At least 8 bytes are guaranteed. 4 extra bytes come iff function is an
+ // intro virtual.
+ uint32_t Len = 8;
+
+ uint16_t Attrs = support::endian::read16le(Content.data());
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+
+ if (LLVM_UNLIKELY(isIntroVirtual(Attrs)))
+ Len += 4;
+ Offset += Len;
+ Content = Content.drop_front(Len);
+ }
+}
+
+static uint32_t handleBaseClass(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: TypeIndex
+ // 8: Encoded Integer
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+ return 8 + getEncodedIntegerLength(Data.drop_front(8));
+}
+
+static uint32_t handleEnumerator(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: Encoded Integer
+ // <next>: Name
+ uint32_t Size = 4 + getEncodedIntegerLength(Data.drop_front(4));
+ return Size + getCStringLength(Data.drop_front(Size));
+}
+
+static uint32_t handleDataMember(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: TypeIndex
+ // 8: Encoded Integer
+ // <next>: Name
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+ uint32_t Size = 8 + getEncodedIntegerLength(Data.drop_front(8));
+ return Size + getCStringLength(Data.drop_front(Size));
+}
+
+static uint32_t handleOverloadedMethod(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: TypeIndex
+ // 8: Name
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+ return 8 + getCStringLength(Data.drop_front(8));
+}
+
+static uint32_t handleOneMethod(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Attributes
+ // 4: Type
+ // if (isIntroVirtual)
+ // 8: VFTableOffset
+ // <next>: Name
+ uint32_t Size = 8;
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+
+ uint16_t Attrs = support::endian::read16le(Data.drop_front(2).data());
+ if (LLVM_UNLIKELY(isIntroVirtual(Attrs)))
+ Size += 4;
+
+ return Size + getCStringLength(Data.drop_front(Size));
+}
+
+static uint32_t handleNestedType(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: TypeIndex
+ // 8: Name
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+ return 8 + getCStringLength(Data.drop_front(8));
+}
+
+static uint32_t handleStaticDataMember(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: TypeIndex
+ // 8: Name
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+ return 8 + getCStringLength(Data.drop_front(8));
+}
+
+static uint32_t handleVirtualBaseClass(ArrayRef<uint8_t> Data, uint32_t Offset,
+ bool IsIndirect,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Attrs
+ // 4: TypeIndex
+ // 8: TypeIndex
+ // 12: Encoded Integer
+ // <next>: Encoded Integer
+ uint32_t Size = 12;
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 2});
+ Size += getEncodedIntegerLength(Data.drop_front(Size));
+ Size += getEncodedIntegerLength(Data.drop_front(Size));
+ return Size;
+}
+
+static uint32_t handleVFPtr(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: TypeIndex
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+ return 8;
+}
+
+static uint32_t handleListContinuation(ArrayRef<uint8_t> Data, uint32_t Offset,
+ SmallVectorImpl<TiReference> &Refs) {
+ // 0: Kind
+ // 2: Padding
+ // 4: TypeIndex
+ Refs.push_back({TiRefKind::TypeRef, Offset + 4, 1});
+ return 8;
+}
+
+static void handleFieldList(ArrayRef<uint8_t> Content,
+ SmallVectorImpl<TiReference> &Refs) {
+ uint32_t Offset = 0;
+ uint32_t ThisLen = 0;
+ while (!Content.empty()) {
+ TypeLeafKind Kind =
+ static_cast<TypeLeafKind>(support::endian::read16le(Content.data()));
+ switch (Kind) {
+ case LF_BCLASS:
+ ThisLen = handleBaseClass(Content, Offset, Refs);
+ break;
+ case LF_ENUMERATE:
+ ThisLen = handleEnumerator(Content, Offset, Refs);
+ break;
+ case LF_MEMBER:
+ ThisLen = handleDataMember(Content, Offset, Refs);
+ break;
+ case LF_METHOD:
+ ThisLen = handleOverloadedMethod(Content, Offset, Refs);
+ break;
+ case LF_ONEMETHOD:
+ ThisLen = handleOneMethod(Content, Offset, Refs);
+ break;
+ case LF_NESTTYPE:
+ ThisLen = handleNestedType(Content, Offset, Refs);
+ break;
+ case LF_STMEMBER:
+ ThisLen = handleStaticDataMember(Content, Offset, Refs);
+ break;
+ case LF_VBCLASS:
+ case LF_IVBCLASS:
+ ThisLen =
+ handleVirtualBaseClass(Content, Offset, Kind == LF_VBCLASS, Refs);
+ break;
+ case LF_VFUNCTAB:
+ ThisLen = handleVFPtr(Content, Offset, Refs);
+ break;
+ case LF_INDEX:
+ ThisLen = handleListContinuation(Content, Offset, Refs);
+ break;
+ default:
+ return;
+ }
+ Content = Content.drop_front(ThisLen);
+ Offset += ThisLen;
+ if (!Content.empty()) {
+ uint8_t Pad = Content.front();
+ if (Pad >= LF_PAD0) {
+ uint32_t Skip = Pad & 0x0F;
+ Content = Content.drop_front(Skip);
+ Offset += Skip;
+ }
+ }
+ }
+}
+
+static void handlePointer(ArrayRef<uint8_t> Content,
+ SmallVectorImpl<TiReference> &Refs) {
+ Refs.push_back({TiRefKind::TypeRef, 0, 1});
+
+ uint32_t Attrs = support::endian::read32le(Content.drop_front(4).data());
+ if (isMemberPointer(Attrs))
+ Refs.push_back({TiRefKind::TypeRef, 8, 1});
+}
+
+static void discoverTypeIndices(ArrayRef<uint8_t> Content, TypeLeafKind Kind,
+ SmallVectorImpl<TiReference> &Refs) {
+ uint32_t Count;
+ // FIXME: In the future it would be nice if we could avoid hardcoding these
+ // values. One idea is to define some structures representing these types
+ // that would allow the use of offsetof().
+ switch (Kind) {
+ case TypeLeafKind::LF_FUNC_ID:
+ Refs.push_back({TiRefKind::IndexRef, 0, 1});
+ Refs.push_back({TiRefKind::TypeRef, 4, 1});
+ break;
+ case TypeLeafKind::LF_MFUNC_ID:
+ Refs.push_back({TiRefKind::TypeRef, 0, 2});
+ break;
+ case TypeLeafKind::LF_STRING_ID:
+ Refs.push_back({TiRefKind::IndexRef, 0, 1});
+ break;
+ case TypeLeafKind::LF_SUBSTR_LIST:
+ Count = support::endian::read32le(Content.data());
+ if (Count > 0)
+ Refs.push_back({TiRefKind::IndexRef, 4, Count});
+ break;
+ case TypeLeafKind::LF_BUILDINFO:
+ Count = support::endian::read16le(Content.data());
+ if (Count > 0)
+ Refs.push_back({TiRefKind::IndexRef, 2, Count});
+ break;
+ case TypeLeafKind::LF_UDT_SRC_LINE:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1});
+ Refs.push_back({TiRefKind::IndexRef, 4, 1});
+ break;
+ case TypeLeafKind::LF_UDT_MOD_SRC_LINE:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1});
+ break;
+ case TypeLeafKind::LF_MODIFIER:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1});
+ break;
+ case TypeLeafKind::LF_PROCEDURE:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1});
+ Refs.push_back({TiRefKind::TypeRef, 8, 1});
+ break;
+ case TypeLeafKind::LF_MFUNCTION:
+ Refs.push_back({TiRefKind::TypeRef, 0, 3});
+ Refs.push_back({TiRefKind::TypeRef, 16, 1});
+ break;
+ case TypeLeafKind::LF_ARGLIST:
+ Count = support::endian::read32le(Content.data());
+ if (Count > 0)
+ Refs.push_back({TiRefKind::TypeRef, 4, Count});
+ break;
+ case TypeLeafKind::LF_ARRAY:
+ Refs.push_back({TiRefKind::TypeRef, 0, 2});
+ break;
+ case TypeLeafKind::LF_CLASS:
+ case TypeLeafKind::LF_STRUCTURE:
+ case TypeLeafKind::LF_INTERFACE:
+ Refs.push_back({TiRefKind::TypeRef, 4, 3});
+ break;
+ case TypeLeafKind::LF_UNION:
+ Refs.push_back({TiRefKind::TypeRef, 4, 1});
+ break;
+ case TypeLeafKind::LF_ENUM:
+ Refs.push_back({TiRefKind::TypeRef, 4, 2});
+ break;
+ case TypeLeafKind::LF_BITFIELD:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1});
+ break;
+ case TypeLeafKind::LF_VFTABLE:
+ Refs.push_back({TiRefKind::TypeRef, 0, 2});
+ break;
+ case TypeLeafKind::LF_VTSHAPE:
+ break;
+ case TypeLeafKind::LF_METHODLIST:
+ handleMethodOverloadList(Content, Refs);
+ break;
+ case TypeLeafKind::LF_FIELDLIST:
+ handleFieldList(Content, Refs);
+ break;
+ case TypeLeafKind::LF_POINTER:
+ handlePointer(Content, Refs);
+ break;
+ default:
+ break;
+ }
+}
+
+static bool discoverTypeIndices(ArrayRef<uint8_t> Content, SymbolKind Kind,
+ SmallVectorImpl<TiReference> &Refs) {
+ uint32_t Count;
+ // FIXME: In the future it would be nice if we could avoid hardcoding these
+ // values. One idea is to define some structures representing these types
+ // that would allow the use of offsetof().
+ switch (Kind) {
+ 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;
+ case SymbolKind::S_GDATA32:
+ case SymbolKind::S_LDATA32:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
+ break;
+ case SymbolKind::S_BUILDINFO:
+ Refs.push_back({TiRefKind::IndexRef, 0, 1}); // Compile flags
+ break;
+ case SymbolKind::S_LTHREAD32:
+ case SymbolKind::S_GTHREAD32:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
+ break;
+ case SymbolKind::S_FILESTATIC:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
+ break;
+ case SymbolKind::S_LOCAL:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
+ break;
+ case SymbolKind::S_REGISTER:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
+ break;
+ case SymbolKind::S_CONSTANT:
+ Refs.push_back({TiRefKind::TypeRef, 0, 1}); // Type
+ break;
+ case SymbolKind::S_BPREL32:
+ case SymbolKind::S_REGREL32:
+ Refs.push_back({TiRefKind::TypeRef, 4, 1}); // Type
+ break;
+ case SymbolKind::S_CALLSITEINFO:
+ Refs.push_back({TiRefKind::TypeRef, 8, 1}); // Call signature
+ break;
+ case SymbolKind::S_CALLERS:
+ case SymbolKind::S_CALLEES:
+ case SymbolKind::S_INLINEES:
+ // The record is a count followed by an array of type indices.
+ Count = *reinterpret_cast<const ulittle32_t *>(Content.data());
+ Refs.push_back({TiRefKind::IndexRef, 4, Count}); // Callees
+ break;
+ case SymbolKind::S_INLINESITE:
+ Refs.push_back({TiRefKind::IndexRef, 8, 1}); // ID of inlinee
+ break;
+ case SymbolKind::S_HEAPALLOCSITE:
+ Refs.push_back({TiRefKind::TypeRef, 8, 1}); // UDT allocated
+ break;
+
+ // Defranges don't have types, just registers and code offsets.
+ case SymbolKind::S_DEFRANGE_REGISTER:
+ case SymbolKind::S_DEFRANGE_REGISTER_REL:
+ case SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL:
+ case SymbolKind::S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE:
+ case SymbolKind::S_DEFRANGE_SUBFIELD_REGISTER:
+ case SymbolKind::S_DEFRANGE_SUBFIELD:
+ break;
+
+ // No type references.
+ case SymbolKind::S_LABEL32:
+ case SymbolKind::S_OBJNAME:
+ case SymbolKind::S_COMPILE:
+ case SymbolKind::S_COMPILE2:
+ case SymbolKind::S_COMPILE3:
+ case SymbolKind::S_ENVBLOCK:
+ case SymbolKind::S_BLOCK32:
+ case SymbolKind::S_FRAMEPROC:
+ case SymbolKind::S_THUNK32:
+ case SymbolKind::S_FRAMECOOKIE:
+ case SymbolKind::S_UNAMESPACE:
+ break;
+ // Scope ending symbols.
+ case SymbolKind::S_END:
+ case SymbolKind::S_INLINESITE_END:
+ case SymbolKind::S_PROC_ID_END:
+ break;
+ default:
+ return false; // Unknown symbol.
+ }
+ return true;
+}
+
+void llvm::codeview::discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TiReference> &Refs) {
+ ::discoverTypeIndices(Type.content(), Type.kind(), Refs);
+}
+
+static void resolveTypeIndexReferences(ArrayRef<uint8_t> RecordData,
+ ArrayRef<TiReference> Refs,
+ SmallVectorImpl<TypeIndex> &Indices) {
+ Indices.clear();
+
+ if (Refs.empty())
+ return;
+
+ RecordData = RecordData.drop_front(sizeof(RecordPrefix));
+
+ BinaryStreamReader Reader(RecordData, support::little);
+ for (const auto &Ref : Refs) {
+ Reader.setOffset(Ref.Offset);
+ FixedStreamArray<TypeIndex> Run;
+ cantFail(Reader.readArray(Run, Ref.Count));
+ Indices.append(Run.begin(), Run.end());
+ }
+}
+
+void llvm::codeview::discoverTypeIndices(const CVType &Type,
+ SmallVectorImpl<TypeIndex> &Indices) {
+ return discoverTypeIndices(Type.RecordData, Indices);
+}
+
+void llvm::codeview::discoverTypeIndices(ArrayRef<uint8_t> RecordData,
+ SmallVectorImpl<TypeIndex> &Indices) {
+ SmallVector<TiReference, 4> Refs;
+ discoverTypeIndices(RecordData, Refs);
+ resolveTypeIndexReferences(RecordData, Refs, Indices);
+}
+
+void llvm::codeview::discoverTypeIndices(ArrayRef<uint8_t> RecordData,
+ SmallVectorImpl<TiReference> &Refs) {
+ const RecordPrefix *P =
+ reinterpret_cast<const RecordPrefix *>(RecordData.data());
+ TypeLeafKind K = static_cast<TypeLeafKind>(uint16_t(P->RecordKind));
+ ::discoverTypeIndices(RecordData.drop_front(sizeof(RecordPrefix)), K, Refs);
+}
+
+bool llvm::codeview::discoverTypeIndicesInSymbol(
+ const CVSymbol &Sym, SmallVectorImpl<TiReference> &Refs) {
+ SymbolKind K = Sym.kind();
+ return ::discoverTypeIndices(Sym.content(), K, Refs);
+}
+
+bool llvm::codeview::discoverTypeIndicesInSymbol(
+ ArrayRef<uint8_t> RecordData, SmallVectorImpl<TiReference> &Refs) {
+ const RecordPrefix *P =
+ reinterpret_cast<const RecordPrefix *>(RecordData.data());
+ SymbolKind K = static_cast<SymbolKind>(uint16_t(P->RecordKind));
+ return ::discoverTypeIndices(RecordData.drop_front(sizeof(RecordPrefix)), K,
+ Refs);
+}
+
+bool llvm::codeview::discoverTypeIndicesInSymbol(
+ ArrayRef<uint8_t> RecordData, SmallVectorImpl<TypeIndex> &Indices) {
+ SmallVector<TiReference, 2> Refs;
+ if (!discoverTypeIndicesInSymbol(RecordData, Refs))
+ return false;
+ resolveTypeIndexReferences(RecordData, Refs, Indices);
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp
index 8e632f3be4..2b6fc8a0fe 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordHelpers.cpp
@@ -1,52 +1,52 @@
-//===- TypeRecordHelpers.cpp ------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-template <typename RecordT> static ClassOptions getUdtOptions(CVType CVT) {
- RecordT Record;
- if (auto EC = TypeDeserializer::deserializeAs<RecordT>(CVT, Record)) {
- consumeError(std::move(EC));
- return ClassOptions::None;
- }
- return Record.getOptions();
-}
-
-bool llvm::codeview::isUdtForwardRef(CVType CVT) {
- ClassOptions UdtOptions = ClassOptions::None;
- switch (CVT.kind()) {
- case LF_STRUCTURE:
- case LF_CLASS:
- case LF_INTERFACE:
- UdtOptions = getUdtOptions<ClassRecord>(std::move(CVT));
- break;
- case LF_ENUM:
- UdtOptions = getUdtOptions<EnumRecord>(std::move(CVT));
- break;
- case LF_UNION:
- UdtOptions = getUdtOptions<UnionRecord>(std::move(CVT));
- break;
- default:
- return false;
- }
- return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None;
-}
-
-TypeIndex llvm::codeview::getModifiedType(const CVType &CVT) {
- assert(CVT.kind() == LF_MODIFIER);
- SmallVector<TypeIndex, 1> Refs;
- discoverTypeIndices(CVT, Refs);
- return Refs.front();
-}
+//===- TypeRecordHelpers.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+template <typename RecordT> static ClassOptions getUdtOptions(CVType CVT) {
+ RecordT Record;
+ if (auto EC = TypeDeserializer::deserializeAs<RecordT>(CVT, Record)) {
+ consumeError(std::move(EC));
+ return ClassOptions::None;
+ }
+ return Record.getOptions();
+}
+
+bool llvm::codeview::isUdtForwardRef(CVType CVT) {
+ ClassOptions UdtOptions = ClassOptions::None;
+ switch (CVT.kind()) {
+ case LF_STRUCTURE:
+ case LF_CLASS:
+ case LF_INTERFACE:
+ UdtOptions = getUdtOptions<ClassRecord>(std::move(CVT));
+ break;
+ case LF_ENUM:
+ UdtOptions = getUdtOptions<EnumRecord>(std::move(CVT));
+ break;
+ case LF_UNION:
+ UdtOptions = getUdtOptions<UnionRecord>(std::move(CVT));
+ break;
+ default:
+ return false;
+ }
+ return (UdtOptions & ClassOptions::ForwardReference) != ClassOptions::None;
+}
+
+TypeIndex llvm::codeview::getModifiedType(const CVType &CVT) {
+ assert(CVT.kind() == LF_MODIFIER);
+ SmallVector<TypeIndex, 1> Refs;
+ discoverTypeIndices(CVT, Refs);
+ return Refs.front();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
index 7ac3761561..32a3f9719c 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeRecordMapping.cpp
@@ -1,710 +1,710 @@
-//===- TypeRecordMapping.cpp ------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/EnumTables.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-namespace {
-
-#define error(X) \
- if (auto EC = X) \
- return EC;
-
-static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
-#define CV_TYPE(enum, val) {#enum, enum},
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
-};
-
-static StringRef getLeafTypeName(TypeLeafKind LT) {
- switch (LT) {
-#define TYPE_RECORD(ename, value, name) \
- case ename: \
- return #name;
-#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
- default:
- break;
- }
- return "UnknownLeaf";
-}
-
-template <typename T>
-static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
- return lhs.Name < rhs.Name;
-}
-
-template <typename T, typename TFlag>
-static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
- ArrayRef<EnumEntry<TFlag>> Flags) {
- if (!IO.isStreaming())
- return std::string("");
- typedef EnumEntry<TFlag> FlagEntry;
- typedef SmallVector<FlagEntry, 10> FlagVector;
- FlagVector SetFlags;
- for (const auto &Flag : Flags) {
- if (Flag.Value == 0)
- continue;
- if ((Value & Flag.Value) == Flag.Value) {
- SetFlags.push_back(Flag);
- }
- }
-
- llvm::sort(SetFlags, &compEnumNames<TFlag>);
-
- std::string FlagLabel;
- bool FirstOcc = true;
- for (const auto &Flag : SetFlags) {
- if (FirstOcc)
- FirstOcc = false;
- else
- FlagLabel += (" | ");
-
- FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
- }
-
- if (!FlagLabel.empty()) {
- std::string LabelWithBraces(" ( ");
- LabelWithBraces += FlagLabel + " )";
- return LabelWithBraces;
- } else
- return FlagLabel;
-}
-
-template <typename T, typename TEnum>
-static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
- ArrayRef<EnumEntry<TEnum>> EnumValues) {
- if (!IO.isStreaming())
- return "";
- StringRef Name;
- for (const auto &EnumItem : EnumValues) {
- if (EnumItem.Value == Value) {
- Name = EnumItem.Name;
- break;
- }
- }
-
- return Name;
-}
-
-static std::string getMemberAttributes(CodeViewRecordIO &IO,
- MemberAccess Access, MethodKind Kind,
- MethodOptions Options) {
- if (!IO.isStreaming())
- return "";
- std::string AccessSpecifier = std::string(
- getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames())));
- std::string MemberAttrs(AccessSpecifier);
- if (Kind != MethodKind::Vanilla) {
- std::string MethodKind = std::string(
- getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames())));
- MemberAttrs += ", " + MethodKind;
- }
- if (Options != MethodOptions::None) {
- std::string MethodOptions = getFlagNames(
- IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
- MemberAttrs += ", " + MethodOptions;
- }
- return MemberAttrs;
-}
-
-struct MapOneMethodRecord {
- explicit MapOneMethodRecord(bool IsFromOverloadList)
- : IsFromOverloadList(IsFromOverloadList) {}
-
- Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
- std::string Attrs = getMemberAttributes(
- IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
- error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
- if (IsFromOverloadList) {
- uint16_t Padding = 0;
- error(IO.mapInteger(Padding));
- }
- error(IO.mapInteger(Method.Type, "Type"));
- if (Method.isIntroducingVirtual()) {
- error(IO.mapInteger(Method.VFTableOffset, "VFTableOffset"));
- } else if (IO.isReading())
- Method.VFTableOffset = -1;
-
- if (!IsFromOverloadList)
- error(IO.mapStringZ(Method.Name, "Name"));
-
- return Error::success();
- }
-
-private:
- bool IsFromOverloadList;
-};
-} // namespace
-
-static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name,
- StringRef &UniqueName, bool HasUniqueName) {
- if (IO.isWriting()) {
- // Try to be smart about what we write here. We can't write anything too
- // large, so if we're going to go over the limit, truncate both the name
- // and unique name by the same amount.
- size_t BytesLeft = IO.maxFieldLength();
- if (HasUniqueName) {
- size_t BytesNeeded = Name.size() + UniqueName.size() + 2;
- StringRef N = Name;
- StringRef U = UniqueName;
- if (BytesNeeded > BytesLeft) {
- size_t BytesToDrop = (BytesNeeded - BytesLeft);
- size_t DropN = std::min(N.size(), BytesToDrop / 2);
- size_t DropU = std::min(U.size(), BytesToDrop - DropN);
-
- N = N.drop_back(DropN);
- U = U.drop_back(DropU);
- }
-
- error(IO.mapStringZ(N));
- error(IO.mapStringZ(U));
- } else {
- // Cap the length of the string at however many bytes we have available,
- // plus one for the required null terminator.
- auto N = StringRef(Name).take_front(BytesLeft - 1);
- error(IO.mapStringZ(N));
- }
- } else {
- // 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, "LinkageName"));
- }
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitTypeBegin(CVType &CVR) {
- assert(!TypeKind.hasValue() && "Already in a type mapping!");
- assert(!MemberKind.hasValue() && "Already in a member mapping!");
-
- // FieldList and MethodList records can be any length because they can be
- // split with continuation records. All other record types cannot be
- // longer than the maximum record length.
- Optional<uint32_t> MaxLen;
- if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
- CVR.kind() != TypeLeafKind::LF_METHODLIST)
- MaxLen = MaxRecordLength - sizeof(RecordPrefix);
- error(IO.beginRecord(MaxLen));
- TypeKind = CVR.kind();
-
- if (IO.isStreaming()) {
- auto RecordKind = CVR.kind();
- uint16_t RecordLen = CVR.length() - 2;
- std::string RecordKindName = std::string(
- getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames)));
- error(IO.mapInteger(RecordLen, "Record length"));
- error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
- }
- return Error::success();
-}
-
-Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) {
- if (IO.isStreaming())
- IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
- utohexstr(Index.getIndex()) + ")");
- return visitTypeBegin(CVR);
-}
-
-Error TypeRecordMapping::visitTypeEnd(CVType &Record) {
- assert(TypeKind.hasValue() && "Not in a type mapping!");
- assert(!MemberKind.hasValue() && "Still in a member mapping!");
-
- error(IO.endRecord());
-
- TypeKind.reset();
- return Error::success();
-}
-
-Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
- assert(TypeKind.hasValue() && "Not in a type mapping!");
- assert(!MemberKind.hasValue() && "Already in a member mapping!");
-
- // The largest possible subrecord is one in which there is a record prefix,
- // followed by the subrecord, followed by a continuation, and that entire
+//===- TypeRecordMapping.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeRecordMapping.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/DebugInfo/CodeView/EnumTables.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+namespace {
+
+#define error(X) \
+ if (auto EC = X) \
+ return EC;
+
+static const EnumEntry<TypeLeafKind> LeafTypeNames[] = {
+#define CV_TYPE(enum, val) {#enum, enum},
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+};
+
+static StringRef getLeafTypeName(TypeLeafKind LT) {
+ switch (LT) {
+#define TYPE_RECORD(ename, value, name) \
+ case ename: \
+ return #name;
+#include "llvm/DebugInfo/CodeView/CodeViewTypes.def"
+ default:
+ break;
+ }
+ return "UnknownLeaf";
+}
+
+template <typename T>
+static bool compEnumNames(const EnumEntry<T> &lhs, const EnumEntry<T> &rhs) {
+ return lhs.Name < rhs.Name;
+}
+
+template <typename T, typename TFlag>
+static std::string getFlagNames(CodeViewRecordIO &IO, T Value,
+ ArrayRef<EnumEntry<TFlag>> Flags) {
+ if (!IO.isStreaming())
+ return std::string("");
+ typedef EnumEntry<TFlag> FlagEntry;
+ typedef SmallVector<FlagEntry, 10> FlagVector;
+ FlagVector SetFlags;
+ for (const auto &Flag : Flags) {
+ if (Flag.Value == 0)
+ continue;
+ if ((Value & Flag.Value) == Flag.Value) {
+ SetFlags.push_back(Flag);
+ }
+ }
+
+ llvm::sort(SetFlags, &compEnumNames<TFlag>);
+
+ std::string FlagLabel;
+ bool FirstOcc = true;
+ for (const auto &Flag : SetFlags) {
+ if (FirstOcc)
+ FirstOcc = false;
+ else
+ FlagLabel += (" | ");
+
+ FlagLabel += (Flag.Name.str() + " (0x" + utohexstr(Flag.Value) + ")");
+ }
+
+ if (!FlagLabel.empty()) {
+ std::string LabelWithBraces(" ( ");
+ LabelWithBraces += FlagLabel + " )";
+ return LabelWithBraces;
+ } else
+ return FlagLabel;
+}
+
+template <typename T, typename TEnum>
+static StringRef getEnumName(CodeViewRecordIO &IO, T Value,
+ ArrayRef<EnumEntry<TEnum>> EnumValues) {
+ if (!IO.isStreaming())
+ return "";
+ StringRef Name;
+ for (const auto &EnumItem : EnumValues) {
+ if (EnumItem.Value == Value) {
+ Name = EnumItem.Name;
+ break;
+ }
+ }
+
+ return Name;
+}
+
+static std::string getMemberAttributes(CodeViewRecordIO &IO,
+ MemberAccess Access, MethodKind Kind,
+ MethodOptions Options) {
+ if (!IO.isStreaming())
+ return "";
+ std::string AccessSpecifier = std::string(
+ getEnumName(IO, uint8_t(Access), makeArrayRef(getMemberAccessNames())));
+ std::string MemberAttrs(AccessSpecifier);
+ if (Kind != MethodKind::Vanilla) {
+ std::string MethodKind = std::string(
+ getEnumName(IO, unsigned(Kind), makeArrayRef(getMemberKindNames())));
+ MemberAttrs += ", " + MethodKind;
+ }
+ if (Options != MethodOptions::None) {
+ std::string MethodOptions = getFlagNames(
+ IO, unsigned(Options), makeArrayRef(getMethodOptionNames()));
+ MemberAttrs += ", " + MethodOptions;
+ }
+ return MemberAttrs;
+}
+
+struct MapOneMethodRecord {
+ explicit MapOneMethodRecord(bool IsFromOverloadList)
+ : IsFromOverloadList(IsFromOverloadList) {}
+
+ Error operator()(CodeViewRecordIO &IO, OneMethodRecord &Method) const {
+ std::string Attrs = getMemberAttributes(
+ IO, Method.getAccess(), Method.getMethodKind(), Method.getOptions());
+ error(IO.mapInteger(Method.Attrs.Attrs, "Attrs: " + Attrs));
+ if (IsFromOverloadList) {
+ uint16_t Padding = 0;
+ error(IO.mapInteger(Padding));
+ }
+ error(IO.mapInteger(Method.Type, "Type"));
+ if (Method.isIntroducingVirtual()) {
+ error(IO.mapInteger(Method.VFTableOffset, "VFTableOffset"));
+ } else if (IO.isReading())
+ Method.VFTableOffset = -1;
+
+ if (!IsFromOverloadList)
+ error(IO.mapStringZ(Method.Name, "Name"));
+
+ return Error::success();
+ }
+
+private:
+ bool IsFromOverloadList;
+};
+} // namespace
+
+static Error mapNameAndUniqueName(CodeViewRecordIO &IO, StringRef &Name,
+ StringRef &UniqueName, bool HasUniqueName) {
+ if (IO.isWriting()) {
+ // Try to be smart about what we write here. We can't write anything too
+ // large, so if we're going to go over the limit, truncate both the name
+ // and unique name by the same amount.
+ size_t BytesLeft = IO.maxFieldLength();
+ if (HasUniqueName) {
+ size_t BytesNeeded = Name.size() + UniqueName.size() + 2;
+ StringRef N = Name;
+ StringRef U = UniqueName;
+ if (BytesNeeded > BytesLeft) {
+ size_t BytesToDrop = (BytesNeeded - BytesLeft);
+ size_t DropN = std::min(N.size(), BytesToDrop / 2);
+ size_t DropU = std::min(U.size(), BytesToDrop - DropN);
+
+ N = N.drop_back(DropN);
+ U = U.drop_back(DropU);
+ }
+
+ error(IO.mapStringZ(N));
+ error(IO.mapStringZ(U));
+ } else {
+ // Cap the length of the string at however many bytes we have available,
+ // plus one for the required null terminator.
+ auto N = StringRef(Name).take_front(BytesLeft - 1);
+ error(IO.mapStringZ(N));
+ }
+ } else {
+ // 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, "LinkageName"));
+ }
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitTypeBegin(CVType &CVR) {
+ assert(!TypeKind.hasValue() && "Already in a type mapping!");
+ assert(!MemberKind.hasValue() && "Already in a member mapping!");
+
+ // FieldList and MethodList records can be any length because they can be
+ // split with continuation records. All other record types cannot be
+ // longer than the maximum record length.
+ Optional<uint32_t> MaxLen;
+ if (CVR.kind() != TypeLeafKind::LF_FIELDLIST &&
+ CVR.kind() != TypeLeafKind::LF_METHODLIST)
+ MaxLen = MaxRecordLength - sizeof(RecordPrefix);
+ error(IO.beginRecord(MaxLen));
+ TypeKind = CVR.kind();
+
+ if (IO.isStreaming()) {
+ auto RecordKind = CVR.kind();
+ uint16_t RecordLen = CVR.length() - 2;
+ std::string RecordKindName = std::string(
+ getEnumName(IO, unsigned(RecordKind), makeArrayRef(LeafTypeNames)));
+ error(IO.mapInteger(RecordLen, "Record length"));
+ error(IO.mapEnum(RecordKind, "Record kind: " + RecordKindName));
+ }
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitTypeBegin(CVType &CVR, TypeIndex Index) {
+ if (IO.isStreaming())
+ IO.emitRawComment(" " + getLeafTypeName(CVR.kind()) + " (0x" +
+ utohexstr(Index.getIndex()) + ")");
+ return visitTypeBegin(CVR);
+}
+
+Error TypeRecordMapping::visitTypeEnd(CVType &Record) {
+ assert(TypeKind.hasValue() && "Not in a type mapping!");
+ assert(!MemberKind.hasValue() && "Still in a member mapping!");
+
+ error(IO.endRecord());
+
+ TypeKind.reset();
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitMemberBegin(CVMemberRecord &Record) {
+ assert(TypeKind.hasValue() && "Not in a type mapping!");
+ assert(!MemberKind.hasValue() && "Already in a member mapping!");
+
+ // The largest possible subrecord is one in which there is a record prefix,
+ // followed by the subrecord, followed by a continuation, and that entire
// sequence spawns `MaxRecordLength` bytes. So the record's length is
- // calculated as follows.
-
- constexpr uint32_t ContinuationLength = 8;
- error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix) -
- ContinuationLength));
-
- MemberKind = Record.Kind;
- if (IO.isStreaming()) {
- std::string MemberKindName = std::string(getLeafTypeName(Record.Kind));
- MemberKindName +=
- " ( " +
- (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
- .str() +
- " )";
- error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
- }
- return Error::success();
-}
-
-Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) {
- assert(TypeKind.hasValue() && "Not in a type mapping!");
- assert(MemberKind.hasValue() && "Not in a member mapping!");
-
- if (IO.isReading()) {
- if (auto EC = IO.skipPadding())
- return EC;
- }
-
- MemberKind.reset();
- error(IO.endRecord());
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) {
- std::string ModifierNames =
- getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
- makeArrayRef(getTypeModifierNames()));
- error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
- error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
- ProcedureRecord &Record) {
- std::string CallingConvName = std::string(getEnumName(
- IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
- std::string FuncOptionNames =
- getFlagNames(IO, static_cast<uint16_t>(Record.Options),
- makeArrayRef(getFunctionOptionEnum()));
- error(IO.mapInteger(Record.ReturnType, "ReturnType"));
- error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
- error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
- error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
- error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
- MemberFunctionRecord &Record) {
- std::string CallingConvName = std::string(getEnumName(
- IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
- std::string FuncOptionNames =
- getFlagNames(IO, static_cast<uint16_t>(Record.Options),
- makeArrayRef(getFunctionOptionEnum()));
- error(IO.mapInteger(Record.ReturnType, "ReturnType"));
- error(IO.mapInteger(Record.ClassType, "ClassType"));
- error(IO.mapInteger(Record.ThisType, "ThisType"));
- error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
- error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
- error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
- error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
- error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArgListRecord &Record) {
- error(IO.mapVectorN<uint32_t>(
- Record.ArgIndices,
- [](CodeViewRecordIO &IO, TypeIndex &N) {
- return IO.mapInteger(N, "Argument");
- },
- "NumArgs"));
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
- StringListRecord &Record) {
- error(IO.mapVectorN<uint32_t>(
- Record.StringIndices,
- [](CodeViewRecordIO &IO, TypeIndex &N) {
- return IO.mapInteger(N, "Strings");
- },
- "NumStrings"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) {
-
- SmallString<128> Attr("Attrs: ");
-
- if (IO.isStreaming()) {
- std::string PtrType =
- std::string(getEnumName(IO, unsigned(Record.getPointerKind()),
- makeArrayRef(getPtrKindNames())));
- Attr += "[ Type: " + PtrType;
-
- std::string PtrMode = std::string(getEnumName(
- IO, unsigned(Record.getMode()), makeArrayRef(getPtrModeNames())));
- Attr += ", Mode: " + PtrMode;
-
- auto PtrSizeOf = Record.getSize();
- Attr += ", SizeOf: " + itostr(PtrSizeOf);
-
- if (Record.isFlat())
- Attr += ", isFlat";
- if (Record.isConst())
- Attr += ", isConst";
- if (Record.isVolatile())
- Attr += ", isVolatile";
- if (Record.isUnaligned())
- Attr += ", isUnaligned";
- if (Record.isRestrict())
- Attr += ", isRestricted";
- if (Record.isLValueReferenceThisPtr())
- Attr += ", isThisPtr&";
- if (Record.isRValueReferenceThisPtr())
- Attr += ", isThisPtr&&";
- Attr += " ]";
- }
-
- error(IO.mapInteger(Record.ReferentType, "PointeeType"));
- error(IO.mapInteger(Record.Attrs, Attr));
-
- if (Record.isPointerToMember()) {
- if (IO.isReading())
- Record.MemberInfo.emplace();
-
- MemberPointerInfo &M = *Record.MemberInfo;
- error(IO.mapInteger(M.ContainingType, "ClassType"));
- std::string PtrMemberGetRepresentation = std::string(getEnumName(
- IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames())));
- error(IO.mapEnum(M.Representation,
- "Representation: " + PtrMemberGetRepresentation));
- }
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArrayRecord &Record) {
- 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.kind() == TypeLeafKind::LF_STRUCTURE) ||
- (CVR.kind() == TypeLeafKind::LF_CLASS) ||
- (CVR.kind() == TypeLeafKind::LF_INTERFACE));
-
- std::string PropertiesNames =
- getFlagNames(IO, static_cast<uint16_t>(Record.Options),
- makeArrayRef(getClassOptionNames()));
- error(IO.mapInteger(Record.MemberCount, "MemberCount"));
- error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
- 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()));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
- std::string PropertiesNames =
- getFlagNames(IO, static_cast<uint16_t>(Record.Options),
- makeArrayRef(getClassOptionNames()));
- error(IO.mapInteger(Record.MemberCount, "MemberCount"));
- error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
- error(IO.mapInteger(Record.FieldList, "FieldList"));
- error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
- error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
- Record.hasUniqueName()));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) {
- std::string PropertiesNames =
- getFlagNames(IO, static_cast<uint16_t>(Record.Options),
- makeArrayRef(getClassOptionNames()));
- error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
- error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
- error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
- error(IO.mapInteger(Record.FieldList, "FieldListType"));
- error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
- Record.hasUniqueName()));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BitFieldRecord &Record) {
- error(IO.mapInteger(Record.Type, "Type"));
- error(IO.mapInteger(Record.BitSize, "BitSize"));
- error(IO.mapInteger(Record.BitOffset, "BitOffset"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
- VFTableShapeRecord &Record) {
- uint16_t Size;
- if (!IO.isReading()) {
- ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
- Size = Slots.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;
- if ((SlotIndex + 1) < Slots.size()) {
- Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
- }
- error(IO.mapInteger(Byte));
- }
- } else {
- error(IO.mapInteger(Size));
- for (uint16_t I = 0; I < Size; I += 2) {
- uint8_t Byte;
- error(IO.mapInteger(Byte));
- Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte & 0xF));
- if ((I + 1) < Size)
- Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte >> 4));
- }
- }
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, VFTableRecord &Record) {
- error(IO.mapInteger(Record.CompleteClass, "CompleteClass"));
- error(IO.mapInteger(Record.OverriddenVFTable, "OverriddenVFTable"));
- error(IO.mapInteger(Record.VFPtrOffset, "VFPtrOffset"));
- uint32_t NamesLen = 0;
- 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, "MethodName");
- },
- "VFTableName"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR, StringIdRecord &Record) {
- 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, "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, "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, "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, "ClassType"));
- error(IO.mapInteger(Record.FunctionType, "FunctionType"));
- error(IO.mapStringZ(Record.Name, "Name"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
- BuildInfoRecord &Record) {
- error(IO.mapVectorN<uint16_t>(
- Record.ArgIndices,
- [](CodeViewRecordIO &IO, TypeIndex &N) {
- return IO.mapInteger(N, "Argument");
- },
- "NumArgs"));
-
- return Error::success();
-}
-
-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), "Method"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
- FieldListRecord &Record) {
- if (IO.isStreaming()) {
- if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
- return EC;
- } else
- error(IO.mapByteVectorTail(Record.Data));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
- TypeServer2Record &Record) {
- 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) {
- std::string ModeName = std::string(
- getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum())));
- error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- BaseClassRecord &Record) {
- std::string Attrs = getMemberAttributes(
- IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
- error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
- error(IO.mapInteger(Record.Type, "BaseType"));
- error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- EnumeratorRecord &Record) {
- std::string Attrs = getMemberAttributes(
- IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
- error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
-
- // FIXME: Handle full APInt such as __int128.
- error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
- error(IO.mapStringZ(Record.Name, "Name"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- DataMemberRecord &Record) {
- std::string Attrs = getMemberAttributes(
- IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
- error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
- error(IO.mapInteger(Record.Type, "Type"));
- error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
- error(IO.mapStringZ(Record.Name, "Name"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- OverloadedMethodRecord &Record) {
- error(IO.mapInteger(Record.NumOverloads, "MethodCount"));
- error(IO.mapInteger(Record.MethodList, "MethodListIndex"));
- error(IO.mapStringZ(Record.Name, "Name"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- OneMethodRecord &Record) {
- const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
- MapOneMethodRecord Mapper(IsFromOverloadList);
- return Mapper(IO, Record);
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- NestedTypeRecord &Record) {
- uint16_t Padding = 0;
- error(IO.mapInteger(Padding, "Padding"));
- error(IO.mapInteger(Record.Type, "Type"));
- error(IO.mapStringZ(Record.Name, "Name"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- StaticDataMemberRecord &Record) {
-
- std::string Attrs = getMemberAttributes(
- IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
- error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
- error(IO.mapInteger(Record.Type, "Type"));
- error(IO.mapStringZ(Record.Name, "Name"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- VirtualBaseClassRecord &Record) {
-
- std::string Attrs = getMemberAttributes(
- IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
- error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
- error(IO.mapInteger(Record.BaseType, "BaseType"));
- error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
- error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
- error(IO.mapEncodedInteger(Record.VTableIndex, "VBTableIndex"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- VFPtrRecord &Record) {
- uint16_t Padding = 0;
- error(IO.mapInteger(Padding, "Padding"));
- error(IO.mapInteger(Record.Type, "Type"));
-
- return Error::success();
-}
-
-Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
- ListContinuationRecord &Record) {
- uint16_t Padding = 0;
- 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, "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, "Signature"));
- return Error::success();
-}
+ // calculated as follows.
+
+ constexpr uint32_t ContinuationLength = 8;
+ error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix) -
+ ContinuationLength));
+
+ MemberKind = Record.Kind;
+ if (IO.isStreaming()) {
+ std::string MemberKindName = std::string(getLeafTypeName(Record.Kind));
+ MemberKindName +=
+ " ( " +
+ (getEnumName(IO, unsigned(Record.Kind), makeArrayRef(LeafTypeNames)))
+ .str() +
+ " )";
+ error(IO.mapEnum(Record.Kind, "Member kind: " + MemberKindName));
+ }
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitMemberEnd(CVMemberRecord &Record) {
+ assert(TypeKind.hasValue() && "Not in a type mapping!");
+ assert(MemberKind.hasValue() && "Not in a member mapping!");
+
+ if (IO.isReading()) {
+ if (auto EC = IO.skipPadding())
+ return EC;
+ }
+
+ MemberKind.reset();
+ error(IO.endRecord());
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ModifierRecord &Record) {
+ std::string ModifierNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Modifiers),
+ makeArrayRef(getTypeModifierNames()));
+ error(IO.mapInteger(Record.ModifiedType, "ModifiedType"));
+ error(IO.mapEnum(Record.Modifiers, "Modifiers" + ModifierNames));
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ ProcedureRecord &Record) {
+ std::string CallingConvName = std::string(getEnumName(
+ IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
+ std::string FuncOptionNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getFunctionOptionEnum()));
+ error(IO.mapInteger(Record.ReturnType, "ReturnType"));
+ error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
+ error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
+ error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
+ error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ MemberFunctionRecord &Record) {
+ std::string CallingConvName = std::string(getEnumName(
+ IO, uint8_t(Record.CallConv), makeArrayRef(getCallingConventions())));
+ std::string FuncOptionNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getFunctionOptionEnum()));
+ error(IO.mapInteger(Record.ReturnType, "ReturnType"));
+ error(IO.mapInteger(Record.ClassType, "ClassType"));
+ error(IO.mapInteger(Record.ThisType, "ThisType"));
+ error(IO.mapEnum(Record.CallConv, "CallingConvention: " + CallingConvName));
+ error(IO.mapEnum(Record.Options, "FunctionOptions" + FuncOptionNames));
+ error(IO.mapInteger(Record.ParameterCount, "NumParameters"));
+ error(IO.mapInteger(Record.ArgumentList, "ArgListType"));
+ error(IO.mapInteger(Record.ThisPointerAdjustment, "ThisAdjustment"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArgListRecord &Record) {
+ error(IO.mapVectorN<uint32_t>(
+ Record.ArgIndices,
+ [](CodeViewRecordIO &IO, TypeIndex &N) {
+ return IO.mapInteger(N, "Argument");
+ },
+ "NumArgs"));
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ StringListRecord &Record) {
+ error(IO.mapVectorN<uint32_t>(
+ Record.StringIndices,
+ [](CodeViewRecordIO &IO, TypeIndex &N) {
+ return IO.mapInteger(N, "Strings");
+ },
+ "NumStrings"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, PointerRecord &Record) {
+
+ SmallString<128> Attr("Attrs: ");
+
+ if (IO.isStreaming()) {
+ std::string PtrType =
+ std::string(getEnumName(IO, unsigned(Record.getPointerKind()),
+ makeArrayRef(getPtrKindNames())));
+ Attr += "[ Type: " + PtrType;
+
+ std::string PtrMode = std::string(getEnumName(
+ IO, unsigned(Record.getMode()), makeArrayRef(getPtrModeNames())));
+ Attr += ", Mode: " + PtrMode;
+
+ auto PtrSizeOf = Record.getSize();
+ Attr += ", SizeOf: " + itostr(PtrSizeOf);
+
+ if (Record.isFlat())
+ Attr += ", isFlat";
+ if (Record.isConst())
+ Attr += ", isConst";
+ if (Record.isVolatile())
+ Attr += ", isVolatile";
+ if (Record.isUnaligned())
+ Attr += ", isUnaligned";
+ if (Record.isRestrict())
+ Attr += ", isRestricted";
+ if (Record.isLValueReferenceThisPtr())
+ Attr += ", isThisPtr&";
+ if (Record.isRValueReferenceThisPtr())
+ Attr += ", isThisPtr&&";
+ Attr += " ]";
+ }
+
+ error(IO.mapInteger(Record.ReferentType, "PointeeType"));
+ error(IO.mapInteger(Record.Attrs, Attr));
+
+ if (Record.isPointerToMember()) {
+ if (IO.isReading())
+ Record.MemberInfo.emplace();
+
+ MemberPointerInfo &M = *Record.MemberInfo;
+ error(IO.mapInteger(M.ContainingType, "ClassType"));
+ std::string PtrMemberGetRepresentation = std::string(getEnumName(
+ IO, uint16_t(M.Representation), makeArrayRef(getPtrMemberRepNames())));
+ error(IO.mapEnum(M.Representation,
+ "Representation: " + PtrMemberGetRepresentation));
+ }
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, ArrayRecord &Record) {
+ 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.kind() == TypeLeafKind::LF_STRUCTURE) ||
+ (CVR.kind() == TypeLeafKind::LF_CLASS) ||
+ (CVR.kind() == TypeLeafKind::LF_INTERFACE));
+
+ std::string PropertiesNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getClassOptionNames()));
+ error(IO.mapInteger(Record.MemberCount, "MemberCount"));
+ error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
+ 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()));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, UnionRecord &Record) {
+ std::string PropertiesNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getClassOptionNames()));
+ error(IO.mapInteger(Record.MemberCount, "MemberCount"));
+ error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
+ error(IO.mapInteger(Record.FieldList, "FieldList"));
+ error(IO.mapEncodedInteger(Record.Size, "SizeOf"));
+ error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
+ Record.hasUniqueName()));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, EnumRecord &Record) {
+ std::string PropertiesNames =
+ getFlagNames(IO, static_cast<uint16_t>(Record.Options),
+ makeArrayRef(getClassOptionNames()));
+ error(IO.mapInteger(Record.MemberCount, "NumEnumerators"));
+ error(IO.mapEnum(Record.Options, "Properties" + PropertiesNames));
+ error(IO.mapInteger(Record.UnderlyingType, "UnderlyingType"));
+ error(IO.mapInteger(Record.FieldList, "FieldListType"));
+ error(mapNameAndUniqueName(IO, Record.Name, Record.UniqueName,
+ Record.hasUniqueName()));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, BitFieldRecord &Record) {
+ error(IO.mapInteger(Record.Type, "Type"));
+ error(IO.mapInteger(Record.BitSize, "BitSize"));
+ error(IO.mapInteger(Record.BitOffset, "BitOffset"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ VFTableShapeRecord &Record) {
+ uint16_t Size;
+ if (!IO.isReading()) {
+ ArrayRef<VFTableSlotKind> Slots = Record.getSlots();
+ Size = Slots.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;
+ if ((SlotIndex + 1) < Slots.size()) {
+ Byte |= static_cast<uint8_t>(Slots[SlotIndex + 1]);
+ }
+ error(IO.mapInteger(Byte));
+ }
+ } else {
+ error(IO.mapInteger(Size));
+ for (uint16_t I = 0; I < Size; I += 2) {
+ uint8_t Byte;
+ error(IO.mapInteger(Byte));
+ Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte & 0xF));
+ if ((I + 1) < Size)
+ Record.Slots.push_back(static_cast<VFTableSlotKind>(Byte >> 4));
+ }
+ }
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, VFTableRecord &Record) {
+ error(IO.mapInteger(Record.CompleteClass, "CompleteClass"));
+ error(IO.mapInteger(Record.OverriddenVFTable, "OverriddenVFTable"));
+ error(IO.mapInteger(Record.VFPtrOffset, "VFPtrOffset"));
+ uint32_t NamesLen = 0;
+ 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, "MethodName");
+ },
+ "VFTableName"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR, StringIdRecord &Record) {
+ 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, "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, "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, "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, "ClassType"));
+ error(IO.mapInteger(Record.FunctionType, "FunctionType"));
+ error(IO.mapStringZ(Record.Name, "Name"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ BuildInfoRecord &Record) {
+ error(IO.mapVectorN<uint16_t>(
+ Record.ArgIndices,
+ [](CodeViewRecordIO &IO, TypeIndex &N) {
+ return IO.mapInteger(N, "Argument");
+ },
+ "NumArgs"));
+
+ return Error::success();
+}
+
+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), "Method"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ FieldListRecord &Record) {
+ if (IO.isStreaming()) {
+ if (auto EC = codeview::visitMemberRecordStream(Record.Data, *this))
+ return EC;
+ } else
+ error(IO.mapByteVectorTail(Record.Data));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownRecord(CVType &CVR,
+ TypeServer2Record &Record) {
+ 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) {
+ std::string ModeName = std::string(
+ getEnumName(IO, uint16_t(Record.Mode), makeArrayRef(getLabelTypeEnum())));
+ error(IO.mapEnum(Record.Mode, "Mode: " + ModeName));
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ BaseClassRecord &Record) {
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
+ error(IO.mapInteger(Record.Type, "BaseType"));
+ error(IO.mapEncodedInteger(Record.Offset, "BaseOffset"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ EnumeratorRecord &Record) {
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
+
+ // FIXME: Handle full APInt such as __int128.
+ error(IO.mapEncodedInteger(Record.Value, "EnumValue"));
+ error(IO.mapStringZ(Record.Name, "Name"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ DataMemberRecord &Record) {
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
+ error(IO.mapInteger(Record.Type, "Type"));
+ error(IO.mapEncodedInteger(Record.FieldOffset, "FieldOffset"));
+ error(IO.mapStringZ(Record.Name, "Name"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ OverloadedMethodRecord &Record) {
+ error(IO.mapInteger(Record.NumOverloads, "MethodCount"));
+ error(IO.mapInteger(Record.MethodList, "MethodListIndex"));
+ error(IO.mapStringZ(Record.Name, "Name"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ OneMethodRecord &Record) {
+ const bool IsFromOverloadList = (TypeKind == LF_METHODLIST);
+ MapOneMethodRecord Mapper(IsFromOverloadList);
+ return Mapper(IO, Record);
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ NestedTypeRecord &Record) {
+ uint16_t Padding = 0;
+ error(IO.mapInteger(Padding, "Padding"));
+ error(IO.mapInteger(Record.Type, "Type"));
+ error(IO.mapStringZ(Record.Name, "Name"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ StaticDataMemberRecord &Record) {
+
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
+ error(IO.mapInteger(Record.Type, "Type"));
+ error(IO.mapStringZ(Record.Name, "Name"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ VirtualBaseClassRecord &Record) {
+
+ std::string Attrs = getMemberAttributes(
+ IO, Record.getAccess(), MethodKind::Vanilla, MethodOptions::None);
+ error(IO.mapInteger(Record.Attrs.Attrs, "Attrs: " + Attrs));
+ error(IO.mapInteger(Record.BaseType, "BaseType"));
+ error(IO.mapInteger(Record.VBPtrType, "VBPtrType"));
+ error(IO.mapEncodedInteger(Record.VBPtrOffset, "VBPtrOffset"));
+ error(IO.mapEncodedInteger(Record.VTableIndex, "VBTableIndex"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ VFPtrRecord &Record) {
+ uint16_t Padding = 0;
+ error(IO.mapInteger(Padding, "Padding"));
+ error(IO.mapInteger(Record.Type, "Type"));
+
+ return Error::success();
+}
+
+Error TypeRecordMapping::visitKnownMember(CVMemberRecord &CVR,
+ ListContinuationRecord &Record) {
+ uint16_t Padding = 0;
+ 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, "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, "Signature"));
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 587a68142a..f08fbb1df2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -1,496 +1,496 @@
-//===-- TypeStreamMerger.cpp ------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
-#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
-#include "llvm/Support/Error.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-static inline size_t slotForIndex(TypeIndex Idx) {
- assert(!Idx.isSimple() && "simple type indices have no slots");
- return Idx.getIndex() - TypeIndex::FirstNonSimpleIndex;
-}
-
-namespace {
-
-/// Implementation of CodeView type stream merging.
-///
-/// A CodeView type stream is a series of records that reference each other
-/// through type indices. A type index is either "simple", meaning it is less
-/// than 0x1000 and refers to a builtin type, or it is complex, meaning it
-/// refers to a prior type record in the current stream. The type index of a
-/// record is equal to the number of records before it in the stream plus
-/// 0x1000.
-///
-/// Type records are only allowed to use type indices smaller than their own, so
+//===-- TypeStreamMerger.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
+#include "llvm/Support/Error.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+static inline size_t slotForIndex(TypeIndex Idx) {
+ assert(!Idx.isSimple() && "simple type indices have no slots");
+ return Idx.getIndex() - TypeIndex::FirstNonSimpleIndex;
+}
+
+namespace {
+
+/// Implementation of CodeView type stream merging.
+///
+/// A CodeView type stream is a series of records that reference each other
+/// through type indices. A type index is either "simple", meaning it is less
+/// than 0x1000 and refers to a builtin type, or it is complex, meaning it
+/// refers to a prior type record in the current stream. The type index of a
+/// record is equal to the number of records before it in the stream plus
+/// 0x1000.
+///
+/// Type records are only allowed to use type indices smaller than their own, so
/// a type stream is effectively a topologically sorted DAG. Cycles occurring in
-/// the type graph of the source program are resolved with forward declarations
-/// of composite types. This class implements the following type stream merging
-/// algorithm, which relies on this DAG structure:
-///
-/// - Begin with a new empty stream, and a new empty hash table that maps from
-/// type record contents to new type index.
-/// - For each new type stream, maintain a map from source type index to
-/// destination type index.
-/// - For each record, copy it and rewrite its type indices to be valid in the
-/// destination type stream.
-/// - If the new type record is not already present in the destination stream
-/// hash table, append it to the destination type stream, assign it the next
-/// type index, and update the two hash tables.
-/// - If the type record already exists in the destination stream, discard it
-/// and update the type index map to forward the source type index to the
-/// existing destination type index.
-///
-/// As an additional complication, type stream merging actually produces two
-/// streams: an item (or IPI) stream and a type stream, as this is what is
-/// actually stored in the final PDB. We choose which records go where by
-/// looking at the record kind.
-class TypeStreamMerger {
-public:
- explicit TypeStreamMerger(SmallVectorImpl<TypeIndex> &SourceToDest)
- : IndexMap(SourceToDest) {
- // When dealing with precompiled headers objects, all data in SourceToDest
- // belongs to the precompiled headers object, and is assumed to be already
- // remapped to the target PDB. Any forthcoming type that will be merged in
- // might potentially back-reference this data. We also don't want to resolve
- // twice the types in the precompiled object.
- CurIndex += SourceToDest.size();
- }
-
- static const TypeIndex Untranslated;
-
- // Local hashing entry points
- Error mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
- MergingTypeTableBuilder &DestTypes,
- const CVTypeArray &IdsAndTypes, Optional<uint32_t> &S);
- Error mergeIdRecords(MergingTypeTableBuilder &Dest,
- ArrayRef<TypeIndex> TypeSourceToDest,
- const CVTypeArray &Ids);
- Error mergeTypeRecords(MergingTypeTableBuilder &Dest,
- const CVTypeArray &Types);
-
- // Global hashing entry points
- Error mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
- GlobalTypeTableBuilder &DestTypes,
- const CVTypeArray &IdsAndTypes,
- ArrayRef<GloballyHashedType> Hashes,
- Optional<uint32_t> &S);
- Error mergeIdRecords(GlobalTypeTableBuilder &Dest,
- ArrayRef<TypeIndex> TypeSourceToDest,
- const CVTypeArray &Ids,
- ArrayRef<GloballyHashedType> Hashes);
- Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, const CVTypeArray &Types,
- ArrayRef<GloballyHashedType> Hashes,
- Optional<uint32_t> &S);
-
-private:
- Error doit(const CVTypeArray &Types);
-
- Error remapAllTypes(const CVTypeArray &Types);
-
- Error remapType(const CVType &Type);
-
- void addMapping(TypeIndex Idx);
-
- inline bool remapTypeIndex(TypeIndex &Idx) {
- // If we're mapping a pure index stream, then IndexMap only contains
- // mappings from OldIdStream -> NewIdStream, in which case we will need to
- // use the special mapping from OldTypeStream -> NewTypeStream which was
- // computed externally. Regardless, we use this special map if and only if
- // we are doing an id-only mapping.
- if (!hasTypeStream())
- return remapIndex(Idx, TypeLookup);
-
- assert(TypeLookup.empty());
- return remapIndex(Idx, IndexMap);
- }
- inline bool remapItemIndex(TypeIndex &Idx) {
- assert(hasIdStream());
- return remapIndex(Idx, IndexMap);
- }
-
- bool hasTypeStream() const {
- return (UseGlobalHashes) ? (!!DestGlobalTypeStream) : (!!DestTypeStream);
- }
-
- bool hasIdStream() const {
- return (UseGlobalHashes) ? (!!DestGlobalIdStream) : (!!DestIdStream);
- }
-
- ArrayRef<uint8_t> remapIndices(const CVType &OriginalType,
- MutableArrayRef<uint8_t> Storage);
-
- inline bool remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map) {
- if (LLVM_LIKELY(remapIndexSimple(Idx, Map)))
- return true;
-
- return remapIndexFallback(Idx, Map);
- }
-
- inline bool remapIndexSimple(TypeIndex &Idx, ArrayRef<TypeIndex> Map) const {
- // Simple types are unchanged.
- if (Idx.isSimple())
- return true;
-
- // Check if this type index refers to a record we've already translated
- // successfully. If it refers to a type later in the stream or a record we
- // had to defer, defer it until later pass.
- unsigned MapPos = slotForIndex(Idx);
- if (LLVM_UNLIKELY(MapPos >= Map.size() || Map[MapPos] == Untranslated))
- return false;
-
- Idx = Map[MapPos];
- return true;
- }
-
- bool remapIndexFallback(TypeIndex &Idx, ArrayRef<TypeIndex> Map);
-
- Error errorCorruptRecord() const {
- return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record);
- }
-
- Expected<bool> shouldRemapType(const CVType &Type);
-
- Optional<Error> LastError;
-
- bool UseGlobalHashes = false;
-
- bool IsSecondPass = false;
-
- unsigned NumBadIndices = 0;
-
- TypeIndex CurIndex{TypeIndex::FirstNonSimpleIndex};
-
- MergingTypeTableBuilder *DestIdStream = nullptr;
- MergingTypeTableBuilder *DestTypeStream = nullptr;
-
- GlobalTypeTableBuilder *DestGlobalIdStream = nullptr;
- GlobalTypeTableBuilder *DestGlobalTypeStream = nullptr;
-
- ArrayRef<GloballyHashedType> GlobalHashes;
-
- // If we're only mapping id records, this array contains the mapping for
- // type records.
- ArrayRef<TypeIndex> TypeLookup;
-
- /// Map from source type index to destination type index. Indexed by source
- /// type index minus 0x1000.
- SmallVectorImpl<TypeIndex> &IndexMap;
-
- /// Temporary storage that we use to copy a record's data while re-writing
- /// its type indices.
- SmallVector<uint8_t, 256> RemapStorage;
-
- Optional<uint32_t> PCHSignature;
-};
-
-} // end anonymous namespace
-
-const TypeIndex TypeStreamMerger::Untranslated(SimpleTypeKind::NotTranslated);
-
-void TypeStreamMerger::addMapping(TypeIndex Idx) {
- if (!IsSecondPass) {
- assert(IndexMap.size() == slotForIndex(CurIndex) &&
- "visitKnownRecord should add one index map entry");
- IndexMap.push_back(Idx);
- } else {
- assert(slotForIndex(CurIndex) < IndexMap.size());
- IndexMap[slotForIndex(CurIndex)] = Idx;
- }
-}
-
-bool TypeStreamMerger::remapIndexFallback(TypeIndex &Idx,
- ArrayRef<TypeIndex> Map) {
- size_t MapPos = slotForIndex(Idx);
-
- // If this is the second pass and this index isn't in the map, then it points
- // outside the current type stream, and this is a corrupt record.
- if (IsSecondPass && MapPos >= Map.size()) {
- // FIXME: Print a more useful error. We can give the current record and the
- // index that we think its pointing to.
- if (LastError)
- LastError = joinErrors(std::move(*LastError), errorCorruptRecord());
- else
- LastError = errorCorruptRecord();
- }
-
- ++NumBadIndices;
-
- // This type index is invalid. Remap this to "not translated by cvpack",
- // and return failure.
- Idx = Untranslated;
- return false;
-}
-
-// Local hashing entry points
-Error TypeStreamMerger::mergeTypeRecords(MergingTypeTableBuilder &Dest,
- const CVTypeArray &Types) {
- DestTypeStream = &Dest;
- UseGlobalHashes = false;
-
- return doit(Types);
-}
-
-Error TypeStreamMerger::mergeIdRecords(MergingTypeTableBuilder &Dest,
- ArrayRef<TypeIndex> TypeSourceToDest,
- const CVTypeArray &Ids) {
- DestIdStream = &Dest;
- TypeLookup = TypeSourceToDest;
- UseGlobalHashes = false;
-
- return doit(Ids);
-}
-
-Error TypeStreamMerger::mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
- MergingTypeTableBuilder &DestTypes,
- const CVTypeArray &IdsAndTypes,
- Optional<uint32_t> &S) {
- DestIdStream = &DestIds;
- DestTypeStream = &DestTypes;
- UseGlobalHashes = false;
- auto Err = doit(IdsAndTypes);
- S = PCHSignature;
- return Err;
-}
-
-// Global hashing entry points
-Error TypeStreamMerger::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
- const CVTypeArray &Types,
- ArrayRef<GloballyHashedType> Hashes,
- Optional<uint32_t> &S) {
- DestGlobalTypeStream = &Dest;
- UseGlobalHashes = true;
- GlobalHashes = Hashes;
- auto Err = doit(Types);
- S = PCHSignature;
- return Err;
-}
-
-Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest,
- ArrayRef<TypeIndex> TypeSourceToDest,
- const CVTypeArray &Ids,
- ArrayRef<GloballyHashedType> Hashes) {
- DestGlobalIdStream = &Dest;
- TypeLookup = TypeSourceToDest;
- UseGlobalHashes = true;
- GlobalHashes = Hashes;
-
- return doit(Ids);
-}
-
-Error TypeStreamMerger::mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
- GlobalTypeTableBuilder &DestTypes,
- const CVTypeArray &IdsAndTypes,
- ArrayRef<GloballyHashedType> Hashes,
- Optional<uint32_t> &S) {
- DestGlobalIdStream = &DestIds;
- DestGlobalTypeStream = &DestTypes;
- UseGlobalHashes = true;
- GlobalHashes = Hashes;
- auto Err = doit(IdsAndTypes);
- S = PCHSignature;
- return Err;
-}
-
-Error TypeStreamMerger::doit(const CVTypeArray &Types) {
- if (auto EC = remapAllTypes(Types))
- return EC;
-
- // If we found bad indices but no other errors, try doing another pass and see
- // if we can resolve the indices that weren't in the map on the first pass.
- // This may require multiple passes, but we should always make progress. MASM
- // is the only known CodeView producer that makes type streams that aren't
- // topologically sorted. The standard library contains MASM-produced objects,
- // so this is important to handle correctly, but we don't have to be too
- // efficient. MASM type streams are usually very small.
- while (!LastError && NumBadIndices > 0) {
- unsigned BadIndicesRemaining = NumBadIndices;
- IsSecondPass = true;
- NumBadIndices = 0;
- CurIndex = TypeIndex(TypeIndex::FirstNonSimpleIndex);
-
- if (auto EC = remapAllTypes(Types))
- return EC;
-
- assert(NumBadIndices <= BadIndicesRemaining &&
- "second pass found more bad indices");
- if (!LastError && NumBadIndices == BadIndicesRemaining) {
- return llvm::make_error<CodeViewError>(
- cv_error_code::corrupt_record, "Input type graph contains cycles");
- }
- }
-
- if (LastError)
- return std::move(*LastError);
- return Error::success();
-}
-
-Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) {
- BinaryStreamRef Stream = Types.getUnderlyingStream();
- ArrayRef<uint8_t> Buffer;
- cantFail(Stream.readBytes(0, Stream.getLength(), Buffer));
-
- return forEachCodeViewRecord<CVType>(
- Buffer, [this](const CVType &T) { return remapType(T); });
-}
-
-Error TypeStreamMerger::remapType(const CVType &Type) {
- auto R = shouldRemapType(Type);
- if (!R)
- return R.takeError();
-
- TypeIndex DestIdx = Untranslated;
- if (*R) {
- auto DoSerialize =
- [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> {
- return remapIndices(Type, Storage);
- };
- unsigned AlignedSize = alignTo(Type.RecordData.size(), 4);
-
- if (LLVM_LIKELY(UseGlobalHashes)) {
- GlobalTypeTableBuilder &Dest =
- isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
- GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
- DestIdx = Dest.insertRecordAs(H, AlignedSize, DoSerialize);
- } else {
- MergingTypeTableBuilder &Dest =
- isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
-
- RemapStorage.resize(AlignedSize);
- ArrayRef<uint8_t> Result = DoSerialize(RemapStorage);
- if (!Result.empty())
- DestIdx = Dest.insertRecordBytes(Result);
- }
- }
- addMapping(DestIdx);
-
- ++CurIndex;
- assert((IsSecondPass || IndexMap.size() == slotForIndex(CurIndex)) &&
- "visitKnownRecord should add one index map entry");
- return Error::success();
-}
-
-ArrayRef<uint8_t>
-TypeStreamMerger::remapIndices(const CVType &OriginalType,
- MutableArrayRef<uint8_t> Storage) {
- unsigned Align = OriginalType.RecordData.size() & 3;
- assert(Storage.size() == alignTo(OriginalType.RecordData.size(), 4) &&
- "The storage buffer size is not a multiple of 4 bytes which will "
- "cause misalignment in the output TPI stream!");
-
- SmallVector<TiReference, 4> Refs;
- discoverTypeIndices(OriginalType.RecordData, Refs);
- if (Refs.empty() && Align == 0)
- return OriginalType.RecordData;
-
- ::memcpy(Storage.data(), OriginalType.RecordData.data(),
- OriginalType.RecordData.size());
-
- uint8_t *DestContent = Storage.data() + sizeof(RecordPrefix);
-
- for (auto &Ref : Refs) {
- TypeIndex *DestTIs =
- reinterpret_cast<TypeIndex *>(DestContent + Ref.Offset);
-
- for (size_t I = 0; I < Ref.Count; ++I) {
- TypeIndex &TI = DestTIs[I];
- bool Success = (Ref.Kind == TiRefKind::IndexRef) ? remapItemIndex(TI)
- : remapTypeIndex(TI);
- if (LLVM_UNLIKELY(!Success))
- return {};
- }
- }
-
- if (Align > 0) {
- RecordPrefix *StorageHeader =
- reinterpret_cast<RecordPrefix *>(Storage.data());
- StorageHeader->RecordLen += 4 - Align;
-
- DestContent = Storage.data() + OriginalType.RecordData.size();
- for (; Align < 4; ++Align)
- *DestContent++ = LF_PAD4 - Align;
- }
- return Storage;
-}
-
-Error llvm::codeview::mergeTypeRecords(MergingTypeTableBuilder &Dest,
- SmallVectorImpl<TypeIndex> &SourceToDest,
- const CVTypeArray &Types) {
- TypeStreamMerger M(SourceToDest);
- return M.mergeTypeRecords(Dest, Types);
-}
-
-Error llvm::codeview::mergeIdRecords(MergingTypeTableBuilder &Dest,
- ArrayRef<TypeIndex> TypeSourceToDest,
- SmallVectorImpl<TypeIndex> &SourceToDest,
- const CVTypeArray &Ids) {
- TypeStreamMerger M(SourceToDest);
- return M.mergeIdRecords(Dest, TypeSourceToDest, Ids);
-}
-
-Error llvm::codeview::mergeTypeAndIdRecords(
- MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes,
- SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes,
- Optional<uint32_t> &PCHSignature) {
- TypeStreamMerger M(SourceToDest);
- return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, PCHSignature);
-}
-
-Error llvm::codeview::mergeTypeAndIdRecords(
- GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes,
- SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes,
- ArrayRef<GloballyHashedType> Hashes, Optional<uint32_t> &PCHSignature) {
- TypeStreamMerger M(SourceToDest);
- return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes,
- PCHSignature);
-}
-
-Error llvm::codeview::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
- SmallVectorImpl<TypeIndex> &SourceToDest,
- const CVTypeArray &Types,
- ArrayRef<GloballyHashedType> Hashes,
- Optional<uint32_t> &PCHSignature) {
- TypeStreamMerger M(SourceToDest);
- return M.mergeTypeRecords(Dest, Types, Hashes, PCHSignature);
-}
-
-Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest,
- ArrayRef<TypeIndex> Types,
- SmallVectorImpl<TypeIndex> &SourceToDest,
- const CVTypeArray &Ids,
- ArrayRef<GloballyHashedType> Hashes) {
- TypeStreamMerger M(SourceToDest);
- return M.mergeIdRecords(Dest, Types, Ids, Hashes);
-}
-
-Expected<bool> TypeStreamMerger::shouldRemapType(const CVType &Type) {
- // For object files containing precompiled types, we need to extract the
- // signature, through EndPrecompRecord. This is done here for performance
- // reasons, to avoid re-parsing the Types stream.
- if (Type.kind() == LF_ENDPRECOMP) {
- EndPrecompRecord EP;
- if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type),
- EP))
- return joinErrors(std::move(EC), errorCorruptRecord());
- if (PCHSignature.hasValue())
- return errorCorruptRecord();
- PCHSignature.emplace(EP.getSignature());
- return false;
- }
- return true;
-}
+/// the type graph of the source program are resolved with forward declarations
+/// of composite types. This class implements the following type stream merging
+/// algorithm, which relies on this DAG structure:
+///
+/// - Begin with a new empty stream, and a new empty hash table that maps from
+/// type record contents to new type index.
+/// - For each new type stream, maintain a map from source type index to
+/// destination type index.
+/// - For each record, copy it and rewrite its type indices to be valid in the
+/// destination type stream.
+/// - If the new type record is not already present in the destination stream
+/// hash table, append it to the destination type stream, assign it the next
+/// type index, and update the two hash tables.
+/// - If the type record already exists in the destination stream, discard it
+/// and update the type index map to forward the source type index to the
+/// existing destination type index.
+///
+/// As an additional complication, type stream merging actually produces two
+/// streams: an item (or IPI) stream and a type stream, as this is what is
+/// actually stored in the final PDB. We choose which records go where by
+/// looking at the record kind.
+class TypeStreamMerger {
+public:
+ explicit TypeStreamMerger(SmallVectorImpl<TypeIndex> &SourceToDest)
+ : IndexMap(SourceToDest) {
+ // When dealing with precompiled headers objects, all data in SourceToDest
+ // belongs to the precompiled headers object, and is assumed to be already
+ // remapped to the target PDB. Any forthcoming type that will be merged in
+ // might potentially back-reference this data. We also don't want to resolve
+ // twice the types in the precompiled object.
+ CurIndex += SourceToDest.size();
+ }
+
+ static const TypeIndex Untranslated;
+
+ // Local hashing entry points
+ Error mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
+ MergingTypeTableBuilder &DestTypes,
+ const CVTypeArray &IdsAndTypes, Optional<uint32_t> &S);
+ Error mergeIdRecords(MergingTypeTableBuilder &Dest,
+ ArrayRef<TypeIndex> TypeSourceToDest,
+ const CVTypeArray &Ids);
+ Error mergeTypeRecords(MergingTypeTableBuilder &Dest,
+ const CVTypeArray &Types);
+
+ // Global hashing entry points
+ Error mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
+ GlobalTypeTableBuilder &DestTypes,
+ const CVTypeArray &IdsAndTypes,
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<uint32_t> &S);
+ Error mergeIdRecords(GlobalTypeTableBuilder &Dest,
+ ArrayRef<TypeIndex> TypeSourceToDest,
+ const CVTypeArray &Ids,
+ ArrayRef<GloballyHashedType> Hashes);
+ Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, const CVTypeArray &Types,
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<uint32_t> &S);
+
+private:
+ Error doit(const CVTypeArray &Types);
+
+ Error remapAllTypes(const CVTypeArray &Types);
+
+ Error remapType(const CVType &Type);
+
+ void addMapping(TypeIndex Idx);
+
+ inline bool remapTypeIndex(TypeIndex &Idx) {
+ // If we're mapping a pure index stream, then IndexMap only contains
+ // mappings from OldIdStream -> NewIdStream, in which case we will need to
+ // use the special mapping from OldTypeStream -> NewTypeStream which was
+ // computed externally. Regardless, we use this special map if and only if
+ // we are doing an id-only mapping.
+ if (!hasTypeStream())
+ return remapIndex(Idx, TypeLookup);
+
+ assert(TypeLookup.empty());
+ return remapIndex(Idx, IndexMap);
+ }
+ inline bool remapItemIndex(TypeIndex &Idx) {
+ assert(hasIdStream());
+ return remapIndex(Idx, IndexMap);
+ }
+
+ bool hasTypeStream() const {
+ return (UseGlobalHashes) ? (!!DestGlobalTypeStream) : (!!DestTypeStream);
+ }
+
+ bool hasIdStream() const {
+ return (UseGlobalHashes) ? (!!DestGlobalIdStream) : (!!DestIdStream);
+ }
+
+ ArrayRef<uint8_t> remapIndices(const CVType &OriginalType,
+ MutableArrayRef<uint8_t> Storage);
+
+ inline bool remapIndex(TypeIndex &Idx, ArrayRef<TypeIndex> Map) {
+ if (LLVM_LIKELY(remapIndexSimple(Idx, Map)))
+ return true;
+
+ return remapIndexFallback(Idx, Map);
+ }
+
+ inline bool remapIndexSimple(TypeIndex &Idx, ArrayRef<TypeIndex> Map) const {
+ // Simple types are unchanged.
+ if (Idx.isSimple())
+ return true;
+
+ // Check if this type index refers to a record we've already translated
+ // successfully. If it refers to a type later in the stream or a record we
+ // had to defer, defer it until later pass.
+ unsigned MapPos = slotForIndex(Idx);
+ if (LLVM_UNLIKELY(MapPos >= Map.size() || Map[MapPos] == Untranslated))
+ return false;
+
+ Idx = Map[MapPos];
+ return true;
+ }
+
+ bool remapIndexFallback(TypeIndex &Idx, ArrayRef<TypeIndex> Map);
+
+ Error errorCorruptRecord() const {
+ return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record);
+ }
+
+ Expected<bool> shouldRemapType(const CVType &Type);
+
+ Optional<Error> LastError;
+
+ bool UseGlobalHashes = false;
+
+ bool IsSecondPass = false;
+
+ unsigned NumBadIndices = 0;
+
+ TypeIndex CurIndex{TypeIndex::FirstNonSimpleIndex};
+
+ MergingTypeTableBuilder *DestIdStream = nullptr;
+ MergingTypeTableBuilder *DestTypeStream = nullptr;
+
+ GlobalTypeTableBuilder *DestGlobalIdStream = nullptr;
+ GlobalTypeTableBuilder *DestGlobalTypeStream = nullptr;
+
+ ArrayRef<GloballyHashedType> GlobalHashes;
+
+ // If we're only mapping id records, this array contains the mapping for
+ // type records.
+ ArrayRef<TypeIndex> TypeLookup;
+
+ /// Map from source type index to destination type index. Indexed by source
+ /// type index minus 0x1000.
+ SmallVectorImpl<TypeIndex> &IndexMap;
+
+ /// Temporary storage that we use to copy a record's data while re-writing
+ /// its type indices.
+ SmallVector<uint8_t, 256> RemapStorage;
+
+ Optional<uint32_t> PCHSignature;
+};
+
+} // end anonymous namespace
+
+const TypeIndex TypeStreamMerger::Untranslated(SimpleTypeKind::NotTranslated);
+
+void TypeStreamMerger::addMapping(TypeIndex Idx) {
+ if (!IsSecondPass) {
+ assert(IndexMap.size() == slotForIndex(CurIndex) &&
+ "visitKnownRecord should add one index map entry");
+ IndexMap.push_back(Idx);
+ } else {
+ assert(slotForIndex(CurIndex) < IndexMap.size());
+ IndexMap[slotForIndex(CurIndex)] = Idx;
+ }
+}
+
+bool TypeStreamMerger::remapIndexFallback(TypeIndex &Idx,
+ ArrayRef<TypeIndex> Map) {
+ size_t MapPos = slotForIndex(Idx);
+
+ // If this is the second pass and this index isn't in the map, then it points
+ // outside the current type stream, and this is a corrupt record.
+ if (IsSecondPass && MapPos >= Map.size()) {
+ // FIXME: Print a more useful error. We can give the current record and the
+ // index that we think its pointing to.
+ if (LastError)
+ LastError = joinErrors(std::move(*LastError), errorCorruptRecord());
+ else
+ LastError = errorCorruptRecord();
+ }
+
+ ++NumBadIndices;
+
+ // This type index is invalid. Remap this to "not translated by cvpack",
+ // and return failure.
+ Idx = Untranslated;
+ return false;
+}
+
+// Local hashing entry points
+Error TypeStreamMerger::mergeTypeRecords(MergingTypeTableBuilder &Dest,
+ const CVTypeArray &Types) {
+ DestTypeStream = &Dest;
+ UseGlobalHashes = false;
+
+ return doit(Types);
+}
+
+Error TypeStreamMerger::mergeIdRecords(MergingTypeTableBuilder &Dest,
+ ArrayRef<TypeIndex> TypeSourceToDest,
+ const CVTypeArray &Ids) {
+ DestIdStream = &Dest;
+ TypeLookup = TypeSourceToDest;
+ UseGlobalHashes = false;
+
+ return doit(Ids);
+}
+
+Error TypeStreamMerger::mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
+ MergingTypeTableBuilder &DestTypes,
+ const CVTypeArray &IdsAndTypes,
+ Optional<uint32_t> &S) {
+ DestIdStream = &DestIds;
+ DestTypeStream = &DestTypes;
+ UseGlobalHashes = false;
+ auto Err = doit(IdsAndTypes);
+ S = PCHSignature;
+ return Err;
+}
+
+// Global hashing entry points
+Error TypeStreamMerger::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
+ const CVTypeArray &Types,
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<uint32_t> &S) {
+ DestGlobalTypeStream = &Dest;
+ UseGlobalHashes = true;
+ GlobalHashes = Hashes;
+ auto Err = doit(Types);
+ S = PCHSignature;
+ return Err;
+}
+
+Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest,
+ ArrayRef<TypeIndex> TypeSourceToDest,
+ const CVTypeArray &Ids,
+ ArrayRef<GloballyHashedType> Hashes) {
+ DestGlobalIdStream = &Dest;
+ TypeLookup = TypeSourceToDest;
+ UseGlobalHashes = true;
+ GlobalHashes = Hashes;
+
+ return doit(Ids);
+}
+
+Error TypeStreamMerger::mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
+ GlobalTypeTableBuilder &DestTypes,
+ const CVTypeArray &IdsAndTypes,
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<uint32_t> &S) {
+ DestGlobalIdStream = &DestIds;
+ DestGlobalTypeStream = &DestTypes;
+ UseGlobalHashes = true;
+ GlobalHashes = Hashes;
+ auto Err = doit(IdsAndTypes);
+ S = PCHSignature;
+ return Err;
+}
+
+Error TypeStreamMerger::doit(const CVTypeArray &Types) {
+ if (auto EC = remapAllTypes(Types))
+ return EC;
+
+ // If we found bad indices but no other errors, try doing another pass and see
+ // if we can resolve the indices that weren't in the map on the first pass.
+ // This may require multiple passes, but we should always make progress. MASM
+ // is the only known CodeView producer that makes type streams that aren't
+ // topologically sorted. The standard library contains MASM-produced objects,
+ // so this is important to handle correctly, but we don't have to be too
+ // efficient. MASM type streams are usually very small.
+ while (!LastError && NumBadIndices > 0) {
+ unsigned BadIndicesRemaining = NumBadIndices;
+ IsSecondPass = true;
+ NumBadIndices = 0;
+ CurIndex = TypeIndex(TypeIndex::FirstNonSimpleIndex);
+
+ if (auto EC = remapAllTypes(Types))
+ return EC;
+
+ assert(NumBadIndices <= BadIndicesRemaining &&
+ "second pass found more bad indices");
+ if (!LastError && NumBadIndices == BadIndicesRemaining) {
+ return llvm::make_error<CodeViewError>(
+ cv_error_code::corrupt_record, "Input type graph contains cycles");
+ }
+ }
+
+ if (LastError)
+ return std::move(*LastError);
+ return Error::success();
+}
+
+Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) {
+ BinaryStreamRef Stream = Types.getUnderlyingStream();
+ ArrayRef<uint8_t> Buffer;
+ cantFail(Stream.readBytes(0, Stream.getLength(), Buffer));
+
+ return forEachCodeViewRecord<CVType>(
+ Buffer, [this](const CVType &T) { return remapType(T); });
+}
+
+Error TypeStreamMerger::remapType(const CVType &Type) {
+ auto R = shouldRemapType(Type);
+ if (!R)
+ return R.takeError();
+
+ TypeIndex DestIdx = Untranslated;
+ if (*R) {
+ auto DoSerialize =
+ [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> {
+ return remapIndices(Type, Storage);
+ };
+ unsigned AlignedSize = alignTo(Type.RecordData.size(), 4);
+
+ if (LLVM_LIKELY(UseGlobalHashes)) {
+ GlobalTypeTableBuilder &Dest =
+ isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
+ GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
+ DestIdx = Dest.insertRecordAs(H, AlignedSize, DoSerialize);
+ } else {
+ MergingTypeTableBuilder &Dest =
+ isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
+
+ RemapStorage.resize(AlignedSize);
+ ArrayRef<uint8_t> Result = DoSerialize(RemapStorage);
+ if (!Result.empty())
+ DestIdx = Dest.insertRecordBytes(Result);
+ }
+ }
+ addMapping(DestIdx);
+
+ ++CurIndex;
+ assert((IsSecondPass || IndexMap.size() == slotForIndex(CurIndex)) &&
+ "visitKnownRecord should add one index map entry");
+ return Error::success();
+}
+
+ArrayRef<uint8_t>
+TypeStreamMerger::remapIndices(const CVType &OriginalType,
+ MutableArrayRef<uint8_t> Storage) {
+ unsigned Align = OriginalType.RecordData.size() & 3;
+ assert(Storage.size() == alignTo(OriginalType.RecordData.size(), 4) &&
+ "The storage buffer size is not a multiple of 4 bytes which will "
+ "cause misalignment in the output TPI stream!");
+
+ SmallVector<TiReference, 4> Refs;
+ discoverTypeIndices(OriginalType.RecordData, Refs);
+ if (Refs.empty() && Align == 0)
+ return OriginalType.RecordData;
+
+ ::memcpy(Storage.data(), OriginalType.RecordData.data(),
+ OriginalType.RecordData.size());
+
+ uint8_t *DestContent = Storage.data() + sizeof(RecordPrefix);
+
+ for (auto &Ref : Refs) {
+ TypeIndex *DestTIs =
+ reinterpret_cast<TypeIndex *>(DestContent + Ref.Offset);
+
+ for (size_t I = 0; I < Ref.Count; ++I) {
+ TypeIndex &TI = DestTIs[I];
+ bool Success = (Ref.Kind == TiRefKind::IndexRef) ? remapItemIndex(TI)
+ : remapTypeIndex(TI);
+ if (LLVM_UNLIKELY(!Success))
+ return {};
+ }
+ }
+
+ if (Align > 0) {
+ RecordPrefix *StorageHeader =
+ reinterpret_cast<RecordPrefix *>(Storage.data());
+ StorageHeader->RecordLen += 4 - Align;
+
+ DestContent = Storage.data() + OriginalType.RecordData.size();
+ for (; Align < 4; ++Align)
+ *DestContent++ = LF_PAD4 - Align;
+ }
+ return Storage;
+}
+
+Error llvm::codeview::mergeTypeRecords(MergingTypeTableBuilder &Dest,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Types) {
+ TypeStreamMerger M(SourceToDest);
+ return M.mergeTypeRecords(Dest, Types);
+}
+
+Error llvm::codeview::mergeIdRecords(MergingTypeTableBuilder &Dest,
+ ArrayRef<TypeIndex> TypeSourceToDest,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Ids) {
+ TypeStreamMerger M(SourceToDest);
+ return M.mergeIdRecords(Dest, TypeSourceToDest, Ids);
+}
+
+Error llvm::codeview::mergeTypeAndIdRecords(
+ MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes,
+ SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes,
+ Optional<uint32_t> &PCHSignature) {
+ TypeStreamMerger M(SourceToDest);
+ return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, PCHSignature);
+}
+
+Error llvm::codeview::mergeTypeAndIdRecords(
+ GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes,
+ SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes,
+ ArrayRef<GloballyHashedType> Hashes, Optional<uint32_t> &PCHSignature) {
+ TypeStreamMerger M(SourceToDest);
+ return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes,
+ PCHSignature);
+}
+
+Error llvm::codeview::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Types,
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<uint32_t> &PCHSignature) {
+ TypeStreamMerger M(SourceToDest);
+ return M.mergeTypeRecords(Dest, Types, Hashes, PCHSignature);
+}
+
+Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest,
+ ArrayRef<TypeIndex> Types,
+ SmallVectorImpl<TypeIndex> &SourceToDest,
+ const CVTypeArray &Ids,
+ ArrayRef<GloballyHashedType> Hashes) {
+ TypeStreamMerger M(SourceToDest);
+ return M.mergeIdRecords(Dest, Types, Ids, Hashes);
+}
+
+Expected<bool> TypeStreamMerger::shouldRemapType(const CVType &Type) {
+ // For object files containing precompiled types, we need to extract the
+ // signature, through EndPrecompRecord. This is done here for performance
+ // reasons, to avoid re-parsing the Types stream.
+ if (Type.kind() == LF_ENDPRECOMP) {
+ EndPrecompRecord EP;
+ if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type),
+ EP))
+ return joinErrors(std::move(EC), errorCorruptRecord());
+ if (PCHSignature.hasValue())
+ return errorCorruptRecord();
+ PCHSignature.emplace(EP.getSignature());
+ return false;
+ }
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeTableCollection.cpp b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeTableCollection.cpp
index e517e8846d..fb2ceda9c1 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeTableCollection.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/TypeTableCollection.cpp
@@ -1,65 +1,65 @@
-//===- TypeTableCollection.cpp -------------------------------- *- C++ --*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
-
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/Support/BinaryStreamReader.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-
-TypeTableCollection::TypeTableCollection(ArrayRef<ArrayRef<uint8_t>> Records)
- : NameStorage(Allocator), Records(Records) {
- Names.resize(Records.size());
-}
-
-Optional<TypeIndex> TypeTableCollection::getFirst() {
- if (empty())
- return None;
- return TypeIndex::fromArrayIndex(0);
-}
-
-Optional<TypeIndex> TypeTableCollection::getNext(TypeIndex Prev) {
- assert(contains(Prev));
- ++Prev;
- if (Prev.toArrayIndex() == size())
- return None;
- return Prev;
-}
-
-CVType TypeTableCollection::getType(TypeIndex Index) {
- assert(Index.toArrayIndex() < Records.size());
- return CVType(Records[Index.toArrayIndex()]);
-}
-
-StringRef TypeTableCollection::getTypeName(TypeIndex Index) {
- if (Index.isNoneType() || Index.isSimple())
- return TypeIndex::simpleTypeName(Index);
-
- uint32_t I = Index.toArrayIndex();
- if (Names[I].data() == nullptr) {
- StringRef Result = NameStorage.save(computeTypeName(*this, Index));
- Names[I] = Result;
- }
- return Names[I];
-}
-
-bool TypeTableCollection::contains(TypeIndex Index) {
- return Index.toArrayIndex() <= size();
-}
-
-uint32_t TypeTableCollection::size() { return Records.size(); }
-
-uint32_t TypeTableCollection::capacity() { return Records.size(); }
-
-bool TypeTableCollection::replaceType(TypeIndex &Index, CVType Data,
- bool Stabilize) {
- llvm_unreachable("Method cannot be called");
-}
+//===- TypeTableCollection.cpp -------------------------------- *- C++ --*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/CodeView/TypeTableCollection.h"
+
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/Support/BinaryStreamReader.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+
+TypeTableCollection::TypeTableCollection(ArrayRef<ArrayRef<uint8_t>> Records)
+ : NameStorage(Allocator), Records(Records) {
+ Names.resize(Records.size());
+}
+
+Optional<TypeIndex> TypeTableCollection::getFirst() {
+ if (empty())
+ return None;
+ return TypeIndex::fromArrayIndex(0);
+}
+
+Optional<TypeIndex> TypeTableCollection::getNext(TypeIndex Prev) {
+ assert(contains(Prev));
+ ++Prev;
+ if (Prev.toArrayIndex() == size())
+ return None;
+ return Prev;
+}
+
+CVType TypeTableCollection::getType(TypeIndex Index) {
+ assert(Index.toArrayIndex() < Records.size());
+ return CVType(Records[Index.toArrayIndex()]);
+}
+
+StringRef TypeTableCollection::getTypeName(TypeIndex Index) {
+ if (Index.isNoneType() || Index.isSimple())
+ return TypeIndex::simpleTypeName(Index);
+
+ uint32_t I = Index.toArrayIndex();
+ if (Names[I].data() == nullptr) {
+ StringRef Result = NameStorage.save(computeTypeName(*this, Index));
+ Names[I] = Result;
+ }
+ return Names[I];
+}
+
+bool TypeTableCollection::contains(TypeIndex Index) {
+ return Index.toArrayIndex() <= size();
+}
+
+uint32_t TypeTableCollection::size() { return Records.size(); }
+
+uint32_t TypeTableCollection::capacity() { return Records.size(); }
+
+bool TypeTableCollection::replaceType(TypeIndex &Index, CVType Data,
+ bool Stabilize) {
+ llvm_unreachable("Method cannot be called");
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make b/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make
index 8829a8f09f..b099dd11da 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/CodeView/ya.make
@@ -1,71 +1,71 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
OWNER(
orivej
g:cpp-contrib
)
-
+
LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-PEERDIR(
+PEERDIR(
contrib/libs/llvm12
contrib/libs/llvm12/lib/DebugInfo/MSF
contrib/libs/llvm12/lib/Support
-)
-
+)
+
ADDINCL(
contrib/libs/llvm12/lib/DebugInfo/CodeView
)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
-SRCS(
- AppendingTypeTableBuilder.cpp
- CVSymbolVisitor.cpp
- CVTypeVisitor.cpp
- CodeViewError.cpp
- CodeViewRecordIO.cpp
- ContinuationRecordBuilder.cpp
- DebugChecksumsSubsection.cpp
- DebugCrossExSubsection.cpp
- DebugCrossImpSubsection.cpp
- DebugFrameDataSubsection.cpp
- DebugInlineeLinesSubsection.cpp
- DebugLinesSubsection.cpp
- DebugStringTableSubsection.cpp
- DebugSubsection.cpp
- DebugSubsectionRecord.cpp
- DebugSubsectionVisitor.cpp
- DebugSymbolRVASubsection.cpp
- DebugSymbolsSubsection.cpp
- EnumTables.cpp
- Formatters.cpp
- GlobalTypeTableBuilder.cpp
- LazyRandomTypeCollection.cpp
- Line.cpp
- MergingTypeTableBuilder.cpp
- RecordName.cpp
- RecordSerialization.cpp
- SimpleTypeSerializer.cpp
- StringsAndChecksums.cpp
- SymbolDumper.cpp
- SymbolRecordHelpers.cpp
- SymbolRecordMapping.cpp
- SymbolSerializer.cpp
- TypeDumpVisitor.cpp
- TypeHashing.cpp
- TypeIndex.cpp
- TypeIndexDiscovery.cpp
- TypeRecordHelpers.cpp
- TypeRecordMapping.cpp
- TypeStreamMerger.cpp
- TypeTableCollection.cpp
-)
-
-END()
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+SRCS(
+ AppendingTypeTableBuilder.cpp
+ CVSymbolVisitor.cpp
+ CVTypeVisitor.cpp
+ CodeViewError.cpp
+ CodeViewRecordIO.cpp
+ ContinuationRecordBuilder.cpp
+ DebugChecksumsSubsection.cpp
+ DebugCrossExSubsection.cpp
+ DebugCrossImpSubsection.cpp
+ DebugFrameDataSubsection.cpp
+ DebugInlineeLinesSubsection.cpp
+ DebugLinesSubsection.cpp
+ DebugStringTableSubsection.cpp
+ DebugSubsection.cpp
+ DebugSubsectionRecord.cpp
+ DebugSubsectionVisitor.cpp
+ DebugSymbolRVASubsection.cpp
+ DebugSymbolsSubsection.cpp
+ EnumTables.cpp
+ Formatters.cpp
+ GlobalTypeTableBuilder.cpp
+ LazyRandomTypeCollection.cpp
+ Line.cpp
+ MergingTypeTableBuilder.cpp
+ RecordName.cpp
+ RecordSerialization.cpp
+ SimpleTypeSerializer.cpp
+ StringsAndChecksums.cpp
+ SymbolDumper.cpp
+ SymbolRecordHelpers.cpp
+ SymbolRecordMapping.cpp
+ SymbolSerializer.cpp
+ TypeDumpVisitor.cpp
+ TypeHashing.cpp
+ TypeIndex.cpp
+ TypeIndexDiscovery.cpp
+ TypeRecordHelpers.cpp
+ TypeRecordMapping.cpp
+ TypeStreamMerger.cpp
+ TypeTableCollection.cpp
+)
+
+END()
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
index ee1ff5460b..ef0711fb9a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp
@@ -1,215 +1,215 @@
-//===- DWARFAbbreviationDeclaration.cpp -----------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
-
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstddef>
-#include <cstdint>
-
-using namespace llvm;
-using namespace dwarf;
-
-void DWARFAbbreviationDeclaration::clear() {
- Code = 0;
- Tag = DW_TAG_null;
- CodeByteSize = 0;
- HasChildren = false;
- AttributeSpecs.clear();
- FixedAttributeSize.reset();
-}
-
-DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
- clear();
-}
-
-bool
-DWARFAbbreviationDeclaration::extract(DataExtractor Data,
- uint64_t* OffsetPtr) {
- clear();
- const uint64_t Offset = *OffsetPtr;
- Code = Data.getULEB128(OffsetPtr);
- if (Code == 0) {
- return false;
- }
- CodeByteSize = *OffsetPtr - Offset;
- Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
- if (Tag == DW_TAG_null) {
- clear();
- return false;
- }
- uint8_t ChildrenByte = Data.getU8(OffsetPtr);
- HasChildren = (ChildrenByte == DW_CHILDREN_yes);
- // Assign a value to our optional FixedAttributeSize member variable. If
- // this member variable still has a value after the while loop below, then
- // all attribute data in this abbreviation declaration has a fixed byte size.
- FixedAttributeSize = FixedSizeInfo();
-
- // Read all of the abbreviation attributes and forms.
- while (true) {
- auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
- auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
- if (A && F) {
- bool IsImplicitConst = (F == DW_FORM_implicit_const);
- if (IsImplicitConst) {
- int64_t V = Data.getSLEB128(OffsetPtr);
- AttributeSpecs.push_back(AttributeSpec(A, F, V));
- continue;
- }
- Optional<uint8_t> ByteSize;
- // If this abbrevation still has a fixed byte size, then update the
- // FixedAttributeSize as needed.
- switch (F) {
- case DW_FORM_addr:
- if (FixedAttributeSize)
- ++FixedAttributeSize->NumAddrs;
- break;
-
- case DW_FORM_ref_addr:
- if (FixedAttributeSize)
- ++FixedAttributeSize->NumRefAddrs;
- break;
-
- case DW_FORM_strp:
- case DW_FORM_GNU_ref_alt:
- case DW_FORM_GNU_strp_alt:
- case DW_FORM_line_strp:
- case DW_FORM_sec_offset:
- case DW_FORM_strp_sup:
- if (FixedAttributeSize)
- ++FixedAttributeSize->NumDwarfOffsets;
- break;
-
- default:
- // The form has a byte size that doesn't depend on Params.
- // If it's a fixed size, keep track of it.
- if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
- if (FixedAttributeSize)
- FixedAttributeSize->NumBytes += *ByteSize;
- break;
- }
- // Indicate we no longer have a fixed byte size for this
- // abbreviation by clearing the FixedAttributeSize optional value
- // so it doesn't have a value.
- FixedAttributeSize.reset();
- break;
- }
- // Record this attribute and its fixed size if it has one.
- AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
- } else if (A == 0 && F == 0) {
- // We successfully reached the end of this abbreviation declaration
- // since both attribute and form are zero.
- break;
- } else {
- // Attribute and form pairs must either both be non-zero, in which case
- // they are added to the abbreviation declaration, or both be zero to
- // terminate the abbrevation declaration. In this case only one was
- // zero which is an error.
- clear();
- return false;
- }
- }
- return true;
-}
-
-void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
- OS << '[' << getCode() << "] ";
- OS << formatv("{0}", getTag());
- OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
- for (const AttributeSpec &Spec : AttributeSpecs) {
- OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
- if (Spec.isImplicitConst())
- OS << '\t' << Spec.getImplicitConstValue();
- OS << '\n';
- }
- OS << '\n';
-}
-
-Optional<uint32_t>
-DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
- for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
- if (AttributeSpecs[i].Attr == Attr)
- return i;
- }
- return None;
-}
-
-Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
- const uint64_t DIEOffset, const dwarf::Attribute Attr,
- const DWARFUnit &U) const {
- // Check if this abbreviation has this attribute without needing to skip
- // any data so we can return quickly if it doesn't.
- Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
- if (!MatchAttrIndex)
- return None;
-
- auto DebugInfoData = U.getDebugInfoExtractor();
-
- // Add the byte size of ULEB that for the abbrev Code so we can start
- // skipping the attribute data.
- uint64_t Offset = DIEOffset + CodeByteSize;
- for (uint32_t CurAttrIdx = 0; CurAttrIdx != *MatchAttrIndex; ++CurAttrIdx)
- // Match Offset along until we get to the attribute we want.
- if (auto FixedSize = AttributeSpecs[CurAttrIdx].getByteSize(U))
- Offset += *FixedSize;
- else
- DWARFFormValue::skipValue(AttributeSpecs[CurAttrIdx].Form, DebugInfoData,
- &Offset, U.getFormParams());
-
- // We have arrived at the attribute to extract, extract if from Offset.
- const AttributeSpec &Spec = AttributeSpecs[*MatchAttrIndex];
- if (Spec.isImplicitConst())
- return DWARFFormValue::createFromSValue(Spec.Form,
- Spec.getImplicitConstValue());
-
- DWARFFormValue FormValue(Spec.Form);
- if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
- return FormValue;
-
- return None;
-}
-
-size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
- const DWARFUnit &U) const {
- size_t ByteSize = NumBytes;
- if (NumAddrs)
- ByteSize += NumAddrs * U.getAddressByteSize();
- if (NumRefAddrs)
- ByteSize += NumRefAddrs * U.getRefAddrByteSize();
- if (NumDwarfOffsets)
- ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
- return ByteSize;
-}
-
-Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
- const DWARFUnit &U) const {
- if (isImplicitConst())
- return 0;
- if (ByteSize.HasByteSize)
- return ByteSize.ByteSize;
- Optional<int64_t> S;
- auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
- if (FixedByteSize)
- S = *FixedByteSize;
- return S;
-}
-
-Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
- const DWARFUnit &U) const {
- if (FixedAttributeSize)
- return FixedAttributeSize->getByteSize(U);
- return None;
-}
+//===- DWARFAbbreviationDeclaration.cpp -----------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstddef>
+#include <cstdint>
+
+using namespace llvm;
+using namespace dwarf;
+
+void DWARFAbbreviationDeclaration::clear() {
+ Code = 0;
+ Tag = DW_TAG_null;
+ CodeByteSize = 0;
+ HasChildren = false;
+ AttributeSpecs.clear();
+ FixedAttributeSize.reset();
+}
+
+DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() {
+ clear();
+}
+
+bool
+DWARFAbbreviationDeclaration::extract(DataExtractor Data,
+ uint64_t* OffsetPtr) {
+ clear();
+ const uint64_t Offset = *OffsetPtr;
+ Code = Data.getULEB128(OffsetPtr);
+ if (Code == 0) {
+ return false;
+ }
+ CodeByteSize = *OffsetPtr - Offset;
+ Tag = static_cast<llvm::dwarf::Tag>(Data.getULEB128(OffsetPtr));
+ if (Tag == DW_TAG_null) {
+ clear();
+ return false;
+ }
+ uint8_t ChildrenByte = Data.getU8(OffsetPtr);
+ HasChildren = (ChildrenByte == DW_CHILDREN_yes);
+ // Assign a value to our optional FixedAttributeSize member variable. If
+ // this member variable still has a value after the while loop below, then
+ // all attribute data in this abbreviation declaration has a fixed byte size.
+ FixedAttributeSize = FixedSizeInfo();
+
+ // Read all of the abbreviation attributes and forms.
+ while (true) {
+ auto A = static_cast<Attribute>(Data.getULEB128(OffsetPtr));
+ auto F = static_cast<Form>(Data.getULEB128(OffsetPtr));
+ if (A && F) {
+ bool IsImplicitConst = (F == DW_FORM_implicit_const);
+ if (IsImplicitConst) {
+ int64_t V = Data.getSLEB128(OffsetPtr);
+ AttributeSpecs.push_back(AttributeSpec(A, F, V));
+ continue;
+ }
+ Optional<uint8_t> ByteSize;
+ // If this abbrevation still has a fixed byte size, then update the
+ // FixedAttributeSize as needed.
+ switch (F) {
+ case DW_FORM_addr:
+ if (FixedAttributeSize)
+ ++FixedAttributeSize->NumAddrs;
+ break;
+
+ case DW_FORM_ref_addr:
+ if (FixedAttributeSize)
+ ++FixedAttributeSize->NumRefAddrs;
+ break;
+
+ case DW_FORM_strp:
+ case DW_FORM_GNU_ref_alt:
+ case DW_FORM_GNU_strp_alt:
+ case DW_FORM_line_strp:
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp_sup:
+ if (FixedAttributeSize)
+ ++FixedAttributeSize->NumDwarfOffsets;
+ break;
+
+ default:
+ // The form has a byte size that doesn't depend on Params.
+ // If it's a fixed size, keep track of it.
+ if ((ByteSize = dwarf::getFixedFormByteSize(F, dwarf::FormParams()))) {
+ if (FixedAttributeSize)
+ FixedAttributeSize->NumBytes += *ByteSize;
+ break;
+ }
+ // Indicate we no longer have a fixed byte size for this
+ // abbreviation by clearing the FixedAttributeSize optional value
+ // so it doesn't have a value.
+ FixedAttributeSize.reset();
+ break;
+ }
+ // Record this attribute and its fixed size if it has one.
+ AttributeSpecs.push_back(AttributeSpec(A, F, ByteSize));
+ } else if (A == 0 && F == 0) {
+ // We successfully reached the end of this abbreviation declaration
+ // since both attribute and form are zero.
+ break;
+ } else {
+ // Attribute and form pairs must either both be non-zero, in which case
+ // they are added to the abbreviation declaration, or both be zero to
+ // terminate the abbrevation declaration. In this case only one was
+ // zero which is an error.
+ clear();
+ return false;
+ }
+ }
+ return true;
+}
+
+void DWARFAbbreviationDeclaration::dump(raw_ostream &OS) const {
+ OS << '[' << getCode() << "] ";
+ OS << formatv("{0}", getTag());
+ OS << "\tDW_CHILDREN_" << (hasChildren() ? "yes" : "no") << '\n';
+ for (const AttributeSpec &Spec : AttributeSpecs) {
+ OS << formatv("\t{0}\t{1}", Spec.Attr, Spec.Form);
+ if (Spec.isImplicitConst())
+ OS << '\t' << Spec.getImplicitConstValue();
+ OS << '\n';
+ }
+ OS << '\n';
+}
+
+Optional<uint32_t>
+DWARFAbbreviationDeclaration::findAttributeIndex(dwarf::Attribute Attr) const {
+ for (uint32_t i = 0, e = AttributeSpecs.size(); i != e; ++i) {
+ if (AttributeSpecs[i].Attr == Attr)
+ return i;
+ }
+ return None;
+}
+
+Optional<DWARFFormValue> DWARFAbbreviationDeclaration::getAttributeValue(
+ const uint64_t DIEOffset, const dwarf::Attribute Attr,
+ const DWARFUnit &U) const {
+ // Check if this abbreviation has this attribute without needing to skip
+ // any data so we can return quickly if it doesn't.
+ Optional<uint32_t> MatchAttrIndex = findAttributeIndex(Attr);
+ if (!MatchAttrIndex)
+ return None;
+
+ auto DebugInfoData = U.getDebugInfoExtractor();
+
+ // Add the byte size of ULEB that for the abbrev Code so we can start
+ // skipping the attribute data.
+ uint64_t Offset = DIEOffset + CodeByteSize;
+ for (uint32_t CurAttrIdx = 0; CurAttrIdx != *MatchAttrIndex; ++CurAttrIdx)
+ // Match Offset along until we get to the attribute we want.
+ if (auto FixedSize = AttributeSpecs[CurAttrIdx].getByteSize(U))
+ Offset += *FixedSize;
+ else
+ DWARFFormValue::skipValue(AttributeSpecs[CurAttrIdx].Form, DebugInfoData,
+ &Offset, U.getFormParams());
+
+ // We have arrived at the attribute to extract, extract if from Offset.
+ const AttributeSpec &Spec = AttributeSpecs[*MatchAttrIndex];
+ if (Spec.isImplicitConst())
+ return DWARFFormValue::createFromSValue(Spec.Form,
+ Spec.getImplicitConstValue());
+
+ DWARFFormValue FormValue(Spec.Form);
+ if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U))
+ return FormValue;
+
+ return None;
+}
+
+size_t DWARFAbbreviationDeclaration::FixedSizeInfo::getByteSize(
+ const DWARFUnit &U) const {
+ size_t ByteSize = NumBytes;
+ if (NumAddrs)
+ ByteSize += NumAddrs * U.getAddressByteSize();
+ if (NumRefAddrs)
+ ByteSize += NumRefAddrs * U.getRefAddrByteSize();
+ if (NumDwarfOffsets)
+ ByteSize += NumDwarfOffsets * U.getDwarfOffsetByteSize();
+ return ByteSize;
+}
+
+Optional<int64_t> DWARFAbbreviationDeclaration::AttributeSpec::getByteSize(
+ const DWARFUnit &U) const {
+ if (isImplicitConst())
+ return 0;
+ if (ByteSize.HasByteSize)
+ return ByteSize.ByteSize;
+ Optional<int64_t> S;
+ auto FixedByteSize = dwarf::getFixedFormByteSize(Form, U.getFormParams());
+ if (FixedByteSize)
+ S = *FixedByteSize;
+ return S;
+}
+
+Optional<size_t> DWARFAbbreviationDeclaration::getFixedAttributesByteSize(
+ const DWARFUnit &U) const {
+ if (FixedAttributeSize)
+ return FixedAttributeSize->getByteSize(U);
+ return None;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
index 28d35b609c..88566eecd5 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp
@@ -1,905 +1,905 @@
-//===- DWARFAcceleratorTable.cpp ------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
-
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DJB.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/ScopedPrinter.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstddef>
-#include <cstdint>
-#include <utility>
-
-using namespace llvm;
-
-namespace {
-struct Atom {
- unsigned Value;
-};
-
-static raw_ostream &operator<<(raw_ostream &OS, const Atom &A) {
- StringRef Str = dwarf::AtomTypeString(A.Value);
- if (!Str.empty())
- return OS << Str;
- return OS << "DW_ATOM_unknown_" << format("%x", A.Value);
-}
-} // namespace
-
-static Atom formatAtom(unsigned Atom) { return {Atom}; }
-
-DWARFAcceleratorTable::~DWARFAcceleratorTable() = default;
-
-Error AppleAcceleratorTable::extract() {
- uint64_t Offset = 0;
-
- // Check that we can at least read the header.
- if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength) + 4))
- return createStringError(errc::illegal_byte_sequence,
- "Section too small: cannot read header.");
-
- Hdr.Magic = AccelSection.getU32(&Offset);
- Hdr.Version = AccelSection.getU16(&Offset);
- Hdr.HashFunction = AccelSection.getU16(&Offset);
- Hdr.BucketCount = AccelSection.getU32(&Offset);
- Hdr.HashCount = AccelSection.getU32(&Offset);
- Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
-
- // Check that we can read all the hashes and offsets from the
- // section (see SourceLevelDebugging.rst for the structure of the index).
- // We need to substract one because we're checking for an *offset* which is
- // equal to the size for an empty table and hence pointer after the section.
- if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
- Hdr.BucketCount * 4 + Hdr.HashCount * 8 - 1))
- return createStringError(
- errc::illegal_byte_sequence,
- "Section too small: cannot read buckets and hashes.");
-
- HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
- uint32_t NumAtoms = AccelSection.getU32(&Offset);
-
- for (unsigned i = 0; i < NumAtoms; ++i) {
- uint16_t AtomType = AccelSection.getU16(&Offset);
- auto AtomForm = static_cast<dwarf::Form>(AccelSection.getU16(&Offset));
- HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
- }
-
- IsValid = true;
- return Error::success();
-}
-
-uint32_t AppleAcceleratorTable::getNumBuckets() { return Hdr.BucketCount; }
-uint32_t AppleAcceleratorTable::getNumHashes() { return Hdr.HashCount; }
-uint32_t AppleAcceleratorTable::getSizeHdr() { return sizeof(Hdr); }
-uint32_t AppleAcceleratorTable::getHeaderDataLength() {
- return Hdr.HeaderDataLength;
-}
-
-ArrayRef<std::pair<AppleAcceleratorTable::HeaderData::AtomType,
- AppleAcceleratorTable::HeaderData::Form>>
-AppleAcceleratorTable::getAtomsDesc() {
- return HdrData.Atoms;
-}
-
-bool AppleAcceleratorTable::validateForms() {
- for (auto Atom : getAtomsDesc()) {
- DWARFFormValue FormValue(Atom.second);
- switch (Atom.first) {
- case dwarf::DW_ATOM_die_offset:
- case dwarf::DW_ATOM_die_tag:
- case dwarf::DW_ATOM_type_flags:
- if ((!FormValue.isFormClass(DWARFFormValue::FC_Constant) &&
- !FormValue.isFormClass(DWARFFormValue::FC_Flag)) ||
- FormValue.getForm() == dwarf::DW_FORM_sdata)
- return false;
- break;
- default:
- break;
- }
- }
- return true;
-}
-
-std::pair<uint64_t, dwarf::Tag>
-AppleAcceleratorTable::readAtoms(uint64_t *HashDataOffset) {
- uint64_t DieOffset = dwarf::DW_INVALID_OFFSET;
- dwarf::Tag DieTag = dwarf::DW_TAG_null;
- dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
-
- for (auto Atom : getAtomsDesc()) {
- DWARFFormValue FormValue(Atom.second);
- FormValue.extractValue(AccelSection, HashDataOffset, FormParams);
- switch (Atom.first) {
- case dwarf::DW_ATOM_die_offset:
- DieOffset = *FormValue.getAsUnsignedConstant();
- break;
- case dwarf::DW_ATOM_die_tag:
- DieTag = (dwarf::Tag)*FormValue.getAsUnsignedConstant();
- break;
- default:
- break;
- }
- }
- return {DieOffset, DieTag};
-}
-
-void AppleAcceleratorTable::Header::dump(ScopedPrinter &W) const {
- DictScope HeaderScope(W, "Header");
- W.printHex("Magic", Magic);
- W.printHex("Version", Version);
- W.printHex("Hash function", HashFunction);
- W.printNumber("Bucket count", BucketCount);
- W.printNumber("Hashes count", HashCount);
- W.printNumber("HeaderData length", HeaderDataLength);
-}
-
-Optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset(
- Optional<DWARFFormValue> Value) const {
- if (!Value)
- return None;
-
- switch (Value->getForm()) {
- case dwarf::DW_FORM_ref1:
- case dwarf::DW_FORM_ref2:
- case dwarf::DW_FORM_ref4:
- case dwarf::DW_FORM_ref8:
- case dwarf::DW_FORM_ref_udata:
- return Value->getRawUValue() + DIEOffsetBase;
- default:
- return Value->getAsSectionOffset();
- }
-}
-
-bool AppleAcceleratorTable::dumpName(ScopedPrinter &W,
- SmallVectorImpl<DWARFFormValue> &AtomForms,
- uint64_t *DataOffset) const {
- dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
- uint64_t NameOffset = *DataOffset;
- if (!AccelSection.isValidOffsetForDataOfSize(*DataOffset, 4)) {
- W.printString("Incorrectly terminated list.");
- return false;
- }
- uint64_t StringOffset = AccelSection.getRelocatedValue(4, DataOffset);
- if (!StringOffset)
- return false; // End of list
-
- DictScope NameScope(W, ("Name@0x" + Twine::utohexstr(NameOffset)).str());
- W.startLine() << format("String: 0x%08" PRIx64, StringOffset);
- W.getOStream() << " \"" << StringSection.getCStr(&StringOffset) << "\"\n";
-
- unsigned NumData = AccelSection.getU32(DataOffset);
- for (unsigned Data = 0; Data < NumData; ++Data) {
- ListScope DataScope(W, ("Data " + Twine(Data)).str());
- unsigned i = 0;
- for (auto &Atom : AtomForms) {
- W.startLine() << format("Atom[%d]: ", i);
- if (Atom.extractValue(AccelSection, DataOffset, FormParams)) {
- Atom.dump(W.getOStream());
- if (Optional<uint64_t> Val = Atom.getAsUnsignedConstant()) {
- StringRef Str = dwarf::AtomValueString(HdrData.Atoms[i].first, *Val);
- if (!Str.empty())
- W.getOStream() << " (" << Str << ")";
- }
- } else
- W.getOStream() << "Error extracting the value";
- W.getOStream() << "\n";
- i++;
- }
- }
- return true; // more entries follow
-}
-
-LLVM_DUMP_METHOD void AppleAcceleratorTable::dump(raw_ostream &OS) const {
- if (!IsValid)
- return;
-
- ScopedPrinter W(OS);
-
- Hdr.dump(W);
-
- W.printNumber("DIE offset base", HdrData.DIEOffsetBase);
- W.printNumber("Number of atoms", uint64_t(HdrData.Atoms.size()));
- SmallVector<DWARFFormValue, 3> AtomForms;
- {
- ListScope AtomsScope(W, "Atoms");
- unsigned i = 0;
- for (const auto &Atom : HdrData.Atoms) {
- DictScope AtomScope(W, ("Atom " + Twine(i++)).str());
- W.startLine() << "Type: " << formatAtom(Atom.first) << '\n';
- W.startLine() << "Form: " << formatv("{0}", Atom.second) << '\n';
- AtomForms.push_back(DWARFFormValue(Atom.second));
- }
- }
-
- // Now go through the actual tables and dump them.
- uint64_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
- uint64_t HashesBase = Offset + Hdr.BucketCount * 4;
- uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
-
- for (unsigned Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket) {
- unsigned Index = AccelSection.getU32(&Offset);
-
- ListScope BucketScope(W, ("Bucket " + Twine(Bucket)).str());
- if (Index == UINT32_MAX) {
- W.printString("EMPTY");
- continue;
- }
-
- for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
- uint64_t HashOffset = HashesBase + HashIdx*4;
- uint64_t OffsetsOffset = OffsetsBase + HashIdx*4;
- uint32_t Hash = AccelSection.getU32(&HashOffset);
-
- if (Hash % Hdr.BucketCount != Bucket)
- break;
-
- uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
- ListScope HashScope(W, ("Hash 0x" + Twine::utohexstr(Hash)).str());
- if (!AccelSection.isValidOffset(DataOffset)) {
- W.printString("Invalid section offset");
- continue;
- }
- while (dumpName(W, AtomForms, &DataOffset))
- /*empty*/;
- }
- }
-}
-
-AppleAcceleratorTable::Entry::Entry(
- const AppleAcceleratorTable::HeaderData &HdrData)
- : HdrData(&HdrData) {
- Values.reserve(HdrData.Atoms.size());
- for (const auto &Atom : HdrData.Atoms)
- Values.push_back(DWARFFormValue(Atom.second));
-}
-
-void AppleAcceleratorTable::Entry::extract(
- const AppleAcceleratorTable &AccelTable, uint64_t *Offset) {
-
- dwarf::FormParams FormParams = {AccelTable.Hdr.Version, 0,
- dwarf::DwarfFormat::DWARF32};
- for (auto &Atom : Values)
- Atom.extractValue(AccelTable.AccelSection, Offset, FormParams);
-}
-
-Optional<DWARFFormValue>
-AppleAcceleratorTable::Entry::lookup(HeaderData::AtomType Atom) const {
- assert(HdrData && "Dereferencing end iterator?");
- assert(HdrData->Atoms.size() == Values.size());
- for (auto Tuple : zip_first(HdrData->Atoms, Values)) {
- if (std::get<0>(Tuple).first == Atom)
- return std::get<1>(Tuple);
- }
- return None;
-}
-
-Optional<uint64_t> AppleAcceleratorTable::Entry::getDIESectionOffset() const {
- return HdrData->extractOffset(lookup(dwarf::DW_ATOM_die_offset));
-}
-
-Optional<uint64_t> AppleAcceleratorTable::Entry::getCUOffset() const {
- return HdrData->extractOffset(lookup(dwarf::DW_ATOM_cu_offset));
-}
-
-Optional<dwarf::Tag> AppleAcceleratorTable::Entry::getTag() const {
- Optional<DWARFFormValue> Tag = lookup(dwarf::DW_ATOM_die_tag);
- if (!Tag)
- return None;
- if (Optional<uint64_t> Value = Tag->getAsUnsignedConstant())
- return dwarf::Tag(*Value);
- return None;
-}
-
-AppleAcceleratorTable::ValueIterator::ValueIterator(
- const AppleAcceleratorTable &AccelTable, uint64_t Offset)
- : AccelTable(&AccelTable), Current(AccelTable.HdrData), DataOffset(Offset) {
- if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
- return;
-
- // Read the first entry.
- NumData = AccelTable.AccelSection.getU32(&DataOffset);
- Next();
-}
-
-void AppleAcceleratorTable::ValueIterator::Next() {
- assert(NumData > 0 && "attempted to increment iterator past the end");
- auto &AccelSection = AccelTable->AccelSection;
- if (Data >= NumData ||
- !AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
- NumData = 0;
- DataOffset = 0;
- return;
- }
- Current.extract(*AccelTable, &DataOffset);
- ++Data;
-}
-
-iterator_range<AppleAcceleratorTable::ValueIterator>
-AppleAcceleratorTable::equal_range(StringRef Key) const {
- if (!IsValid)
- return make_range(ValueIterator(), ValueIterator());
-
- // Find the bucket.
- unsigned HashValue = djbHash(Key);
- unsigned Bucket = HashValue % Hdr.BucketCount;
- uint64_t BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
- uint64_t HashesBase = BucketBase + Hdr.BucketCount * 4;
- uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
-
- uint64_t BucketOffset = BucketBase + Bucket * 4;
- unsigned Index = AccelSection.getU32(&BucketOffset);
-
- // Search through all hashes in the bucket.
- for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
- uint64_t HashOffset = HashesBase + HashIdx * 4;
- uint64_t OffsetsOffset = OffsetsBase + HashIdx * 4;
- uint32_t Hash = AccelSection.getU32(&HashOffset);
-
- if (Hash % Hdr.BucketCount != Bucket)
- // We are already in the next bucket.
- break;
-
- uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
- uint64_t StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
- if (!StringOffset)
- break;
-
- // Finally, compare the key.
- if (Key == StringSection.getCStr(&StringOffset))
- return make_range({*this, DataOffset}, ValueIterator());
- }
- return make_range(ValueIterator(), ValueIterator());
-}
-
-void DWARFDebugNames::Header::dump(ScopedPrinter &W) const {
- DictScope HeaderScope(W, "Header");
- W.printHex("Length", UnitLength);
- W.printString("Format", dwarf::FormatString(Format));
- W.printNumber("Version", Version);
- W.printNumber("CU count", CompUnitCount);
- W.printNumber("Local TU count", LocalTypeUnitCount);
- W.printNumber("Foreign TU count", ForeignTypeUnitCount);
- W.printNumber("Bucket count", BucketCount);
- W.printNumber("Name count", NameCount);
- W.printHex("Abbreviations table size", AbbrevTableSize);
- W.startLine() << "Augmentation: '" << AugmentationString << "'\n";
-}
-
-Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
- uint64_t *Offset) {
- auto HeaderError = [Offset = *Offset](Error E) {
- return createStringError(errc::illegal_byte_sequence,
- "parsing .debug_names header at 0x%" PRIx64 ": %s",
- Offset, toString(std::move(E)).c_str());
- };
-
- DataExtractor::Cursor C(*Offset);
- std::tie(UnitLength, Format) = AS.getInitialLength(C);
-
- Version = AS.getU16(C);
- AS.skip(C, 2); // padding
- CompUnitCount = AS.getU32(C);
- LocalTypeUnitCount = AS.getU32(C);
- ForeignTypeUnitCount = AS.getU32(C);
- BucketCount = AS.getU32(C);
- NameCount = AS.getU32(C);
- AbbrevTableSize = AS.getU32(C);
- AugmentationStringSize = alignTo(AS.getU32(C), 4);
-
- if (!C)
- return HeaderError(C.takeError());
-
- if (!AS.isValidOffsetForDataOfSize(C.tell(), AugmentationStringSize))
- return HeaderError(createStringError(errc::illegal_byte_sequence,
- "cannot read header augmentation"));
- AugmentationString.resize(AugmentationStringSize);
- AS.getU8(C, reinterpret_cast<uint8_t *>(AugmentationString.data()),
- AugmentationStringSize);
- *Offset = C.tell();
- return C.takeError();
-}
-
-void DWARFDebugNames::Abbrev::dump(ScopedPrinter &W) const {
- DictScope AbbrevScope(W, ("Abbreviation 0x" + Twine::utohexstr(Code)).str());
- W.startLine() << formatv("Tag: {0}\n", Tag);
-
- for (const auto &Attr : Attributes)
- W.startLine() << formatv("{0}: {1}\n", Attr.Index, Attr.Form);
-}
-
-static constexpr DWARFDebugNames::AttributeEncoding sentinelAttrEnc() {
- return {dwarf::Index(0), dwarf::Form(0)};
-}
-
-static bool isSentinel(const DWARFDebugNames::AttributeEncoding &AE) {
- return AE == sentinelAttrEnc();
-}
-
-static DWARFDebugNames::Abbrev sentinelAbbrev() {
- return DWARFDebugNames::Abbrev(0, dwarf::Tag(0), {});
-}
-
-static bool isSentinel(const DWARFDebugNames::Abbrev &Abbr) {
- return Abbr.Code == 0;
-}
-
-DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getEmptyKey() {
- return sentinelAbbrev();
-}
-
-DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getTombstoneKey() {
- return DWARFDebugNames::Abbrev(~0, dwarf::Tag(0), {});
-}
-
-Expected<DWARFDebugNames::AttributeEncoding>
-DWARFDebugNames::NameIndex::extractAttributeEncoding(uint64_t *Offset) {
- if (*Offset >= EntriesBase) {
- return createStringError(errc::illegal_byte_sequence,
- "Incorrectly terminated abbreviation table.");
- }
-
- uint32_t Index = Section.AccelSection.getULEB128(Offset);
- uint32_t Form = Section.AccelSection.getULEB128(Offset);
- return AttributeEncoding(dwarf::Index(Index), dwarf::Form(Form));
-}
-
-Expected<std::vector<DWARFDebugNames::AttributeEncoding>>
-DWARFDebugNames::NameIndex::extractAttributeEncodings(uint64_t *Offset) {
- std::vector<AttributeEncoding> Result;
- for (;;) {
- auto AttrEncOr = extractAttributeEncoding(Offset);
- if (!AttrEncOr)
- return AttrEncOr.takeError();
- if (isSentinel(*AttrEncOr))
- return std::move(Result);
-
- Result.emplace_back(*AttrEncOr);
- }
-}
-
-Expected<DWARFDebugNames::Abbrev>
-DWARFDebugNames::NameIndex::extractAbbrev(uint64_t *Offset) {
- if (*Offset >= EntriesBase) {
- return createStringError(errc::illegal_byte_sequence,
- "Incorrectly terminated abbreviation table.");
- }
-
- uint32_t Code = Section.AccelSection.getULEB128(Offset);
- if (Code == 0)
- return sentinelAbbrev();
-
- uint32_t Tag = Section.AccelSection.getULEB128(Offset);
- auto AttrEncOr = extractAttributeEncodings(Offset);
- if (!AttrEncOr)
- return AttrEncOr.takeError();
- return Abbrev(Code, dwarf::Tag(Tag), std::move(*AttrEncOr));
-}
-
-Error DWARFDebugNames::NameIndex::extract() {
- const DWARFDataExtractor &AS = Section.AccelSection;
- uint64_t Offset = Base;
- if (Error E = Hdr.extract(AS, &Offset))
- return E;
-
- const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
- CUsBase = Offset;
- Offset += Hdr.CompUnitCount * SectionOffsetSize;
- Offset += Hdr.LocalTypeUnitCount * SectionOffsetSize;
- Offset += Hdr.ForeignTypeUnitCount * 8;
- BucketsBase = Offset;
- Offset += Hdr.BucketCount * 4;
- HashesBase = Offset;
- if (Hdr.BucketCount > 0)
- Offset += Hdr.NameCount * 4;
- StringOffsetsBase = Offset;
- Offset += Hdr.NameCount * SectionOffsetSize;
- EntryOffsetsBase = Offset;
- Offset += Hdr.NameCount * SectionOffsetSize;
-
- if (!AS.isValidOffsetForDataOfSize(Offset, Hdr.AbbrevTableSize))
- return createStringError(errc::illegal_byte_sequence,
- "Section too small: cannot read abbreviations.");
-
- EntriesBase = Offset + Hdr.AbbrevTableSize;
-
- for (;;) {
- auto AbbrevOr = extractAbbrev(&Offset);
- if (!AbbrevOr)
- return AbbrevOr.takeError();
- if (isSentinel(*AbbrevOr))
- return Error::success();
-
- if (!Abbrevs.insert(std::move(*AbbrevOr)).second)
- return createStringError(errc::invalid_argument,
- "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
- // (NameIndex::getEntry) to populate them.
- Values.reserve(Abbr.Attributes.size());
- for (const auto &Attr : Abbr.Attributes)
- Values.emplace_back(Attr.Form);
-}
-
-Optional<DWARFFormValue>
-DWARFDebugNames::Entry::lookup(dwarf::Index Index) const {
- assert(Abbr->Attributes.size() == Values.size());
- for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
- if (std::get<0>(Tuple).Index == Index)
- return std::get<1>(Tuple);
- }
- return None;
-}
-
-Optional<uint64_t> DWARFDebugNames::Entry::getDIEUnitOffset() const {
- if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_die_offset))
- return Off->getAsReferenceUVal();
- return None;
-}
-
-Optional<uint64_t> DWARFDebugNames::Entry::getCUIndex() const {
- if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit))
- return Off->getAsUnsignedConstant();
- // In a per-CU index, the entries without a DW_IDX_compile_unit attribute
- // implicitly refer to the single CU.
- if (NameIdx->getCUCount() == 1)
- return 0;
- return None;
-}
-
-Optional<uint64_t> DWARFDebugNames::Entry::getCUOffset() const {
- Optional<uint64_t> Index = getCUIndex();
- if (!Index || *Index >= NameIdx->getCUCount())
- return None;
- return NameIdx->getCUOffset(*Index);
-}
-
-void DWARFDebugNames::Entry::dump(ScopedPrinter &W) const {
- W.printHex("Abbrev", Abbr->Code);
- W.startLine() << formatv("Tag: {0}\n", Abbr->Tag);
- assert(Abbr->Attributes.size() == Values.size());
- for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
- W.startLine() << formatv("{0}: ", std::get<0>(Tuple).Index);
- std::get<1>(Tuple).dump(W.getOStream());
- W.getOStream() << '\n';
- }
-}
-
-char DWARFDebugNames::SentinelError::ID;
-std::error_code DWARFDebugNames::SentinelError::convertToErrorCode() const {
- return inconvertibleErrorCode();
-}
-
-uint64_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const {
- assert(CU < Hdr.CompUnitCount);
- const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
- uint64_t Offset = CUsBase + SectionOffsetSize * CU;
- return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
-}
-
-uint64_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const {
- assert(TU < Hdr.LocalTypeUnitCount);
- const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
- uint64_t Offset = CUsBase + SectionOffsetSize * (Hdr.CompUnitCount + TU);
- return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
-}
-
-uint64_t DWARFDebugNames::NameIndex::getForeignTUSignature(uint32_t TU) const {
- assert(TU < Hdr.ForeignTypeUnitCount);
- const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
- uint64_t Offset =
- CUsBase +
- SectionOffsetSize * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU;
- return Section.AccelSection.getU64(&Offset);
-}
-
-Expected<DWARFDebugNames::Entry>
-DWARFDebugNames::NameIndex::getEntry(uint64_t *Offset) const {
- const DWARFDataExtractor &AS = Section.AccelSection;
- if (!AS.isValidOffset(*Offset))
- return createStringError(errc::illegal_byte_sequence,
- "Incorrectly terminated entry list.");
-
- uint32_t AbbrevCode = AS.getULEB128(Offset);
- if (AbbrevCode == 0)
- return make_error<SentinelError>();
-
- const auto AbbrevIt = Abbrevs.find_as(AbbrevCode);
- if (AbbrevIt == Abbrevs.end())
- return createStringError(errc::invalid_argument, "Invalid abbreviation.");
-
- Entry E(*this, *AbbrevIt);
-
- dwarf::FormParams FormParams = {Hdr.Version, 0, Hdr.Format};
- for (auto &Value : E.Values) {
- if (!Value.extractValue(AS, Offset, FormParams))
- return createStringError(errc::io_error,
- "Error extracting index attribute values.");
- }
- return std::move(E);
-}
-
-DWARFDebugNames::NameTableEntry
-DWARFDebugNames::NameIndex::getNameTableEntry(uint32_t Index) const {
- assert(0 < Index && Index <= Hdr.NameCount);
- const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
- uint64_t StringOffsetOffset =
- StringOffsetsBase + SectionOffsetSize * (Index - 1);
- uint64_t EntryOffsetOffset =
- EntryOffsetsBase + SectionOffsetSize * (Index - 1);
- const DWARFDataExtractor &AS = Section.AccelSection;
-
- uint64_t StringOffset =
- AS.getRelocatedValue(SectionOffsetSize, &StringOffsetOffset);
- uint64_t EntryOffset = AS.getUnsigned(&EntryOffsetOffset, SectionOffsetSize);
- EntryOffset += EntriesBase;
- return {Section.StringSection, Index, StringOffset, EntryOffset};
-}
-
-uint32_t
-DWARFDebugNames::NameIndex::getBucketArrayEntry(uint32_t Bucket) const {
- assert(Bucket < Hdr.BucketCount);
- uint64_t BucketOffset = BucketsBase + 4 * Bucket;
- return Section.AccelSection.getU32(&BucketOffset);
-}
-
-uint32_t DWARFDebugNames::NameIndex::getHashArrayEntry(uint32_t Index) const {
- assert(0 < Index && Index <= Hdr.NameCount);
- uint64_t HashOffset = HashesBase + 4 * (Index - 1);
- return Section.AccelSection.getU32(&HashOffset);
-}
-
-// Returns true if we should continue scanning for entries, false if this is the
-// last (sentinel) entry). In case of a parsing error we also return false, as
-// it's not possible to recover this entry list (but the other lists may still
-// parse OK).
-bool DWARFDebugNames::NameIndex::dumpEntry(ScopedPrinter &W,
- uint64_t *Offset) const {
- uint64_t EntryId = *Offset;
- auto EntryOr = getEntry(Offset);
- if (!EntryOr) {
- handleAllErrors(EntryOr.takeError(), [](const SentinelError &) {},
- [&W](const ErrorInfoBase &EI) { EI.log(W.startLine()); });
- return false;
- }
-
- DictScope EntryScope(W, ("Entry @ 0x" + Twine::utohexstr(EntryId)).str());
- EntryOr->dump(W);
- return true;
-}
-
-void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W,
- const NameTableEntry &NTE,
- Optional<uint32_t> Hash) const {
- DictScope NameScope(W, ("Name " + Twine(NTE.getIndex())).str());
- if (Hash)
- W.printHex("Hash", *Hash);
-
- W.startLine() << format("String: 0x%08" PRIx64, NTE.getStringOffset());
- W.getOStream() << " \"" << NTE.getString() << "\"\n";
-
- uint64_t EntryOffset = NTE.getEntryOffset();
- while (dumpEntry(W, &EntryOffset))
- /*empty*/;
-}
-
-void DWARFDebugNames::NameIndex::dumpCUs(ScopedPrinter &W) const {
- ListScope CUScope(W, "Compilation Unit offsets");
- for (uint32_t CU = 0; CU < Hdr.CompUnitCount; ++CU)
- W.startLine() << format("CU[%u]: 0x%08" PRIx64 "\n", CU, getCUOffset(CU));
-}
-
-void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const {
- if (Hdr.LocalTypeUnitCount == 0)
- return;
-
- ListScope TUScope(W, "Local Type Unit offsets");
- for (uint32_t TU = 0; TU < Hdr.LocalTypeUnitCount; ++TU)
- W.startLine() << format("LocalTU[%u]: 0x%08" PRIx64 "\n", TU,
- getLocalTUOffset(TU));
-}
-
-void DWARFDebugNames::NameIndex::dumpForeignTUs(ScopedPrinter &W) const {
- if (Hdr.ForeignTypeUnitCount == 0)
- return;
-
- ListScope TUScope(W, "Foreign Type Unit signatures");
- for (uint32_t TU = 0; TU < Hdr.ForeignTypeUnitCount; ++TU) {
- W.startLine() << format("ForeignTU[%u]: 0x%016" PRIx64 "\n", TU,
- getForeignTUSignature(TU));
- }
-}
-
-void DWARFDebugNames::NameIndex::dumpAbbreviations(ScopedPrinter &W) const {
- ListScope AbbrevsScope(W, "Abbreviations");
- for (const auto &Abbr : Abbrevs)
- Abbr.dump(W);
-}
-
-void DWARFDebugNames::NameIndex::dumpBucket(ScopedPrinter &W,
- uint32_t Bucket) const {
- ListScope BucketScope(W, ("Bucket " + Twine(Bucket)).str());
- uint32_t Index = getBucketArrayEntry(Bucket);
- if (Index == 0) {
- W.printString("EMPTY");
- return;
- }
- if (Index > Hdr.NameCount) {
- W.printString("Name index is invalid");
- return;
- }
-
- for (; Index <= Hdr.NameCount; ++Index) {
- uint32_t Hash = getHashArrayEntry(Index);
- if (Hash % Hdr.BucketCount != Bucket)
- break;
-
- dumpName(W, getNameTableEntry(Index), Hash);
- }
-}
-
-LLVM_DUMP_METHOD void DWARFDebugNames::NameIndex::dump(ScopedPrinter &W) const {
- DictScope UnitScope(W, ("Name Index @ 0x" + Twine::utohexstr(Base)).str());
- Hdr.dump(W);
- dumpCUs(W);
- dumpLocalTUs(W);
- dumpForeignTUs(W);
- dumpAbbreviations(W);
-
- if (Hdr.BucketCount > 0) {
- for (uint32_t Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket)
- dumpBucket(W, Bucket);
- return;
- }
-
- W.startLine() << "Hash table not present\n";
- for (NameTableEntry NTE : *this)
- dumpName(W, NTE, None);
-}
-
-Error DWARFDebugNames::extract() {
- uint64_t Offset = 0;
- while (AccelSection.isValidOffset(Offset)) {
- NameIndex Next(*this, Offset);
- if (Error E = Next.extract())
- return E;
- Offset = Next.getNextUnitOffset();
- NameIndices.push_back(std::move(Next));
- }
- return Error::success();
-}
-
-iterator_range<DWARFDebugNames::ValueIterator>
-DWARFDebugNames::NameIndex::equal_range(StringRef Key) const {
- return make_range(ValueIterator(*this, Key), ValueIterator());
-}
-
-LLVM_DUMP_METHOD void DWARFDebugNames::dump(raw_ostream &OS) const {
- ScopedPrinter W(OS);
- for (const NameIndex &NI : NameIndices)
- NI.dump(W);
-}
-
-Optional<uint64_t>
-DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() {
- const Header &Hdr = CurrentIndex->Hdr;
- if (Hdr.BucketCount == 0) {
- // No Hash Table, We need to search through all names in the Name Index.
- for (NameTableEntry NTE : *CurrentIndex) {
- if (NTE.getString() == Key)
- return NTE.getEntryOffset();
- }
- return None;
- }
-
- // The Name Index has a Hash Table, so use that to speed up the search.
- // Compute the Key Hash, if it has not been done already.
- if (!Hash)
- Hash = caseFoldingDjbHash(Key);
- uint32_t Bucket = *Hash % Hdr.BucketCount;
- uint32_t Index = CurrentIndex->getBucketArrayEntry(Bucket);
- if (Index == 0)
- return None; // Empty bucket
-
- for (; Index <= Hdr.NameCount; ++Index) {
- uint32_t Hash = CurrentIndex->getHashArrayEntry(Index);
- if (Hash % Hdr.BucketCount != Bucket)
- return None; // End of bucket
-
- NameTableEntry NTE = CurrentIndex->getNameTableEntry(Index);
- if (NTE.getString() == Key)
- return NTE.getEntryOffset();
- }
- return None;
-}
-
-bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() {
- auto EntryOr = CurrentIndex->getEntry(&DataOffset);
- if (!EntryOr) {
- consumeError(EntryOr.takeError());
- return false;
- }
- CurrentEntry = std::move(*EntryOr);
- return true;
-}
-
-bool DWARFDebugNames::ValueIterator::findInCurrentIndex() {
- Optional<uint64_t> Offset = findEntryOffsetInCurrentIndex();
- if (!Offset)
- return false;
- DataOffset = *Offset;
- return getEntryAtCurrentOffset();
-}
-
-void DWARFDebugNames::ValueIterator::searchFromStartOfCurrentIndex() {
- for (const NameIndex *End = CurrentIndex->Section.NameIndices.end();
- CurrentIndex != End; ++CurrentIndex) {
- if (findInCurrentIndex())
- return;
- }
- setEnd();
-}
-
-void DWARFDebugNames::ValueIterator::next() {
- assert(CurrentIndex && "Incrementing an end() iterator?");
-
- // First try the next entry in the current Index.
- if (getEntryAtCurrentOffset())
- return;
-
- // If we're a local iterator or we have reached the last Index, we're done.
- if (IsLocal || CurrentIndex == &CurrentIndex->Section.NameIndices.back()) {
- setEnd();
- return;
- }
-
- // Otherwise, try the next index.
- ++CurrentIndex;
- searchFromStartOfCurrentIndex();
-}
-
-DWARFDebugNames::ValueIterator::ValueIterator(const DWARFDebugNames &AccelTable,
- StringRef Key)
- : CurrentIndex(AccelTable.NameIndices.begin()), IsLocal(false),
- Key(std::string(Key)) {
- searchFromStartOfCurrentIndex();
-}
-
-DWARFDebugNames::ValueIterator::ValueIterator(
- const DWARFDebugNames::NameIndex &NI, StringRef Key)
- : CurrentIndex(&NI), IsLocal(true), Key(std::string(Key)) {
- if (!findInCurrentIndex())
- setEnd();
-}
-
-iterator_range<DWARFDebugNames::ValueIterator>
-DWARFDebugNames::equal_range(StringRef Key) const {
- if (NameIndices.empty())
- return make_range(ValueIterator(), ValueIterator());
- return make_range(ValueIterator(*this, Key), ValueIterator());
-}
-
-const DWARFDebugNames::NameIndex *
-DWARFDebugNames::getCUNameIndex(uint64_t CUOffset) {
- if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) {
- for (const auto &NI : *this) {
- for (uint32_t CU = 0; CU < NI.getCUCount(); ++CU)
- CUToNameIndex.try_emplace(NI.getCUOffset(CU), &NI);
- }
- }
- return CUToNameIndex.lookup(CUOffset);
-}
+//===- DWARFAcceleratorTable.cpp ------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DJB.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstddef>
+#include <cstdint>
+#include <utility>
+
+using namespace llvm;
+
+namespace {
+struct Atom {
+ unsigned Value;
+};
+
+static raw_ostream &operator<<(raw_ostream &OS, const Atom &A) {
+ StringRef Str = dwarf::AtomTypeString(A.Value);
+ if (!Str.empty())
+ return OS << Str;
+ return OS << "DW_ATOM_unknown_" << format("%x", A.Value);
+}
+} // namespace
+
+static Atom formatAtom(unsigned Atom) { return {Atom}; }
+
+DWARFAcceleratorTable::~DWARFAcceleratorTable() = default;
+
+Error AppleAcceleratorTable::extract() {
+ uint64_t Offset = 0;
+
+ // Check that we can at least read the header.
+ if (!AccelSection.isValidOffset(offsetof(Header, HeaderDataLength) + 4))
+ return createStringError(errc::illegal_byte_sequence,
+ "Section too small: cannot read header.");
+
+ Hdr.Magic = AccelSection.getU32(&Offset);
+ Hdr.Version = AccelSection.getU16(&Offset);
+ Hdr.HashFunction = AccelSection.getU16(&Offset);
+ Hdr.BucketCount = AccelSection.getU32(&Offset);
+ Hdr.HashCount = AccelSection.getU32(&Offset);
+ Hdr.HeaderDataLength = AccelSection.getU32(&Offset);
+
+ // Check that we can read all the hashes and offsets from the
+ // section (see SourceLevelDebugging.rst for the structure of the index).
+ // We need to substract one because we're checking for an *offset* which is
+ // equal to the size for an empty table and hence pointer after the section.
+ if (!AccelSection.isValidOffset(sizeof(Hdr) + Hdr.HeaderDataLength +
+ Hdr.BucketCount * 4 + Hdr.HashCount * 8 - 1))
+ return createStringError(
+ errc::illegal_byte_sequence,
+ "Section too small: cannot read buckets and hashes.");
+
+ HdrData.DIEOffsetBase = AccelSection.getU32(&Offset);
+ uint32_t NumAtoms = AccelSection.getU32(&Offset);
+
+ for (unsigned i = 0; i < NumAtoms; ++i) {
+ uint16_t AtomType = AccelSection.getU16(&Offset);
+ auto AtomForm = static_cast<dwarf::Form>(AccelSection.getU16(&Offset));
+ HdrData.Atoms.push_back(std::make_pair(AtomType, AtomForm));
+ }
+
+ IsValid = true;
+ return Error::success();
+}
+
+uint32_t AppleAcceleratorTable::getNumBuckets() { return Hdr.BucketCount; }
+uint32_t AppleAcceleratorTable::getNumHashes() { return Hdr.HashCount; }
+uint32_t AppleAcceleratorTable::getSizeHdr() { return sizeof(Hdr); }
+uint32_t AppleAcceleratorTable::getHeaderDataLength() {
+ return Hdr.HeaderDataLength;
+}
+
+ArrayRef<std::pair<AppleAcceleratorTable::HeaderData::AtomType,
+ AppleAcceleratorTable::HeaderData::Form>>
+AppleAcceleratorTable::getAtomsDesc() {
+ return HdrData.Atoms;
+}
+
+bool AppleAcceleratorTable::validateForms() {
+ for (auto Atom : getAtomsDesc()) {
+ DWARFFormValue FormValue(Atom.second);
+ switch (Atom.first) {
+ case dwarf::DW_ATOM_die_offset:
+ case dwarf::DW_ATOM_die_tag:
+ case dwarf::DW_ATOM_type_flags:
+ if ((!FormValue.isFormClass(DWARFFormValue::FC_Constant) &&
+ !FormValue.isFormClass(DWARFFormValue::FC_Flag)) ||
+ FormValue.getForm() == dwarf::DW_FORM_sdata)
+ return false;
+ break;
+ default:
+ break;
+ }
+ }
+ return true;
+}
+
+std::pair<uint64_t, dwarf::Tag>
+AppleAcceleratorTable::readAtoms(uint64_t *HashDataOffset) {
+ uint64_t DieOffset = dwarf::DW_INVALID_OFFSET;
+ dwarf::Tag DieTag = dwarf::DW_TAG_null;
+ dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
+
+ for (auto Atom : getAtomsDesc()) {
+ DWARFFormValue FormValue(Atom.second);
+ FormValue.extractValue(AccelSection, HashDataOffset, FormParams);
+ switch (Atom.first) {
+ case dwarf::DW_ATOM_die_offset:
+ DieOffset = *FormValue.getAsUnsignedConstant();
+ break;
+ case dwarf::DW_ATOM_die_tag:
+ DieTag = (dwarf::Tag)*FormValue.getAsUnsignedConstant();
+ break;
+ default:
+ break;
+ }
+ }
+ return {DieOffset, DieTag};
+}
+
+void AppleAcceleratorTable::Header::dump(ScopedPrinter &W) const {
+ DictScope HeaderScope(W, "Header");
+ W.printHex("Magic", Magic);
+ W.printHex("Version", Version);
+ W.printHex("Hash function", HashFunction);
+ W.printNumber("Bucket count", BucketCount);
+ W.printNumber("Hashes count", HashCount);
+ W.printNumber("HeaderData length", HeaderDataLength);
+}
+
+Optional<uint64_t> AppleAcceleratorTable::HeaderData::extractOffset(
+ Optional<DWARFFormValue> Value) const {
+ if (!Value)
+ return None;
+
+ switch (Value->getForm()) {
+ case dwarf::DW_FORM_ref1:
+ case dwarf::DW_FORM_ref2:
+ case dwarf::DW_FORM_ref4:
+ case dwarf::DW_FORM_ref8:
+ case dwarf::DW_FORM_ref_udata:
+ return Value->getRawUValue() + DIEOffsetBase;
+ default:
+ return Value->getAsSectionOffset();
+ }
+}
+
+bool AppleAcceleratorTable::dumpName(ScopedPrinter &W,
+ SmallVectorImpl<DWARFFormValue> &AtomForms,
+ uint64_t *DataOffset) const {
+ dwarf::FormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32};
+ uint64_t NameOffset = *DataOffset;
+ if (!AccelSection.isValidOffsetForDataOfSize(*DataOffset, 4)) {
+ W.printString("Incorrectly terminated list.");
+ return false;
+ }
+ uint64_t StringOffset = AccelSection.getRelocatedValue(4, DataOffset);
+ if (!StringOffset)
+ return false; // End of list
+
+ DictScope NameScope(W, ("Name@0x" + Twine::utohexstr(NameOffset)).str());
+ W.startLine() << format("String: 0x%08" PRIx64, StringOffset);
+ W.getOStream() << " \"" << StringSection.getCStr(&StringOffset) << "\"\n";
+
+ unsigned NumData = AccelSection.getU32(DataOffset);
+ for (unsigned Data = 0; Data < NumData; ++Data) {
+ ListScope DataScope(W, ("Data " + Twine(Data)).str());
+ unsigned i = 0;
+ for (auto &Atom : AtomForms) {
+ W.startLine() << format("Atom[%d]: ", i);
+ if (Atom.extractValue(AccelSection, DataOffset, FormParams)) {
+ Atom.dump(W.getOStream());
+ if (Optional<uint64_t> Val = Atom.getAsUnsignedConstant()) {
+ StringRef Str = dwarf::AtomValueString(HdrData.Atoms[i].first, *Val);
+ if (!Str.empty())
+ W.getOStream() << " (" << Str << ")";
+ }
+ } else
+ W.getOStream() << "Error extracting the value";
+ W.getOStream() << "\n";
+ i++;
+ }
+ }
+ return true; // more entries follow
+}
+
+LLVM_DUMP_METHOD void AppleAcceleratorTable::dump(raw_ostream &OS) const {
+ if (!IsValid)
+ return;
+
+ ScopedPrinter W(OS);
+
+ Hdr.dump(W);
+
+ W.printNumber("DIE offset base", HdrData.DIEOffsetBase);
+ W.printNumber("Number of atoms", uint64_t(HdrData.Atoms.size()));
+ SmallVector<DWARFFormValue, 3> AtomForms;
+ {
+ ListScope AtomsScope(W, "Atoms");
+ unsigned i = 0;
+ for (const auto &Atom : HdrData.Atoms) {
+ DictScope AtomScope(W, ("Atom " + Twine(i++)).str());
+ W.startLine() << "Type: " << formatAtom(Atom.first) << '\n';
+ W.startLine() << "Form: " << formatv("{0}", Atom.second) << '\n';
+ AtomForms.push_back(DWARFFormValue(Atom.second));
+ }
+ }
+
+ // Now go through the actual tables and dump them.
+ uint64_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength;
+ uint64_t HashesBase = Offset + Hdr.BucketCount * 4;
+ uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
+
+ for (unsigned Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket) {
+ unsigned Index = AccelSection.getU32(&Offset);
+
+ ListScope BucketScope(W, ("Bucket " + Twine(Bucket)).str());
+ if (Index == UINT32_MAX) {
+ W.printString("EMPTY");
+ continue;
+ }
+
+ for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
+ uint64_t HashOffset = HashesBase + HashIdx*4;
+ uint64_t OffsetsOffset = OffsetsBase + HashIdx*4;
+ uint32_t Hash = AccelSection.getU32(&HashOffset);
+
+ if (Hash % Hdr.BucketCount != Bucket)
+ break;
+
+ uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
+ ListScope HashScope(W, ("Hash 0x" + Twine::utohexstr(Hash)).str());
+ if (!AccelSection.isValidOffset(DataOffset)) {
+ W.printString("Invalid section offset");
+ continue;
+ }
+ while (dumpName(W, AtomForms, &DataOffset))
+ /*empty*/;
+ }
+ }
+}
+
+AppleAcceleratorTable::Entry::Entry(
+ const AppleAcceleratorTable::HeaderData &HdrData)
+ : HdrData(&HdrData) {
+ Values.reserve(HdrData.Atoms.size());
+ for (const auto &Atom : HdrData.Atoms)
+ Values.push_back(DWARFFormValue(Atom.second));
+}
+
+void AppleAcceleratorTable::Entry::extract(
+ const AppleAcceleratorTable &AccelTable, uint64_t *Offset) {
+
+ dwarf::FormParams FormParams = {AccelTable.Hdr.Version, 0,
+ dwarf::DwarfFormat::DWARF32};
+ for (auto &Atom : Values)
+ Atom.extractValue(AccelTable.AccelSection, Offset, FormParams);
+}
+
+Optional<DWARFFormValue>
+AppleAcceleratorTable::Entry::lookup(HeaderData::AtomType Atom) const {
+ assert(HdrData && "Dereferencing end iterator?");
+ assert(HdrData->Atoms.size() == Values.size());
+ for (auto Tuple : zip_first(HdrData->Atoms, Values)) {
+ if (std::get<0>(Tuple).first == Atom)
+ return std::get<1>(Tuple);
+ }
+ return None;
+}
+
+Optional<uint64_t> AppleAcceleratorTable::Entry::getDIESectionOffset() const {
+ return HdrData->extractOffset(lookup(dwarf::DW_ATOM_die_offset));
+}
+
+Optional<uint64_t> AppleAcceleratorTable::Entry::getCUOffset() const {
+ return HdrData->extractOffset(lookup(dwarf::DW_ATOM_cu_offset));
+}
+
+Optional<dwarf::Tag> AppleAcceleratorTable::Entry::getTag() const {
+ Optional<DWARFFormValue> Tag = lookup(dwarf::DW_ATOM_die_tag);
+ if (!Tag)
+ return None;
+ if (Optional<uint64_t> Value = Tag->getAsUnsignedConstant())
+ return dwarf::Tag(*Value);
+ return None;
+}
+
+AppleAcceleratorTable::ValueIterator::ValueIterator(
+ const AppleAcceleratorTable &AccelTable, uint64_t Offset)
+ : AccelTable(&AccelTable), Current(AccelTable.HdrData), DataOffset(Offset) {
+ if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4))
+ return;
+
+ // Read the first entry.
+ NumData = AccelTable.AccelSection.getU32(&DataOffset);
+ Next();
+}
+
+void AppleAcceleratorTable::ValueIterator::Next() {
+ assert(NumData > 0 && "attempted to increment iterator past the end");
+ auto &AccelSection = AccelTable->AccelSection;
+ if (Data >= NumData ||
+ !AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) {
+ NumData = 0;
+ DataOffset = 0;
+ return;
+ }
+ Current.extract(*AccelTable, &DataOffset);
+ ++Data;
+}
+
+iterator_range<AppleAcceleratorTable::ValueIterator>
+AppleAcceleratorTable::equal_range(StringRef Key) const {
+ if (!IsValid)
+ return make_range(ValueIterator(), ValueIterator());
+
+ // Find the bucket.
+ unsigned HashValue = djbHash(Key);
+ unsigned Bucket = HashValue % Hdr.BucketCount;
+ uint64_t BucketBase = sizeof(Hdr) + Hdr.HeaderDataLength;
+ uint64_t HashesBase = BucketBase + Hdr.BucketCount * 4;
+ uint64_t OffsetsBase = HashesBase + Hdr.HashCount * 4;
+
+ uint64_t BucketOffset = BucketBase + Bucket * 4;
+ unsigned Index = AccelSection.getU32(&BucketOffset);
+
+ // Search through all hashes in the bucket.
+ for (unsigned HashIdx = Index; HashIdx < Hdr.HashCount; ++HashIdx) {
+ uint64_t HashOffset = HashesBase + HashIdx * 4;
+ uint64_t OffsetsOffset = OffsetsBase + HashIdx * 4;
+ uint32_t Hash = AccelSection.getU32(&HashOffset);
+
+ if (Hash % Hdr.BucketCount != Bucket)
+ // We are already in the next bucket.
+ break;
+
+ uint64_t DataOffset = AccelSection.getU32(&OffsetsOffset);
+ uint64_t StringOffset = AccelSection.getRelocatedValue(4, &DataOffset);
+ if (!StringOffset)
+ break;
+
+ // Finally, compare the key.
+ if (Key == StringSection.getCStr(&StringOffset))
+ return make_range({*this, DataOffset}, ValueIterator());
+ }
+ return make_range(ValueIterator(), ValueIterator());
+}
+
+void DWARFDebugNames::Header::dump(ScopedPrinter &W) const {
+ DictScope HeaderScope(W, "Header");
+ W.printHex("Length", UnitLength);
+ W.printString("Format", dwarf::FormatString(Format));
+ W.printNumber("Version", Version);
+ W.printNumber("CU count", CompUnitCount);
+ W.printNumber("Local TU count", LocalTypeUnitCount);
+ W.printNumber("Foreign TU count", ForeignTypeUnitCount);
+ W.printNumber("Bucket count", BucketCount);
+ W.printNumber("Name count", NameCount);
+ W.printHex("Abbreviations table size", AbbrevTableSize);
+ W.startLine() << "Augmentation: '" << AugmentationString << "'\n";
+}
+
+Error DWARFDebugNames::Header::extract(const DWARFDataExtractor &AS,
+ uint64_t *Offset) {
+ auto HeaderError = [Offset = *Offset](Error E) {
+ return createStringError(errc::illegal_byte_sequence,
+ "parsing .debug_names header at 0x%" PRIx64 ": %s",
+ Offset, toString(std::move(E)).c_str());
+ };
+
+ DataExtractor::Cursor C(*Offset);
+ std::tie(UnitLength, Format) = AS.getInitialLength(C);
+
+ Version = AS.getU16(C);
+ AS.skip(C, 2); // padding
+ CompUnitCount = AS.getU32(C);
+ LocalTypeUnitCount = AS.getU32(C);
+ ForeignTypeUnitCount = AS.getU32(C);
+ BucketCount = AS.getU32(C);
+ NameCount = AS.getU32(C);
+ AbbrevTableSize = AS.getU32(C);
+ AugmentationStringSize = alignTo(AS.getU32(C), 4);
+
+ if (!C)
+ return HeaderError(C.takeError());
+
+ if (!AS.isValidOffsetForDataOfSize(C.tell(), AugmentationStringSize))
+ return HeaderError(createStringError(errc::illegal_byte_sequence,
+ "cannot read header augmentation"));
+ AugmentationString.resize(AugmentationStringSize);
+ AS.getU8(C, reinterpret_cast<uint8_t *>(AugmentationString.data()),
+ AugmentationStringSize);
+ *Offset = C.tell();
+ return C.takeError();
+}
+
+void DWARFDebugNames::Abbrev::dump(ScopedPrinter &W) const {
+ DictScope AbbrevScope(W, ("Abbreviation 0x" + Twine::utohexstr(Code)).str());
+ W.startLine() << formatv("Tag: {0}\n", Tag);
+
+ for (const auto &Attr : Attributes)
+ W.startLine() << formatv("{0}: {1}\n", Attr.Index, Attr.Form);
+}
+
+static constexpr DWARFDebugNames::AttributeEncoding sentinelAttrEnc() {
+ return {dwarf::Index(0), dwarf::Form(0)};
+}
+
+static bool isSentinel(const DWARFDebugNames::AttributeEncoding &AE) {
+ return AE == sentinelAttrEnc();
+}
+
+static DWARFDebugNames::Abbrev sentinelAbbrev() {
+ return DWARFDebugNames::Abbrev(0, dwarf::Tag(0), {});
+}
+
+static bool isSentinel(const DWARFDebugNames::Abbrev &Abbr) {
+ return Abbr.Code == 0;
+}
+
+DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getEmptyKey() {
+ return sentinelAbbrev();
+}
+
+DWARFDebugNames::Abbrev DWARFDebugNames::AbbrevMapInfo::getTombstoneKey() {
+ return DWARFDebugNames::Abbrev(~0, dwarf::Tag(0), {});
+}
+
+Expected<DWARFDebugNames::AttributeEncoding>
+DWARFDebugNames::NameIndex::extractAttributeEncoding(uint64_t *Offset) {
+ if (*Offset >= EntriesBase) {
+ return createStringError(errc::illegal_byte_sequence,
+ "Incorrectly terminated abbreviation table.");
+ }
+
+ uint32_t Index = Section.AccelSection.getULEB128(Offset);
+ uint32_t Form = Section.AccelSection.getULEB128(Offset);
+ return AttributeEncoding(dwarf::Index(Index), dwarf::Form(Form));
+}
+
+Expected<std::vector<DWARFDebugNames::AttributeEncoding>>
+DWARFDebugNames::NameIndex::extractAttributeEncodings(uint64_t *Offset) {
+ std::vector<AttributeEncoding> Result;
+ for (;;) {
+ auto AttrEncOr = extractAttributeEncoding(Offset);
+ if (!AttrEncOr)
+ return AttrEncOr.takeError();
+ if (isSentinel(*AttrEncOr))
+ return std::move(Result);
+
+ Result.emplace_back(*AttrEncOr);
+ }
+}
+
+Expected<DWARFDebugNames::Abbrev>
+DWARFDebugNames::NameIndex::extractAbbrev(uint64_t *Offset) {
+ if (*Offset >= EntriesBase) {
+ return createStringError(errc::illegal_byte_sequence,
+ "Incorrectly terminated abbreviation table.");
+ }
+
+ uint32_t Code = Section.AccelSection.getULEB128(Offset);
+ if (Code == 0)
+ return sentinelAbbrev();
+
+ uint32_t Tag = Section.AccelSection.getULEB128(Offset);
+ auto AttrEncOr = extractAttributeEncodings(Offset);
+ if (!AttrEncOr)
+ return AttrEncOr.takeError();
+ return Abbrev(Code, dwarf::Tag(Tag), std::move(*AttrEncOr));
+}
+
+Error DWARFDebugNames::NameIndex::extract() {
+ const DWARFDataExtractor &AS = Section.AccelSection;
+ uint64_t Offset = Base;
+ if (Error E = Hdr.extract(AS, &Offset))
+ return E;
+
+ const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
+ CUsBase = Offset;
+ Offset += Hdr.CompUnitCount * SectionOffsetSize;
+ Offset += Hdr.LocalTypeUnitCount * SectionOffsetSize;
+ Offset += Hdr.ForeignTypeUnitCount * 8;
+ BucketsBase = Offset;
+ Offset += Hdr.BucketCount * 4;
+ HashesBase = Offset;
+ if (Hdr.BucketCount > 0)
+ Offset += Hdr.NameCount * 4;
+ StringOffsetsBase = Offset;
+ Offset += Hdr.NameCount * SectionOffsetSize;
+ EntryOffsetsBase = Offset;
+ Offset += Hdr.NameCount * SectionOffsetSize;
+
+ if (!AS.isValidOffsetForDataOfSize(Offset, Hdr.AbbrevTableSize))
+ return createStringError(errc::illegal_byte_sequence,
+ "Section too small: cannot read abbreviations.");
+
+ EntriesBase = Offset + Hdr.AbbrevTableSize;
+
+ for (;;) {
+ auto AbbrevOr = extractAbbrev(&Offset);
+ if (!AbbrevOr)
+ return AbbrevOr.takeError();
+ if (isSentinel(*AbbrevOr))
+ return Error::success();
+
+ if (!Abbrevs.insert(std::move(*AbbrevOr)).second)
+ return createStringError(errc::invalid_argument,
+ "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
+ // (NameIndex::getEntry) to populate them.
+ Values.reserve(Abbr.Attributes.size());
+ for (const auto &Attr : Abbr.Attributes)
+ Values.emplace_back(Attr.Form);
+}
+
+Optional<DWARFFormValue>
+DWARFDebugNames::Entry::lookup(dwarf::Index Index) const {
+ assert(Abbr->Attributes.size() == Values.size());
+ for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
+ if (std::get<0>(Tuple).Index == Index)
+ return std::get<1>(Tuple);
+ }
+ return None;
+}
+
+Optional<uint64_t> DWARFDebugNames::Entry::getDIEUnitOffset() const {
+ if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_die_offset))
+ return Off->getAsReferenceUVal();
+ return None;
+}
+
+Optional<uint64_t> DWARFDebugNames::Entry::getCUIndex() const {
+ if (Optional<DWARFFormValue> Off = lookup(dwarf::DW_IDX_compile_unit))
+ return Off->getAsUnsignedConstant();
+ // In a per-CU index, the entries without a DW_IDX_compile_unit attribute
+ // implicitly refer to the single CU.
+ if (NameIdx->getCUCount() == 1)
+ return 0;
+ return None;
+}
+
+Optional<uint64_t> DWARFDebugNames::Entry::getCUOffset() const {
+ Optional<uint64_t> Index = getCUIndex();
+ if (!Index || *Index >= NameIdx->getCUCount())
+ return None;
+ return NameIdx->getCUOffset(*Index);
+}
+
+void DWARFDebugNames::Entry::dump(ScopedPrinter &W) const {
+ W.printHex("Abbrev", Abbr->Code);
+ W.startLine() << formatv("Tag: {0}\n", Abbr->Tag);
+ assert(Abbr->Attributes.size() == Values.size());
+ for (auto Tuple : zip_first(Abbr->Attributes, Values)) {
+ W.startLine() << formatv("{0}: ", std::get<0>(Tuple).Index);
+ std::get<1>(Tuple).dump(W.getOStream());
+ W.getOStream() << '\n';
+ }
+}
+
+char DWARFDebugNames::SentinelError::ID;
+std::error_code DWARFDebugNames::SentinelError::convertToErrorCode() const {
+ return inconvertibleErrorCode();
+}
+
+uint64_t DWARFDebugNames::NameIndex::getCUOffset(uint32_t CU) const {
+ assert(CU < Hdr.CompUnitCount);
+ const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
+ uint64_t Offset = CUsBase + SectionOffsetSize * CU;
+ return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
+}
+
+uint64_t DWARFDebugNames::NameIndex::getLocalTUOffset(uint32_t TU) const {
+ assert(TU < Hdr.LocalTypeUnitCount);
+ const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
+ uint64_t Offset = CUsBase + SectionOffsetSize * (Hdr.CompUnitCount + TU);
+ return Section.AccelSection.getRelocatedValue(SectionOffsetSize, &Offset);
+}
+
+uint64_t DWARFDebugNames::NameIndex::getForeignTUSignature(uint32_t TU) const {
+ assert(TU < Hdr.ForeignTypeUnitCount);
+ const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
+ uint64_t Offset =
+ CUsBase +
+ SectionOffsetSize * (Hdr.CompUnitCount + Hdr.LocalTypeUnitCount) + 8 * TU;
+ return Section.AccelSection.getU64(&Offset);
+}
+
+Expected<DWARFDebugNames::Entry>
+DWARFDebugNames::NameIndex::getEntry(uint64_t *Offset) const {
+ const DWARFDataExtractor &AS = Section.AccelSection;
+ if (!AS.isValidOffset(*Offset))
+ return createStringError(errc::illegal_byte_sequence,
+ "Incorrectly terminated entry list.");
+
+ uint32_t AbbrevCode = AS.getULEB128(Offset);
+ if (AbbrevCode == 0)
+ return make_error<SentinelError>();
+
+ const auto AbbrevIt = Abbrevs.find_as(AbbrevCode);
+ if (AbbrevIt == Abbrevs.end())
+ return createStringError(errc::invalid_argument, "Invalid abbreviation.");
+
+ Entry E(*this, *AbbrevIt);
+
+ dwarf::FormParams FormParams = {Hdr.Version, 0, Hdr.Format};
+ for (auto &Value : E.Values) {
+ if (!Value.extractValue(AS, Offset, FormParams))
+ return createStringError(errc::io_error,
+ "Error extracting index attribute values.");
+ }
+ return std::move(E);
+}
+
+DWARFDebugNames::NameTableEntry
+DWARFDebugNames::NameIndex::getNameTableEntry(uint32_t Index) const {
+ assert(0 < Index && Index <= Hdr.NameCount);
+ const unsigned SectionOffsetSize = dwarf::getDwarfOffsetByteSize(Hdr.Format);
+ uint64_t StringOffsetOffset =
+ StringOffsetsBase + SectionOffsetSize * (Index - 1);
+ uint64_t EntryOffsetOffset =
+ EntryOffsetsBase + SectionOffsetSize * (Index - 1);
+ const DWARFDataExtractor &AS = Section.AccelSection;
+
+ uint64_t StringOffset =
+ AS.getRelocatedValue(SectionOffsetSize, &StringOffsetOffset);
+ uint64_t EntryOffset = AS.getUnsigned(&EntryOffsetOffset, SectionOffsetSize);
+ EntryOffset += EntriesBase;
+ return {Section.StringSection, Index, StringOffset, EntryOffset};
+}
+
+uint32_t
+DWARFDebugNames::NameIndex::getBucketArrayEntry(uint32_t Bucket) const {
+ assert(Bucket < Hdr.BucketCount);
+ uint64_t BucketOffset = BucketsBase + 4 * Bucket;
+ return Section.AccelSection.getU32(&BucketOffset);
+}
+
+uint32_t DWARFDebugNames::NameIndex::getHashArrayEntry(uint32_t Index) const {
+ assert(0 < Index && Index <= Hdr.NameCount);
+ uint64_t HashOffset = HashesBase + 4 * (Index - 1);
+ return Section.AccelSection.getU32(&HashOffset);
+}
+
+// Returns true if we should continue scanning for entries, false if this is the
+// last (sentinel) entry). In case of a parsing error we also return false, as
+// it's not possible to recover this entry list (but the other lists may still
+// parse OK).
+bool DWARFDebugNames::NameIndex::dumpEntry(ScopedPrinter &W,
+ uint64_t *Offset) const {
+ uint64_t EntryId = *Offset;
+ auto EntryOr = getEntry(Offset);
+ if (!EntryOr) {
+ handleAllErrors(EntryOr.takeError(), [](const SentinelError &) {},
+ [&W](const ErrorInfoBase &EI) { EI.log(W.startLine()); });
+ return false;
+ }
+
+ DictScope EntryScope(W, ("Entry @ 0x" + Twine::utohexstr(EntryId)).str());
+ EntryOr->dump(W);
+ return true;
+}
+
+void DWARFDebugNames::NameIndex::dumpName(ScopedPrinter &W,
+ const NameTableEntry &NTE,
+ Optional<uint32_t> Hash) const {
+ DictScope NameScope(W, ("Name " + Twine(NTE.getIndex())).str());
+ if (Hash)
+ W.printHex("Hash", *Hash);
+
+ W.startLine() << format("String: 0x%08" PRIx64, NTE.getStringOffset());
+ W.getOStream() << " \"" << NTE.getString() << "\"\n";
+
+ uint64_t EntryOffset = NTE.getEntryOffset();
+ while (dumpEntry(W, &EntryOffset))
+ /*empty*/;
+}
+
+void DWARFDebugNames::NameIndex::dumpCUs(ScopedPrinter &W) const {
+ ListScope CUScope(W, "Compilation Unit offsets");
+ for (uint32_t CU = 0; CU < Hdr.CompUnitCount; ++CU)
+ W.startLine() << format("CU[%u]: 0x%08" PRIx64 "\n", CU, getCUOffset(CU));
+}
+
+void DWARFDebugNames::NameIndex::dumpLocalTUs(ScopedPrinter &W) const {
+ if (Hdr.LocalTypeUnitCount == 0)
+ return;
+
+ ListScope TUScope(W, "Local Type Unit offsets");
+ for (uint32_t TU = 0; TU < Hdr.LocalTypeUnitCount; ++TU)
+ W.startLine() << format("LocalTU[%u]: 0x%08" PRIx64 "\n", TU,
+ getLocalTUOffset(TU));
+}
+
+void DWARFDebugNames::NameIndex::dumpForeignTUs(ScopedPrinter &W) const {
+ if (Hdr.ForeignTypeUnitCount == 0)
+ return;
+
+ ListScope TUScope(W, "Foreign Type Unit signatures");
+ for (uint32_t TU = 0; TU < Hdr.ForeignTypeUnitCount; ++TU) {
+ W.startLine() << format("ForeignTU[%u]: 0x%016" PRIx64 "\n", TU,
+ getForeignTUSignature(TU));
+ }
+}
+
+void DWARFDebugNames::NameIndex::dumpAbbreviations(ScopedPrinter &W) const {
+ ListScope AbbrevsScope(W, "Abbreviations");
+ for (const auto &Abbr : Abbrevs)
+ Abbr.dump(W);
+}
+
+void DWARFDebugNames::NameIndex::dumpBucket(ScopedPrinter &W,
+ uint32_t Bucket) const {
+ ListScope BucketScope(W, ("Bucket " + Twine(Bucket)).str());
+ uint32_t Index = getBucketArrayEntry(Bucket);
+ if (Index == 0) {
+ W.printString("EMPTY");
+ return;
+ }
+ if (Index > Hdr.NameCount) {
+ W.printString("Name index is invalid");
+ return;
+ }
+
+ for (; Index <= Hdr.NameCount; ++Index) {
+ uint32_t Hash = getHashArrayEntry(Index);
+ if (Hash % Hdr.BucketCount != Bucket)
+ break;
+
+ dumpName(W, getNameTableEntry(Index), Hash);
+ }
+}
+
+LLVM_DUMP_METHOD void DWARFDebugNames::NameIndex::dump(ScopedPrinter &W) const {
+ DictScope UnitScope(W, ("Name Index @ 0x" + Twine::utohexstr(Base)).str());
+ Hdr.dump(W);
+ dumpCUs(W);
+ dumpLocalTUs(W);
+ dumpForeignTUs(W);
+ dumpAbbreviations(W);
+
+ if (Hdr.BucketCount > 0) {
+ for (uint32_t Bucket = 0; Bucket < Hdr.BucketCount; ++Bucket)
+ dumpBucket(W, Bucket);
+ return;
+ }
+
+ W.startLine() << "Hash table not present\n";
+ for (NameTableEntry NTE : *this)
+ dumpName(W, NTE, None);
+}
+
+Error DWARFDebugNames::extract() {
+ uint64_t Offset = 0;
+ while (AccelSection.isValidOffset(Offset)) {
+ NameIndex Next(*this, Offset);
+ if (Error E = Next.extract())
+ return E;
+ Offset = Next.getNextUnitOffset();
+ NameIndices.push_back(std::move(Next));
+ }
+ return Error::success();
+}
+
+iterator_range<DWARFDebugNames::ValueIterator>
+DWARFDebugNames::NameIndex::equal_range(StringRef Key) const {
+ return make_range(ValueIterator(*this, Key), ValueIterator());
+}
+
+LLVM_DUMP_METHOD void DWARFDebugNames::dump(raw_ostream &OS) const {
+ ScopedPrinter W(OS);
+ for (const NameIndex &NI : NameIndices)
+ NI.dump(W);
+}
+
+Optional<uint64_t>
+DWARFDebugNames::ValueIterator::findEntryOffsetInCurrentIndex() {
+ const Header &Hdr = CurrentIndex->Hdr;
+ if (Hdr.BucketCount == 0) {
+ // No Hash Table, We need to search through all names in the Name Index.
+ for (NameTableEntry NTE : *CurrentIndex) {
+ if (NTE.getString() == Key)
+ return NTE.getEntryOffset();
+ }
+ return None;
+ }
+
+ // The Name Index has a Hash Table, so use that to speed up the search.
+ // Compute the Key Hash, if it has not been done already.
+ if (!Hash)
+ Hash = caseFoldingDjbHash(Key);
+ uint32_t Bucket = *Hash % Hdr.BucketCount;
+ uint32_t Index = CurrentIndex->getBucketArrayEntry(Bucket);
+ if (Index == 0)
+ return None; // Empty bucket
+
+ for (; Index <= Hdr.NameCount; ++Index) {
+ uint32_t Hash = CurrentIndex->getHashArrayEntry(Index);
+ if (Hash % Hdr.BucketCount != Bucket)
+ return None; // End of bucket
+
+ NameTableEntry NTE = CurrentIndex->getNameTableEntry(Index);
+ if (NTE.getString() == Key)
+ return NTE.getEntryOffset();
+ }
+ return None;
+}
+
+bool DWARFDebugNames::ValueIterator::getEntryAtCurrentOffset() {
+ auto EntryOr = CurrentIndex->getEntry(&DataOffset);
+ if (!EntryOr) {
+ consumeError(EntryOr.takeError());
+ return false;
+ }
+ CurrentEntry = std::move(*EntryOr);
+ return true;
+}
+
+bool DWARFDebugNames::ValueIterator::findInCurrentIndex() {
+ Optional<uint64_t> Offset = findEntryOffsetInCurrentIndex();
+ if (!Offset)
+ return false;
+ DataOffset = *Offset;
+ return getEntryAtCurrentOffset();
+}
+
+void DWARFDebugNames::ValueIterator::searchFromStartOfCurrentIndex() {
+ for (const NameIndex *End = CurrentIndex->Section.NameIndices.end();
+ CurrentIndex != End; ++CurrentIndex) {
+ if (findInCurrentIndex())
+ return;
+ }
+ setEnd();
+}
+
+void DWARFDebugNames::ValueIterator::next() {
+ assert(CurrentIndex && "Incrementing an end() iterator?");
+
+ // First try the next entry in the current Index.
+ if (getEntryAtCurrentOffset())
+ return;
+
+ // If we're a local iterator or we have reached the last Index, we're done.
+ if (IsLocal || CurrentIndex == &CurrentIndex->Section.NameIndices.back()) {
+ setEnd();
+ return;
+ }
+
+ // Otherwise, try the next index.
+ ++CurrentIndex;
+ searchFromStartOfCurrentIndex();
+}
+
+DWARFDebugNames::ValueIterator::ValueIterator(const DWARFDebugNames &AccelTable,
+ StringRef Key)
+ : CurrentIndex(AccelTable.NameIndices.begin()), IsLocal(false),
+ Key(std::string(Key)) {
+ searchFromStartOfCurrentIndex();
+}
+
+DWARFDebugNames::ValueIterator::ValueIterator(
+ const DWARFDebugNames::NameIndex &NI, StringRef Key)
+ : CurrentIndex(&NI), IsLocal(true), Key(std::string(Key)) {
+ if (!findInCurrentIndex())
+ setEnd();
+}
+
+iterator_range<DWARFDebugNames::ValueIterator>
+DWARFDebugNames::equal_range(StringRef Key) const {
+ if (NameIndices.empty())
+ return make_range(ValueIterator(), ValueIterator());
+ return make_range(ValueIterator(*this, Key), ValueIterator());
+}
+
+const DWARFDebugNames::NameIndex *
+DWARFDebugNames::getCUNameIndex(uint64_t CUOffset) {
+ if (CUToNameIndex.size() == 0 && NameIndices.size() > 0) {
+ for (const auto &NI : *this) {
+ for (uint32_t CU = 0; CU < NI.getCUCount(); ++CU)
+ CUToNameIndex.try_emplace(NI.getCUOffset(CU), &NI);
+ }
+ }
+ return CUToNameIndex.lookup(CUOffset);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
index 25d2e852a7..b5921d04ef 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFAddressRange.cpp
@@ -1,33 +1,33 @@
-//===- DWARFDebugAranges.cpp ------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
- DIDumpOptions DumpOpts,
- const DWARFObject *Obj) const {
-
- OS << (DumpOpts.DisplayRawContents ? " " : "[");
+//===- DWARFDebugAranges.cpp ------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+void DWARFAddressRange::dump(raw_ostream &OS, uint32_t AddressSize,
+ DIDumpOptions DumpOpts,
+ const DWARFObject *Obj) const {
+
+ OS << (DumpOpts.DisplayRawContents ? " " : "[");
DWARFFormValue::dumpAddress(OS, AddressSize, LowPC);
OS << ", ";
DWARFFormValue::dumpAddress(OS, AddressSize, HighPC);
- OS << (DumpOpts.DisplayRawContents ? "" : ")");
-
- if (Obj)
- DWARFFormValue::dumpAddressSection(*Obj, OS, DumpOpts, SectionIndex);
-}
-
-raw_ostream &llvm::operator<<(raw_ostream &OS, const DWARFAddressRange &R) {
- R.dump(OS, /* AddressSize */ 8);
- return OS;
-}
+ OS << (DumpOpts.DisplayRawContents ? "" : ")");
+
+ if (Obj)
+ DWARFFormValue::dumpAddressSection(*Obj, OS, DumpOpts, SectionIndex);
+}
+
+raw_ostream &llvm::operator<<(raw_ostream &OS, const DWARFAddressRange &R) {
+ R.dump(OS, /* AddressSize */ 8);
+ return OS;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
index 2b08120ef4..cfd72886d8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFCompileUnit.cpp
@@ -1,41 +1,41 @@
-//===-- DWARFCompileUnit.cpp ----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(getFormat());
- OS << format("0x%08" PRIx64, getOffset()) << ": Compile Unit:"
- << " length = " << format("0x%0*" PRIx64, OffsetDumpWidth, getLength())
- << ", format = " << dwarf::FormatString(getFormat())
- << ", version = " << format("0x%04x", getVersion());
- if (getVersion() >= 5)
- OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
+//===-- DWARFCompileUnit.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+void DWARFCompileUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(getFormat());
+ OS << format("0x%08" PRIx64, getOffset()) << ": Compile Unit:"
+ << " length = " << format("0x%0*" PRIx64, OffsetDumpWidth, getLength())
+ << ", format = " << dwarf::FormatString(getFormat())
+ << ", version = " << format("0x%04x", getVersion());
+ if (getVersion() >= 5)
+ OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
if (!getAbbreviations())
OS << " (invalid)";
OS << ", addr_size = " << format("0x%02x", getAddressByteSize());
- if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
- OS << ", DWO_id = " << format("0x%016" PRIx64, *getDWOId());
- OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
- << ")\n";
-
- if (DWARFDie CUDie = getUnitDIE(false))
- CUDie.dump(OS, 0, DumpOpts);
- else
- OS << "<compile unit can't be parsed!>\n\n";
-}
-
-// VTable anchor.
-DWARFCompileUnit::~DWARFCompileUnit() = default;
+ if (getVersion() >= 5 && getUnitType() != dwarf::DW_UT_compile)
+ OS << ", DWO_id = " << format("0x%016" PRIx64, *getDWOId());
+ OS << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
+ << ")\n";
+
+ if (DWARFDie CUDie = getUnitDIE(false))
+ CUDie.dump(OS, 0, DumpOpts);
+ else
+ OS << "<compile unit can't be parsed!>\n\n";
+}
+
+// VTable anchor.
+DWARFCompileUnit::~DWARFCompileUnit() = default;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp
index 749d738af9..47ac74b02d 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -1,531 +1,531 @@
-//===- DWARFContext.cpp ---------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
-#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
-#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
-#include "llvm/DebugInfo/DWARF/DWARFSection.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
-#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Object/Decompressor.h"
-#include "llvm/Object/MachO.h"
-#include "llvm/Object/ObjectFile.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"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cstdint>
-#include <deque>
-#include <map>
-#include <string>
-#include <utility>
-#include <vector>
-
-using namespace llvm;
-using namespace dwarf;
-using namespace object;
-
-#define DEBUG_TYPE "dwarf"
-
-using DWARFLineTable = DWARFDebugLine::LineTable;
-using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
-using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
-
-DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
- std::string DWPName,
- std::function<void(Error)> RecoverableErrorHandler,
- std::function<void(Error)> WarningHandler)
- : DIContext(CK_DWARF), DWPName(std::move(DWPName)),
- RecoverableErrorHandler(RecoverableErrorHandler),
- WarningHandler(WarningHandler), DObj(std::move(DObj)) {}
-
-DWARFContext::~DWARFContext() = default;
-
-/// Dump the UUID load command.
-static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
- auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
- if (!MachO)
- return;
- for (auto LC : MachO->load_commands()) {
- raw_ostream::uuid_t UUID;
- if (LC.C.cmd == MachO::LC_UUID) {
- if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
- OS << "error: UUID load command is too short.\n";
- return;
- }
- OS << "UUID: ";
- memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
- OS.write_uuid(UUID);
- Triple T = MachO->getArchTriple();
- OS << " (" << T.getArchName() << ')';
- OS << ' ' << MachO->getFileName() << '\n';
- }
- }
-}
-
-using ContributionCollection =
- std::vector<Optional<StrOffsetsContributionDescriptor>>;
-
-// Collect all the contributions to the string offsets table from all units,
-// sort them by their starting offsets and remove duplicates.
-static ContributionCollection
-collectContributionData(DWARFContext::unit_iterator_range Units) {
- ContributionCollection Contributions;
- for (const auto &U : Units)
- 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.
- llvm::sort(Contributions,
- [](const Optional<StrOffsetsContributionDescriptor> &L,
- const Optional<StrOffsetsContributionDescriptor> &R) {
- if (L && R)
- return L->Base < R->Base;
- return R.hasValue();
- });
-
- // Uniquify contributions, as it is possible that units (specifically
- // type units in dwo or dwp files) share contributions. We don't want
- // to report them more than once.
- Contributions.erase(
- std::unique(Contributions.begin(), Contributions.end(),
- [](const Optional<StrOffsetsContributionDescriptor> &L,
- const Optional<StrOffsetsContributionDescriptor> &R) {
- if (L && R)
- return L->Base == R->Base && L->Size == R->Size;
- return false;
- }),
- Contributions.end());
- return Contributions;
-}
-
-// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
-// string offsets section, where each compile or type unit contributes a
-// number of entries (string offsets), with each contribution preceded by
-// a header containing size and version number. Alternatively, it may be a
-// monolithic series of string offsets, as generated by the pre-DWARF v5
-// implementation of split DWARF; however, in that case we still need to
-// collect contributions of units because the size of the offsets (4 or 8
-// bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
-static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
- StringRef SectionName,
- const DWARFObject &Obj,
- const DWARFSection &StringOffsetsSection,
- StringRef StringSection,
- DWARFContext::unit_iterator_range Units,
- bool LittleEndian) {
- auto Contributions = collectContributionData(Units);
- DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
- DataExtractor StrData(StringSection, LittleEndian, 0);
- uint64_t SectionSize = StringOffsetsSection.Data.size();
- uint64_t Offset = 0;
- for (auto &Contribution : Contributions) {
- // Report an ill-formed contribution.
- if (!Contribution) {
- OS << "error: invalid contribution to string offsets table in section ."
- << SectionName << ".\n";
- return;
- }
-
- dwarf::DwarfFormat Format = Contribution->getFormat();
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
- uint16_t Version = Contribution->getVersion();
- uint64_t ContributionHeader = Contribution->Base;
- // In DWARF v5 there is a contribution header that immediately precedes
- // the string offsets base (the location we have previously retrieved from
- // the CU DIE's DW_AT_str_offsets attribute). The header is located either
- // 8 or 16 bytes before the base, depending on the contribution's format.
- if (Version >= 5)
- ContributionHeader -= Format == DWARF32 ? 8 : 16;
-
- // Detect overlapping contributions.
- if (Offset > ContributionHeader) {
- DumpOpts.RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "overlapping contributions to string offsets table in section .%s.",
- SectionName.data()));
- }
- // Report a gap in the table.
- if (Offset < ContributionHeader) {
- OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
- OS << (ContributionHeader - Offset) << "\n";
- }
- OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
- // In DWARF v5 the contribution size in the descriptor does not equal
- // the originally encoded length (it does not contain the length of the
- // version field and the padding, a total of 4 bytes). Add them back in
- // for reporting.
- OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
- << ", Format = " << dwarf::FormatString(Format)
- << ", Version = " << Version << "\n";
-
- Offset = Contribution->Base;
- unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
- while (Offset - Contribution->Base < Contribution->Size) {
- OS << format("0x%8.8" PRIx64 ": ", Offset);
- uint64_t StringOffset =
- StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
- OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset);
- const char *S = StrData.getCStr(&StringOffset);
- if (S)
- OS << format("\"%s\"", S);
- OS << "\n";
- }
- }
- // Report a gap at the end of the table.
- if (Offset < SectionSize) {
- OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
- OS << (SectionSize - Offset) << "\n";
- }
-}
-
-// Dump the .debug_addr section.
-static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
- DIDumpOptions DumpOpts, uint16_t Version,
- uint8_t AddrSize) {
- uint64_t Offset = 0;
- while (AddrData.isValidOffset(Offset)) {
- DWARFDebugAddrTable AddrTable;
- uint64_t TableOffset = Offset;
- if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
- DumpOpts.WarningHandler)) {
- DumpOpts.RecoverableErrorHandler(std::move(Err));
- // Keep going after an error, if we can, assuming that the length field
- // could be read. If it couldn't, stop reading the section.
- if (auto TableLength = AddrTable.getFullLength()) {
- Offset = TableOffset + *TableLength;
- continue;
- }
- break;
- }
- AddrTable.dump(OS, DumpOpts);
- }
-}
-
-// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
-static void dumpRnglistsSection(
- raw_ostream &OS, DWARFDataExtractor &rnglistData,
- llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
- LookupPooledAddress,
- DIDumpOptions DumpOpts) {
- uint64_t Offset = 0;
- while (rnglistData.isValidOffset(Offset)) {
- llvm::DWARFDebugRnglistTable Rnglists;
- uint64_t TableOffset = Offset;
- if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
- DumpOpts.RecoverableErrorHandler(std::move(Err));
- uint64_t Length = Rnglists.length();
- // Keep going after an error, if we can, assuming that the length field
- // could be read. If it couldn't, stop reading the section.
- if (Length == 0)
- break;
- Offset = TableOffset + Length;
- } else {
+//===- DWARFContext.cpp ---------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Object/Decompressor.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/ObjectFile.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"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdint>
+#include <deque>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+using namespace object;
+
+#define DEBUG_TYPE "dwarf"
+
+using DWARFLineTable = DWARFDebugLine::LineTable;
+using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
+using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;
+
+DWARFContext::DWARFContext(std::unique_ptr<const DWARFObject> DObj,
+ std::string DWPName,
+ std::function<void(Error)> RecoverableErrorHandler,
+ std::function<void(Error)> WarningHandler)
+ : DIContext(CK_DWARF), DWPName(std::move(DWPName)),
+ RecoverableErrorHandler(RecoverableErrorHandler),
+ WarningHandler(WarningHandler), DObj(std::move(DObj)) {}
+
+DWARFContext::~DWARFContext() = default;
+
+/// Dump the UUID load command.
+static void dumpUUID(raw_ostream &OS, const ObjectFile &Obj) {
+ auto *MachO = dyn_cast<MachOObjectFile>(&Obj);
+ if (!MachO)
+ return;
+ for (auto LC : MachO->load_commands()) {
+ raw_ostream::uuid_t UUID;
+ if (LC.C.cmd == MachO::LC_UUID) {
+ if (LC.C.cmdsize < sizeof(UUID) + sizeof(LC.C)) {
+ OS << "error: UUID load command is too short.\n";
+ return;
+ }
+ OS << "UUID: ";
+ memcpy(&UUID, LC.Ptr+sizeof(LC.C), sizeof(UUID));
+ OS.write_uuid(UUID);
+ Triple T = MachO->getArchTriple();
+ OS << " (" << T.getArchName() << ')';
+ OS << ' ' << MachO->getFileName() << '\n';
+ }
+ }
+}
+
+using ContributionCollection =
+ std::vector<Optional<StrOffsetsContributionDescriptor>>;
+
+// Collect all the contributions to the string offsets table from all units,
+// sort them by their starting offsets and remove duplicates.
+static ContributionCollection
+collectContributionData(DWARFContext::unit_iterator_range Units) {
+ ContributionCollection Contributions;
+ for (const auto &U : Units)
+ 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.
+ llvm::sort(Contributions,
+ [](const Optional<StrOffsetsContributionDescriptor> &L,
+ const Optional<StrOffsetsContributionDescriptor> &R) {
+ if (L && R)
+ return L->Base < R->Base;
+ return R.hasValue();
+ });
+
+ // Uniquify contributions, as it is possible that units (specifically
+ // type units in dwo or dwp files) share contributions. We don't want
+ // to report them more than once.
+ Contributions.erase(
+ std::unique(Contributions.begin(), Contributions.end(),
+ [](const Optional<StrOffsetsContributionDescriptor> &L,
+ const Optional<StrOffsetsContributionDescriptor> &R) {
+ if (L && R)
+ return L->Base == R->Base && L->Size == R->Size;
+ return false;
+ }),
+ Contributions.end());
+ return Contributions;
+}
+
+// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
+// string offsets section, where each compile or type unit contributes a
+// number of entries (string offsets), with each contribution preceded by
+// a header containing size and version number. Alternatively, it may be a
+// monolithic series of string offsets, as generated by the pre-DWARF v5
+// implementation of split DWARF; however, in that case we still need to
+// collect contributions of units because the size of the offsets (4 or 8
+// bytes) depends on the format of the referencing unit (DWARF32 or DWARF64).
+static void dumpStringOffsetsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
+ StringRef SectionName,
+ const DWARFObject &Obj,
+ const DWARFSection &StringOffsetsSection,
+ StringRef StringSection,
+ DWARFContext::unit_iterator_range Units,
+ bool LittleEndian) {
+ auto Contributions = collectContributionData(Units);
+ DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0);
+ DataExtractor StrData(StringSection, LittleEndian, 0);
+ uint64_t SectionSize = StringOffsetsSection.Data.size();
+ uint64_t Offset = 0;
+ for (auto &Contribution : Contributions) {
+ // Report an ill-formed contribution.
+ if (!Contribution) {
+ OS << "error: invalid contribution to string offsets table in section ."
+ << SectionName << ".\n";
+ return;
+ }
+
+ dwarf::DwarfFormat Format = Contribution->getFormat();
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
+ uint16_t Version = Contribution->getVersion();
+ uint64_t ContributionHeader = Contribution->Base;
+ // In DWARF v5 there is a contribution header that immediately precedes
+ // the string offsets base (the location we have previously retrieved from
+ // the CU DIE's DW_AT_str_offsets attribute). The header is located either
+ // 8 or 16 bytes before the base, depending on the contribution's format.
+ if (Version >= 5)
+ ContributionHeader -= Format == DWARF32 ? 8 : 16;
+
+ // Detect overlapping contributions.
+ if (Offset > ContributionHeader) {
+ DumpOpts.RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "overlapping contributions to string offsets table in section .%s.",
+ SectionName.data()));
+ }
+ // Report a gap in the table.
+ if (Offset < ContributionHeader) {
+ OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
+ OS << (ContributionHeader - Offset) << "\n";
+ }
+ OS << format("0x%8.8" PRIx64 ": ", ContributionHeader);
+ // In DWARF v5 the contribution size in the descriptor does not equal
+ // the originally encoded length (it does not contain the length of the
+ // version field and the padding, a total of 4 bytes). Add them back in
+ // for reporting.
+ OS << "Contribution size = " << (Contribution->Size + (Version < 5 ? 0 : 4))
+ << ", Format = " << dwarf::FormatString(Format)
+ << ", Version = " << Version << "\n";
+
+ Offset = Contribution->Base;
+ unsigned EntrySize = Contribution->getDwarfOffsetByteSize();
+ while (Offset - Contribution->Base < Contribution->Size) {
+ OS << format("0x%8.8" PRIx64 ": ", Offset);
+ uint64_t StringOffset =
+ StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
+ OS << format("%0*" PRIx64 " ", OffsetDumpWidth, StringOffset);
+ const char *S = StrData.getCStr(&StringOffset);
+ if (S)
+ OS << format("\"%s\"", S);
+ OS << "\n";
+ }
+ }
+ // Report a gap at the end of the table.
+ if (Offset < SectionSize) {
+ OS << format("0x%8.8" PRIx64 ": Gap, length = ", Offset);
+ OS << (SectionSize - Offset) << "\n";
+ }
+}
+
+// Dump the .debug_addr section.
+static void dumpAddrSection(raw_ostream &OS, DWARFDataExtractor &AddrData,
+ DIDumpOptions DumpOpts, uint16_t Version,
+ uint8_t AddrSize) {
+ uint64_t Offset = 0;
+ while (AddrData.isValidOffset(Offset)) {
+ DWARFDebugAddrTable AddrTable;
+ uint64_t TableOffset = Offset;
+ if (Error Err = AddrTable.extract(AddrData, &Offset, Version, AddrSize,
+ DumpOpts.WarningHandler)) {
+ DumpOpts.RecoverableErrorHandler(std::move(Err));
+ // Keep going after an error, if we can, assuming that the length field
+ // could be read. If it couldn't, stop reading the section.
+ if (auto TableLength = AddrTable.getFullLength()) {
+ Offset = TableOffset + *TableLength;
+ continue;
+ }
+ break;
+ }
+ AddrTable.dump(OS, DumpOpts);
+ }
+}
+
+// Dump the .debug_rnglists or .debug_rnglists.dwo section (DWARF v5).
+static void dumpRnglistsSection(
+ raw_ostream &OS, DWARFDataExtractor &rnglistData,
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
+ LookupPooledAddress,
+ DIDumpOptions DumpOpts) {
+ uint64_t Offset = 0;
+ while (rnglistData.isValidOffset(Offset)) {
+ llvm::DWARFDebugRnglistTable Rnglists;
+ uint64_t TableOffset = Offset;
+ if (Error Err = Rnglists.extract(rnglistData, &Offset)) {
+ DumpOpts.RecoverableErrorHandler(std::move(Err));
+ uint64_t Length = Rnglists.length();
+ // Keep going after an error, if we can, assuming that the length field
+ // could be read. If it couldn't, stop reading the section.
+ if (Length == 0)
+ break;
+ Offset = TableOffset + Length;
+ } else {
Rnglists.dump(rnglistData, OS, LookupPooledAddress, DumpOpts);
- }
- }
-}
-
-std::unique_ptr<DWARFDebugMacro>
-DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
- auto Macro = std::make_unique<DWARFDebugMacro>();
- auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
- if (Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection
- ? compile_units()
- : dwo_compile_units(),
- SectionType == MacroSection
- ? getStringExtractor()
- : getStringDWOExtractor(),
- Data)
- : Macro->parseMacinfo(Data)) {
- RecoverableErrorHandler(std::move(Err));
- Macro = nullptr;
- }
- };
- switch (SectionType) {
- case MacinfoSection: {
- DWARFDataExtractor Data(DObj->getMacinfoSection(), isLittleEndian(), 0);
- ParseAndDump(Data, /*IsMacro=*/false);
- break;
- }
- case MacinfoDwoSection: {
- DWARFDataExtractor Data(DObj->getMacinfoDWOSection(), isLittleEndian(), 0);
- ParseAndDump(Data, /*IsMacro=*/false);
- break;
- }
- case MacroSection: {
- DWARFDataExtractor Data(*DObj, DObj->getMacroSection(), isLittleEndian(),
- 0);
- ParseAndDump(Data, /*IsMacro=*/true);
- break;
- }
- case MacroDwoSection: {
- DWARFDataExtractor Data(DObj->getMacroDWOSection(), isLittleEndian(), 0);
- ParseAndDump(Data, /*IsMacro=*/true);
- break;
- }
- }
- return Macro;
-}
-
-static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
- DWARFDataExtractor Data,
- const MCRegisterInfo *MRI,
- const DWARFObject &Obj,
- Optional<uint64_t> DumpOffset) {
- uint64_t Offset = 0;
-
- while (Data.isValidOffset(Offset)) {
- DWARFListTableHeader Header(".debug_loclists", "locations");
- if (Error E = Header.extract(Data, &Offset)) {
- DumpOpts.RecoverableErrorHandler(std::move(E));
- return;
- }
-
+ }
+ }
+}
+
+std::unique_ptr<DWARFDebugMacro>
+DWARFContext::parseMacroOrMacinfo(MacroSecType SectionType) {
+ auto Macro = std::make_unique<DWARFDebugMacro>();
+ auto ParseAndDump = [&](DWARFDataExtractor &Data, bool IsMacro) {
+ if (Error Err = IsMacro ? Macro->parseMacro(SectionType == MacroSection
+ ? compile_units()
+ : dwo_compile_units(),
+ SectionType == MacroSection
+ ? getStringExtractor()
+ : getStringDWOExtractor(),
+ Data)
+ : Macro->parseMacinfo(Data)) {
+ RecoverableErrorHandler(std::move(Err));
+ Macro = nullptr;
+ }
+ };
+ switch (SectionType) {
+ case MacinfoSection: {
+ DWARFDataExtractor Data(DObj->getMacinfoSection(), isLittleEndian(), 0);
+ ParseAndDump(Data, /*IsMacro=*/false);
+ break;
+ }
+ case MacinfoDwoSection: {
+ DWARFDataExtractor Data(DObj->getMacinfoDWOSection(), isLittleEndian(), 0);
+ ParseAndDump(Data, /*IsMacro=*/false);
+ break;
+ }
+ case MacroSection: {
+ DWARFDataExtractor Data(*DObj, DObj->getMacroSection(), isLittleEndian(),
+ 0);
+ ParseAndDump(Data, /*IsMacro=*/true);
+ break;
+ }
+ case MacroDwoSection: {
+ DWARFDataExtractor Data(DObj->getMacroDWOSection(), isLittleEndian(), 0);
+ ParseAndDump(Data, /*IsMacro=*/true);
+ break;
+ }
+ }
+ return Macro;
+}
+
+static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
+ DWARFDataExtractor Data,
+ const MCRegisterInfo *MRI,
+ const DWARFObject &Obj,
+ Optional<uint64_t> DumpOffset) {
+ uint64_t Offset = 0;
+
+ while (Data.isValidOffset(Offset)) {
+ DWARFListTableHeader Header(".debug_loclists", "locations");
+ if (Error E = Header.extract(Data, &Offset)) {
+ DumpOpts.RecoverableErrorHandler(std::move(E));
+ return;
+ }
+
Header.dump(Data, OS, DumpOpts);
-
- uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
- Data.setAddressSize(Header.getAddrSize());
- DWARFDebugLoclists Loc(Data, Header.getVersion());
- if (DumpOffset) {
- if (DumpOffset >= Offset && DumpOffset < EndOffset) {
- Offset = *DumpOffset;
- Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, nullptr,
- DumpOpts, /*Indent=*/0);
- OS << "\n";
- return;
- }
- } else {
- Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, Obj, DumpOpts);
- }
- Offset = EndOffset;
- }
-}
-
-static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts,
- DWARFDataExtractor Data, bool GnuStyle) {
- DWARFDebugPubTable Table;
- Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler);
- Table.dump(OS);
-}
-
-void DWARFContext::dump(
- raw_ostream &OS, DIDumpOptions DumpOpts,
- std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
- uint64_t DumpType = DumpOpts.DumpType;
-
- StringRef Extension = sys::path::extension(DObj->getFileName());
- bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
-
- // Print UUID header.
- const auto *ObjFile = DObj->getFile();
- if (DumpType & DIDT_UUID)
- dumpUUID(OS, *ObjFile);
-
- // Print a header for each explicitly-requested section.
- // Otherwise just print one for non-empty sections.
- // Only print empty .dwo section headers when dumping a .dwo file.
- bool Explicit = DumpType != DIDT_All && !IsDWO;
- bool ExplicitDWO = Explicit && IsDWO;
- auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
- StringRef Section) -> Optional<uint64_t> * {
- unsigned Mask = 1U << ID;
- bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
- if (!Should)
- return nullptr;
- OS << "\n" << Name << " contents:\n";
- return &DumpOffsets[ID];
- };
-
- // Dump individual sections.
- if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
- DObj->getAbbrevSection()))
- getDebugAbbrev()->dump(OS);
- if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
- DObj->getAbbrevDWOSection()))
- getDebugAbbrevDWO()->dump(OS);
-
- auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
- OS << '\n' << Name << " contents:\n";
- if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
- for (const auto &U : Units)
- U->getDIEForOffset(DumpOffset.getValue())
- .dump(OS, 0, DumpOpts.noImplicitRecursion());
- else
- for (const auto &U : Units)
- U->dump(OS, DumpOpts);
- };
- if ((DumpType & DIDT_DebugInfo)) {
- if (Explicit || getNumCompileUnits())
- dumpDebugInfo(".debug_info", info_section_units());
- if (ExplicitDWO || getNumDWOCompileUnits())
- dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
- }
-
- auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
- OS << '\n' << Name << " contents:\n";
- for (const auto &U : Units)
- if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
- U->getDIEForOffset(*DumpOffset)
- .dump(OS, 0, DumpOpts.noImplicitRecursion());
- else
- U->dump(OS, DumpOpts);
- };
- if ((DumpType & DIDT_DebugTypes)) {
- if (Explicit || getNumTypeUnits())
- dumpDebugType(".debug_types", types_section_units());
- if (ExplicitDWO || getNumDWOTypeUnits())
- dumpDebugType(".debug_types.dwo", dwo_types_section_units());
- }
-
- DIDumpOptions LLDumpOpts = DumpOpts;
- if (LLDumpOpts.Verbose)
- LLDumpOpts.DisplayRawContents = true;
-
- if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
- DObj->getLocSection().Data)) {
- getDebugLoc()->dump(OS, getRegisterInfo(), *DObj, LLDumpOpts, *Off);
- }
- if (const auto *Off =
- shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
- DObj->getLoclistsSection().Data)) {
- DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
- 0);
- dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
- }
- if (const auto *Off =
- shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
- DObj->getLoclistsDWOSection().Data)) {
- DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
- isLittleEndian(), 0);
- dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
- }
-
- if (const auto *Off =
- shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
- DObj->getLocDWOSection().Data)) {
- DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
- 4);
- DWARFDebugLoclists Loc(Data, /*Version=*/4);
- if (*Off) {
- uint64_t Offset = **Off;
- Loc.dumpLocationList(&Offset, OS,
- /*BaseAddr=*/None, getRegisterInfo(), *DObj, nullptr,
- LLDumpOpts, /*Indent=*/0);
- OS << "\n";
- } else {
- Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), *DObj,
- LLDumpOpts);
- }
- }
-
- if (const Optional<uint64_t> *Off =
- shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
- DObj->getFrameSection().Data)) {
- if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
+
+ uint64_t EndOffset = Header.length() + Header.getHeaderOffset();
+ Data.setAddressSize(Header.getAddrSize());
+ DWARFDebugLoclists Loc(Data, Header.getVersion());
+ if (DumpOffset) {
+ if (DumpOffset >= Offset && DumpOffset < EndOffset) {
+ Offset = *DumpOffset;
+ Loc.dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj, nullptr,
+ DumpOpts, /*Indent=*/0);
+ OS << "\n";
+ return;
+ }
+ } else {
+ Loc.dumpRange(Offset, EndOffset - Offset, OS, MRI, Obj, DumpOpts);
+ }
+ Offset = EndOffset;
+ }
+}
+
+static void dumpPubTableSection(raw_ostream &OS, DIDumpOptions DumpOpts,
+ DWARFDataExtractor Data, bool GnuStyle) {
+ DWARFDebugPubTable Table;
+ Table.extract(Data, GnuStyle, DumpOpts.RecoverableErrorHandler);
+ Table.dump(OS);
+}
+
+void DWARFContext::dump(
+ raw_ostream &OS, DIDumpOptions DumpOpts,
+ std::array<Optional<uint64_t>, DIDT_ID_Count> DumpOffsets) {
+ uint64_t DumpType = DumpOpts.DumpType;
+
+ StringRef Extension = sys::path::extension(DObj->getFileName());
+ bool IsDWO = (Extension == ".dwo") || (Extension == ".dwp");
+
+ // Print UUID header.
+ const auto *ObjFile = DObj->getFile();
+ if (DumpType & DIDT_UUID)
+ dumpUUID(OS, *ObjFile);
+
+ // Print a header for each explicitly-requested section.
+ // Otherwise just print one for non-empty sections.
+ // Only print empty .dwo section headers when dumping a .dwo file.
+ bool Explicit = DumpType != DIDT_All && !IsDWO;
+ bool ExplicitDWO = Explicit && IsDWO;
+ auto shouldDump = [&](bool Explicit, const char *Name, unsigned ID,
+ StringRef Section) -> Optional<uint64_t> * {
+ unsigned Mask = 1U << ID;
+ bool Should = (DumpType & Mask) && (Explicit || !Section.empty());
+ if (!Should)
+ return nullptr;
+ OS << "\n" << Name << " contents:\n";
+ return &DumpOffsets[ID];
+ };
+
+ // Dump individual sections.
+ if (shouldDump(Explicit, ".debug_abbrev", DIDT_ID_DebugAbbrev,
+ DObj->getAbbrevSection()))
+ getDebugAbbrev()->dump(OS);
+ if (shouldDump(ExplicitDWO, ".debug_abbrev.dwo", DIDT_ID_DebugAbbrev,
+ DObj->getAbbrevDWOSection()))
+ getDebugAbbrevDWO()->dump(OS);
+
+ auto dumpDebugInfo = [&](const char *Name, unit_iterator_range Units) {
+ OS << '\n' << Name << " contents:\n";
+ if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugInfo])
+ for (const auto &U : Units)
+ U->getDIEForOffset(DumpOffset.getValue())
+ .dump(OS, 0, DumpOpts.noImplicitRecursion());
+ else
+ for (const auto &U : Units)
+ U->dump(OS, DumpOpts);
+ };
+ if ((DumpType & DIDT_DebugInfo)) {
+ if (Explicit || getNumCompileUnits())
+ dumpDebugInfo(".debug_info", info_section_units());
+ if (ExplicitDWO || getNumDWOCompileUnits())
+ dumpDebugInfo(".debug_info.dwo", dwo_info_section_units());
+ }
+
+ auto dumpDebugType = [&](const char *Name, unit_iterator_range Units) {
+ OS << '\n' << Name << " contents:\n";
+ for (const auto &U : Units)
+ if (auto DumpOffset = DumpOffsets[DIDT_ID_DebugTypes])
+ U->getDIEForOffset(*DumpOffset)
+ .dump(OS, 0, DumpOpts.noImplicitRecursion());
+ else
+ U->dump(OS, DumpOpts);
+ };
+ if ((DumpType & DIDT_DebugTypes)) {
+ if (Explicit || getNumTypeUnits())
+ dumpDebugType(".debug_types", types_section_units());
+ if (ExplicitDWO || getNumDWOTypeUnits())
+ dumpDebugType(".debug_types.dwo", dwo_types_section_units());
+ }
+
+ DIDumpOptions LLDumpOpts = DumpOpts;
+ if (LLDumpOpts.Verbose)
+ LLDumpOpts.DisplayRawContents = true;
+
+ if (const auto *Off = shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
+ DObj->getLocSection().Data)) {
+ getDebugLoc()->dump(OS, getRegisterInfo(), *DObj, LLDumpOpts, *Off);
+ }
+ if (const auto *Off =
+ shouldDump(Explicit, ".debug_loclists", DIDT_ID_DebugLoclists,
+ DObj->getLoclistsSection().Data)) {
+ DWARFDataExtractor Data(*DObj, DObj->getLoclistsSection(), isLittleEndian(),
+ 0);
+ dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
+ }
+ if (const auto *Off =
+ shouldDump(ExplicitDWO, ".debug_loclists.dwo", DIDT_ID_DebugLoclists,
+ DObj->getLoclistsDWOSection().Data)) {
+ DWARFDataExtractor Data(*DObj, DObj->getLoclistsDWOSection(),
+ isLittleEndian(), 0);
+ dumpLoclistsSection(OS, LLDumpOpts, Data, getRegisterInfo(), *DObj, *Off);
+ }
+
+ if (const auto *Off =
+ shouldDump(ExplicitDWO, ".debug_loc.dwo", DIDT_ID_DebugLoc,
+ DObj->getLocDWOSection().Data)) {
+ DWARFDataExtractor Data(*DObj, DObj->getLocDWOSection(), isLittleEndian(),
+ 4);
+ DWARFDebugLoclists Loc(Data, /*Version=*/4);
+ if (*Off) {
+ uint64_t Offset = **Off;
+ Loc.dumpLocationList(&Offset, OS,
+ /*BaseAddr=*/None, getRegisterInfo(), *DObj, nullptr,
+ LLDumpOpts, /*Indent=*/0);
+ OS << "\n";
+ } else {
+ Loc.dumpRange(0, Data.getData().size(), OS, getRegisterInfo(), *DObj,
+ LLDumpOpts);
+ }
+ }
+
+ if (const Optional<uint64_t> *Off =
+ shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
+ DObj->getFrameSection().Data)) {
+ if (Expected<const DWARFDebugFrame *> DF = getDebugFrame())
(*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
- else
- RecoverableErrorHandler(DF.takeError());
- }
-
- if (const Optional<uint64_t> *Off =
- shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
- DObj->getEHFrameSection().Data)) {
- if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
+ else
+ RecoverableErrorHandler(DF.takeError());
+ }
+
+ if (const Optional<uint64_t> *Off =
+ shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
+ DObj->getEHFrameSection().Data)) {
+ if (Expected<const DWARFDebugFrame *> DF = getEHFrame())
(*DF)->dump(OS, DumpOpts, getRegisterInfo(), *Off);
- else
- RecoverableErrorHandler(DF.takeError());
- }
-
- if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
- DObj->getMacroSection().Data)) {
- if (auto Macro = getDebugMacro())
- Macro->dump(OS);
- }
-
- if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,
- DObj->getMacroDWOSection())) {
- if (auto MacroDWO = getDebugMacroDWO())
- MacroDWO->dump(OS);
- }
-
- if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
- DObj->getMacinfoSection())) {
- if (auto Macinfo = getDebugMacinfo())
- Macinfo->dump(OS);
- }
-
- if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
- DObj->getMacinfoDWOSection())) {
- if (auto MacinfoDWO = getDebugMacinfoDWO())
- MacinfoDWO->dump(OS);
- }
-
- if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
- DObj->getArangesSection())) {
- uint64_t offset = 0;
- DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(),
- 0);
- DWARFDebugArangeSet set;
- while (arangesData.isValidOffset(offset)) {
+ else
+ RecoverableErrorHandler(DF.takeError());
+ }
+
+ if (shouldDump(Explicit, ".debug_macro", DIDT_ID_DebugMacro,
+ DObj->getMacroSection().Data)) {
+ if (auto Macro = getDebugMacro())
+ Macro->dump(OS);
+ }
+
+ if (shouldDump(Explicit, ".debug_macro.dwo", DIDT_ID_DebugMacro,
+ DObj->getMacroDWOSection())) {
+ if (auto MacroDWO = getDebugMacroDWO())
+ MacroDWO->dump(OS);
+ }
+
+ if (shouldDump(Explicit, ".debug_macinfo", DIDT_ID_DebugMacro,
+ DObj->getMacinfoSection())) {
+ if (auto Macinfo = getDebugMacinfo())
+ Macinfo->dump(OS);
+ }
+
+ if (shouldDump(Explicit, ".debug_macinfo.dwo", DIDT_ID_DebugMacro,
+ DObj->getMacinfoDWOSection())) {
+ if (auto MacinfoDWO = getDebugMacinfoDWO())
+ MacinfoDWO->dump(OS);
+ }
+
+ if (shouldDump(Explicit, ".debug_aranges", DIDT_ID_DebugAranges,
+ DObj->getArangesSection())) {
+ uint64_t offset = 0;
+ DWARFDataExtractor arangesData(DObj->getArangesSection(), isLittleEndian(),
+ 0);
+ DWARFDebugArangeSet set;
+ while (arangesData.isValidOffset(offset)) {
if (Error E =
set.extract(arangesData, &offset, DumpOpts.WarningHandler)) {
- RecoverableErrorHandler(std::move(E));
- break;
- }
- set.dump(OS);
- }
- }
-
- auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
- DIDumpOptions DumpOpts,
- Optional<uint64_t> DumpOffset) {
- while (!Parser.done()) {
- if (DumpOffset && Parser.getOffset() != *DumpOffset) {
- Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
- continue;
- }
- OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
- << "]\n";
- Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS,
- DumpOpts.Verbose);
- }
- };
-
+ RecoverableErrorHandler(std::move(E));
+ break;
+ }
+ set.dump(OS);
+ }
+ }
+
+ auto DumpLineSection = [&](DWARFDebugLine::SectionParser Parser,
+ DIDumpOptions DumpOpts,
+ Optional<uint64_t> DumpOffset) {
+ while (!Parser.done()) {
+ if (DumpOffset && Parser.getOffset() != *DumpOffset) {
+ Parser.skip(DumpOpts.WarningHandler, DumpOpts.WarningHandler);
+ continue;
+ }
+ OS << "debug_line[" << format("0x%8.8" PRIx64, Parser.getOffset())
+ << "]\n";
+ Parser.parseNext(DumpOpts.WarningHandler, DumpOpts.WarningHandler, &OS,
+ DumpOpts.Verbose);
+ }
+ };
+
auto DumpStrSection = [&](StringRef Section) {
DataExtractor StrData(Section, isLittleEndian(), 0);
uint64_t Offset = 0;
@@ -544,1171 +544,1171 @@ void DWARFContext::dump(
}
};
- if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
- DObj->getLineSection().Data)) {
- DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
- 0);
+ if (const auto *Off = shouldDump(Explicit, ".debug_line", DIDT_ID_DebugLine,
+ DObj->getLineSection().Data)) {
+ DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(),
+ 0);
DWARFDebugLine::SectionParser Parser(LineData, *this, normal_units());
- DumpLineSection(Parser, DumpOpts, *Off);
- }
-
- if (const auto *Off =
- shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
- DObj->getLineDWOSection().Data)) {
- DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
- isLittleEndian(), 0);
+ DumpLineSection(Parser, DumpOpts, *Off);
+ }
+
+ if (const auto *Off =
+ shouldDump(ExplicitDWO, ".debug_line.dwo", DIDT_ID_DebugLine,
+ DObj->getLineDWOSection().Data)) {
+ DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(),
+ isLittleEndian(), 0);
DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_units());
- DumpLineSection(Parser, DumpOpts, *Off);
- }
-
- if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
- DObj->getCUIndexSection())) {
- getCUIndex().dump(OS);
- }
-
- if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
- DObj->getTUIndexSection())) {
- getTUIndex().dump(OS);
- }
-
- if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
+ DumpLineSection(Parser, DumpOpts, *Off);
+ }
+
+ if (shouldDump(Explicit, ".debug_cu_index", DIDT_ID_DebugCUIndex,
+ DObj->getCUIndexSection())) {
+ getCUIndex().dump(OS);
+ }
+
+ if (shouldDump(Explicit, ".debug_tu_index", DIDT_ID_DebugTUIndex,
+ DObj->getTUIndexSection())) {
+ getTUIndex().dump(OS);
+ }
+
+ if (shouldDump(Explicit, ".debug_str", DIDT_ID_DebugStr,
DObj->getStrSection()))
DumpStrSection(DObj->getStrSection());
- if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
+ if (shouldDump(ExplicitDWO, ".debug_str.dwo", DIDT_ID_DebugStr,
DObj->getStrDWOSection()))
DumpStrSection(DObj->getStrDWOSection());
- if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
+ if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
DObj->getLineStrSection()))
DumpStrSection(DObj->getLineStrSection());
-
- if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
- DObj->getAddrSection().Data)) {
- DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
- isLittleEndian(), 0);
- dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
- }
-
- if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
- DObj->getRangesSection().Data)) {
- uint8_t savedAddressByteSize = getCUAddrSize();
- DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
- isLittleEndian(), savedAddressByteSize);
- uint64_t offset = 0;
- DWARFDebugRangeList rangeList;
- while (rangesData.isValidOffset(offset)) {
- if (Error E = rangeList.extract(rangesData, &offset)) {
- DumpOpts.RecoverableErrorHandler(std::move(E));
- break;
- }
- rangeList.dump(OS);
- }
- }
-
- auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {
- const auto &CUs = compile_units();
- auto I = CUs.begin();
- if (I == CUs.end())
- return None;
- return (*I)->getAddrOffsetSectionItem(Index);
- };
-
- if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
- DObj->getRnglistsSection().Data)) {
- DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
- isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
- }
-
- if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
- DObj->getRnglistsDWOSection().Data)) {
- DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
- isLittleEndian(), 0);
- dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
- }
-
- if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
- DObj->getPubnamesSection().Data)) {
- DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(),
- isLittleEndian(), 0);
- dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
- }
-
- if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
- DObj->getPubtypesSection().Data)) {
- DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(),
- isLittleEndian(), 0);
- dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
- }
-
- if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
- DObj->getGnuPubnamesSection().Data)) {
- DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),
- isLittleEndian(), 0);
- dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
- }
-
- if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
- DObj->getGnuPubtypesSection().Data)) {
- DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),
- isLittleEndian(), 0);
- dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
- }
-
- if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
- DObj->getStrOffsetsSection().Data))
- dumpStringOffsetsSection(
- OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
- DObj->getStrSection(), normal_units(), isLittleEndian());
- if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
- DObj->getStrOffsetsDWOSection().Data))
- dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
- DObj->getStrOffsetsDWOSection(),
- DObj->getStrDWOSection(), dwo_units(),
- isLittleEndian());
-
- if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
- DObj->getGdbIndexSection())) {
- getGdbIndex().dump(OS);
- }
-
- if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
- DObj->getAppleNamesSection().Data))
- getAppleNames().dump(OS);
-
- if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
- DObj->getAppleTypesSection().Data))
- getAppleTypes().dump(OS);
-
- if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
- DObj->getAppleNamespacesSection().Data))
- getAppleNamespaces().dump(OS);
-
- if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
- DObj->getAppleObjCSection().Data))
- getAppleObjC().dump(OS);
- if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
- DObj->getNamesSection().Data))
- getDebugNames().dump(OS);
-}
-
-DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
- parseDWOUnits(LazyParse);
-
- if (const auto &CUI = getCUIndex()) {
- if (const auto *R = CUI.getFromHash(Hash))
- return dyn_cast_or_null<DWARFCompileUnit>(
- DWOUnits.getUnitForIndexEntry(*R));
- return nullptr;
- }
-
- // If there's no index, just search through the CUs in the DWO - there's
- // probably only one unless this is something like LTO - though an in-process
- // built/cached lookup table could be used in that case to improve repeated
- // lookups of different CUs in the DWO.
- for (const auto &DWOCU : dwo_compile_units()) {
- // Might not have parsed DWO ID yet.
- if (!DWOCU->getDWOId()) {
- if (Optional<uint64_t> DWOId =
- toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
- DWOCU->setDWOId(*DWOId);
- else
- // No DWO ID?
- continue;
- }
- if (DWOCU->getDWOId() == Hash)
- return dyn_cast<DWARFCompileUnit>(DWOCU.get());
- }
- return nullptr;
-}
-
-DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) {
- parseNormalUnits();
- if (auto *CU = NormalUnits.getUnitForOffset(Offset))
- return CU->getDIEForOffset(Offset);
- return DWARFDie();
-}
-
-bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
- bool Success = true;
- DWARFVerifier verifier(OS, *this, DumpOpts);
-
- Success &= verifier.handleDebugAbbrev();
- if (DumpOpts.DumpType & DIDT_DebugInfo)
- Success &= verifier.handleDebugInfo();
- if (DumpOpts.DumpType & DIDT_DebugLine)
- Success &= verifier.handleDebugLine();
- Success &= verifier.handleAccelTables();
- return Success;
-}
-
-const DWARFUnitIndex &DWARFContext::getCUIndex() {
- if (CUIndex)
- return *CUIndex;
-
- DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
-
- CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
- CUIndex->parse(CUIndexData);
- return *CUIndex;
-}
-
-const DWARFUnitIndex &DWARFContext::getTUIndex() {
- if (TUIndex)
- return *TUIndex;
-
- DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
-
- TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
- TUIndex->parse(TUIndexData);
- return *TUIndex;
-}
-
-DWARFGdbIndex &DWARFContext::getGdbIndex() {
- if (GdbIndex)
- return *GdbIndex;
-
- DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
- GdbIndex = std::make_unique<DWARFGdbIndex>();
- GdbIndex->parse(GdbIndexData);
- return *GdbIndex;
-}
-
-const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
- if (Abbrev)
- return Abbrev.get();
-
- DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
-
- Abbrev.reset(new DWARFDebugAbbrev());
- Abbrev->extract(abbrData);
- return Abbrev.get();
-}
-
-const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
- if (AbbrevDWO)
- return AbbrevDWO.get();
-
- DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
- AbbrevDWO.reset(new DWARFDebugAbbrev());
- AbbrevDWO->extract(abbrData);
- return AbbrevDWO.get();
-}
-
-const DWARFDebugLoc *DWARFContext::getDebugLoc() {
- if (Loc)
- return Loc.get();
-
- // Assume all units have the same address byte size.
- auto LocData =
- getNumCompileUnits()
- ? DWARFDataExtractor(*DObj, DObj->getLocSection(), isLittleEndian(),
- getUnitAtIndex(0)->getAddressByteSize())
- : DWARFDataExtractor("", isLittleEndian(), 0);
- Loc.reset(new DWARFDebugLoc(std::move(LocData)));
- return Loc.get();
-}
-
-const DWARFDebugAranges *DWARFContext::getDebugAranges() {
- if (Aranges)
- return Aranges.get();
-
- Aranges.reset(new DWARFDebugAranges());
- Aranges->generate(this);
- return Aranges.get();
-}
-
-Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
- if (DebugFrame)
- return DebugFrame.get();
-
- // There's a "bug" in the DWARFv3 standard with respect to the target address
- // size within debug frame sections. While DWARF is supposed to be independent
- // of its container, FDEs have fields with size being "target address size",
- // which isn't specified in DWARF in general. It's only specified for CUs, but
- // .eh_frame can appear without a .debug_info section. Follow the example of
- // other tools (libdwarf) and extract this from the container (ObjectFile
- // provides this information). This problem is fixed in DWARFv4
- // See this dwarf-discuss discussion for more details:
- // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
- DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(),
- isLittleEndian(), DObj->getAddressSize());
- auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false);
- if (Error E = DF->parse(debugFrameData))
- return std::move(E);
-
- DebugFrame.swap(DF);
- return DebugFrame.get();
-}
-
-Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() {
- if (EHFrame)
- return EHFrame.get();
-
- DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
- isLittleEndian(), DObj->getAddressSize());
-
- auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true);
- if (Error E = DF->parse(debugFrameData))
- return std::move(E);
- DebugFrame.swap(DF);
- return DebugFrame.get();
-}
-
-const DWARFDebugMacro *DWARFContext::getDebugMacro() {
- if (!Macro)
- Macro = parseMacroOrMacinfo(MacroSection);
- return Macro.get();
-}
-
-const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() {
- if (!MacroDWO)
- MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
- return MacroDWO.get();
-}
-
-const DWARFDebugMacro *DWARFContext::getDebugMacinfo() {
- if (!Macinfo)
- Macinfo = parseMacroOrMacinfo(MacinfoSection);
- return Macinfo.get();
-}
-
-const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
- if (!MacinfoDWO)
- MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
- return MacinfoDWO.get();
-}
-
-template <typename T>
-static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
- const DWARFSection &Section, StringRef StringSection,
- bool IsLittleEndian) {
- if (Cache)
- return *Cache;
- DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
- DataExtractor StrData(StringSection, IsLittleEndian, 0);
- Cache.reset(new T(AccelSection, StrData));
- if (Error E = Cache->extract())
- llvm::consumeError(std::move(E));
- return *Cache;
-}
-
-const DWARFDebugNames &DWARFContext::getDebugNames() {
- return getAccelTable(Names, *DObj, DObj->getNamesSection(),
- DObj->getStrSection(), isLittleEndian());
-}
-
-const AppleAcceleratorTable &DWARFContext::getAppleNames() {
- return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
- DObj->getStrSection(), isLittleEndian());
-}
-
-const AppleAcceleratorTable &DWARFContext::getAppleTypes() {
- return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
- DObj->getStrSection(), isLittleEndian());
-}
-
-const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() {
- return getAccelTable(AppleNamespaces, *DObj,
- DObj->getAppleNamespacesSection(),
- DObj->getStrSection(), isLittleEndian());
-}
-
-const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
- return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
- DObj->getStrSection(), isLittleEndian());
-}
-
-const DWARFDebugLine::LineTable *
-DWARFContext::getLineTableForUnit(DWARFUnit *U) {
- Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
- getLineTableForUnit(U, WarningHandler);
- if (!ExpectedLineTable) {
- WarningHandler(ExpectedLineTable.takeError());
- return nullptr;
- }
- return *ExpectedLineTable;
-}
-
-Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
- DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
- if (!Line)
- Line.reset(new DWARFDebugLine);
-
- auto UnitDIE = U->getUnitDIE();
- if (!UnitDIE)
- return nullptr;
-
- auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
- if (!Offset)
- return nullptr; // No line table for this compile unit.
-
- uint64_t stmtOffset = *Offset + U->getLineTableOffset();
- // See if the line table is cached.
- if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
- return lt;
-
- // Make sure the offset is good before we try to parse.
- if (stmtOffset >= U->getLineSection().Data.size())
- return nullptr;
-
- // We have to parse it first.
- DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
- U->getAddressByteSize());
- return Line->getOrParseLineTable(lineData, stmtOffset, *this, U,
- RecoverableErrorHandler);
-}
-
-void DWARFContext::parseNormalUnits() {
- if (!NormalUnits.empty())
- return;
- DObj->forEachInfoSections([&](const DWARFSection &S) {
- NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO);
- });
- NormalUnits.finishedInfoUnits();
- DObj->forEachTypesSections([&](const DWARFSection &S) {
- NormalUnits.addUnitsForSection(*this, S, DW_SECT_EXT_TYPES);
- });
-}
-
-void DWARFContext::parseDWOUnits(bool Lazy) {
- if (!DWOUnits.empty())
- return;
- DObj->forEachInfoDWOSections([&](const DWARFSection &S) {
- DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy);
- });
- DWOUnits.finishedInfoUnits();
- DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
- DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_EXT_TYPES, Lazy);
- });
-}
-
-DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
- parseNormalUnits();
- return dyn_cast_or_null<DWARFCompileUnit>(
- NormalUnits.getUnitForOffset(Offset));
-}
-
-DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
- // First, get the offset of the compile unit.
- uint64_t CUOffset = getDebugAranges()->findAddress(Address);
- // Retrieve the compile unit.
- return getCompileUnitForOffset(CUOffset);
-}
-
-DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
- DIEsForAddress Result;
-
- DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
- if (!CU)
- return Result;
-
- Result.CompileUnit = CU;
- Result.FunctionDIE = CU->getSubroutineForAddress(Address);
-
- std::vector<DWARFDie> Worklist;
- Worklist.push_back(Result.FunctionDIE);
- while (!Worklist.empty()) {
- DWARFDie DIE = Worklist.back();
- Worklist.pop_back();
-
- if (!DIE.isValid())
- continue;
-
- if (DIE.getTag() == DW_TAG_lexical_block &&
- DIE.addressRangeContainsAddress(Address)) {
- Result.BlockDIE = DIE;
- break;
- }
-
- for (auto Child : DIE)
- Worklist.push_back(Child);
- }
-
- return Result;
-}
-
-/// TODO: change input parameter from "uint64_t Address"
-/// into "SectionedAddress Address"
-static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
- uint64_t Address,
- FunctionNameKind Kind,
+
+ if (shouldDump(Explicit, ".debug_addr", DIDT_ID_DebugAddr,
+ DObj->getAddrSection().Data)) {
+ DWARFDataExtractor AddrData(*DObj, DObj->getAddrSection(),
+ isLittleEndian(), 0);
+ dumpAddrSection(OS, AddrData, DumpOpts, getMaxVersion(), getCUAddrSize());
+ }
+
+ if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
+ DObj->getRangesSection().Data)) {
+ uint8_t savedAddressByteSize = getCUAddrSize();
+ DWARFDataExtractor rangesData(*DObj, DObj->getRangesSection(),
+ isLittleEndian(), savedAddressByteSize);
+ uint64_t offset = 0;
+ DWARFDebugRangeList rangeList;
+ while (rangesData.isValidOffset(offset)) {
+ if (Error E = rangeList.extract(rangesData, &offset)) {
+ DumpOpts.RecoverableErrorHandler(std::move(E));
+ break;
+ }
+ rangeList.dump(OS);
+ }
+ }
+
+ auto LookupPooledAddress = [&](uint32_t Index) -> Optional<SectionedAddress> {
+ const auto &CUs = compile_units();
+ auto I = CUs.begin();
+ if (I == CUs.end())
+ return None;
+ return (*I)->getAddrOffsetSectionItem(Index);
+ };
+
+ if (shouldDump(Explicit, ".debug_rnglists", DIDT_ID_DebugRnglists,
+ DObj->getRnglistsSection().Data)) {
+ DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsSection(),
+ isLittleEndian(), 0);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
+ }
+
+ if (shouldDump(ExplicitDWO, ".debug_rnglists.dwo", DIDT_ID_DebugRnglists,
+ DObj->getRnglistsDWOSection().Data)) {
+ DWARFDataExtractor RnglistData(*DObj, DObj->getRnglistsDWOSection(),
+ isLittleEndian(), 0);
+ dumpRnglistsSection(OS, RnglistData, LookupPooledAddress, DumpOpts);
+ }
+
+ if (shouldDump(Explicit, ".debug_pubnames", DIDT_ID_DebugPubnames,
+ DObj->getPubnamesSection().Data)) {
+ DWARFDataExtractor PubTableData(*DObj, DObj->getPubnamesSection(),
+ isLittleEndian(), 0);
+ dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
+ }
+
+ if (shouldDump(Explicit, ".debug_pubtypes", DIDT_ID_DebugPubtypes,
+ DObj->getPubtypesSection().Data)) {
+ DWARFDataExtractor PubTableData(*DObj, DObj->getPubtypesSection(),
+ isLittleEndian(), 0);
+ dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/false);
+ }
+
+ if (shouldDump(Explicit, ".debug_gnu_pubnames", DIDT_ID_DebugGnuPubnames,
+ DObj->getGnuPubnamesSection().Data)) {
+ DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubnamesSection(),
+ isLittleEndian(), 0);
+ dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
+ }
+
+ if (shouldDump(Explicit, ".debug_gnu_pubtypes", DIDT_ID_DebugGnuPubtypes,
+ DObj->getGnuPubtypesSection().Data)) {
+ DWARFDataExtractor PubTableData(*DObj, DObj->getGnuPubtypesSection(),
+ isLittleEndian(), 0);
+ dumpPubTableSection(OS, DumpOpts, PubTableData, /*GnuStyle=*/true);
+ }
+
+ if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets,
+ DObj->getStrOffsetsSection().Data))
+ dumpStringOffsetsSection(
+ OS, DumpOpts, "debug_str_offsets", *DObj, DObj->getStrOffsetsSection(),
+ DObj->getStrSection(), normal_units(), isLittleEndian());
+ if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets,
+ DObj->getStrOffsetsDWOSection().Data))
+ dumpStringOffsetsSection(OS, DumpOpts, "debug_str_offsets.dwo", *DObj,
+ DObj->getStrOffsetsDWOSection(),
+ DObj->getStrDWOSection(), dwo_units(),
+ isLittleEndian());
+
+ if (shouldDump(Explicit, ".gdb_index", DIDT_ID_GdbIndex,
+ DObj->getGdbIndexSection())) {
+ getGdbIndex().dump(OS);
+ }
+
+ if (shouldDump(Explicit, ".apple_names", DIDT_ID_AppleNames,
+ DObj->getAppleNamesSection().Data))
+ getAppleNames().dump(OS);
+
+ if (shouldDump(Explicit, ".apple_types", DIDT_ID_AppleTypes,
+ DObj->getAppleTypesSection().Data))
+ getAppleTypes().dump(OS);
+
+ if (shouldDump(Explicit, ".apple_namespaces", DIDT_ID_AppleNamespaces,
+ DObj->getAppleNamespacesSection().Data))
+ getAppleNamespaces().dump(OS);
+
+ if (shouldDump(Explicit, ".apple_objc", DIDT_ID_AppleObjC,
+ DObj->getAppleObjCSection().Data))
+ getAppleObjC().dump(OS);
+ if (shouldDump(Explicit, ".debug_names", DIDT_ID_DebugNames,
+ DObj->getNamesSection().Data))
+ getDebugNames().dump(OS);
+}
+
+DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
+ parseDWOUnits(LazyParse);
+
+ if (const auto &CUI = getCUIndex()) {
+ if (const auto *R = CUI.getFromHash(Hash))
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ DWOUnits.getUnitForIndexEntry(*R));
+ return nullptr;
+ }
+
+ // If there's no index, just search through the CUs in the DWO - there's
+ // probably only one unless this is something like LTO - though an in-process
+ // built/cached lookup table could be used in that case to improve repeated
+ // lookups of different CUs in the DWO.
+ for (const auto &DWOCU : dwo_compile_units()) {
+ // Might not have parsed DWO ID yet.
+ if (!DWOCU->getDWOId()) {
+ if (Optional<uint64_t> DWOId =
+ toUnsigned(DWOCU->getUnitDIE().find(DW_AT_GNU_dwo_id)))
+ DWOCU->setDWOId(*DWOId);
+ else
+ // No DWO ID?
+ continue;
+ }
+ if (DWOCU->getDWOId() == Hash)
+ return dyn_cast<DWARFCompileUnit>(DWOCU.get());
+ }
+ return nullptr;
+}
+
+DWARFDie DWARFContext::getDIEForOffset(uint64_t Offset) {
+ parseNormalUnits();
+ if (auto *CU = NormalUnits.getUnitForOffset(Offset))
+ return CU->getDIEForOffset(Offset);
+ return DWARFDie();
+}
+
+bool DWARFContext::verify(raw_ostream &OS, DIDumpOptions DumpOpts) {
+ bool Success = true;
+ DWARFVerifier verifier(OS, *this, DumpOpts);
+
+ Success &= verifier.handleDebugAbbrev();
+ if (DumpOpts.DumpType & DIDT_DebugInfo)
+ Success &= verifier.handleDebugInfo();
+ if (DumpOpts.DumpType & DIDT_DebugLine)
+ Success &= verifier.handleDebugLine();
+ Success &= verifier.handleAccelTables();
+ return Success;
+}
+
+const DWARFUnitIndex &DWARFContext::getCUIndex() {
+ if (CUIndex)
+ return *CUIndex;
+
+ DataExtractor CUIndexData(DObj->getCUIndexSection(), isLittleEndian(), 0);
+
+ CUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_INFO);
+ CUIndex->parse(CUIndexData);
+ return *CUIndex;
+}
+
+const DWARFUnitIndex &DWARFContext::getTUIndex() {
+ if (TUIndex)
+ return *TUIndex;
+
+ DataExtractor TUIndexData(DObj->getTUIndexSection(), isLittleEndian(), 0);
+
+ TUIndex = std::make_unique<DWARFUnitIndex>(DW_SECT_EXT_TYPES);
+ TUIndex->parse(TUIndexData);
+ return *TUIndex;
+}
+
+DWARFGdbIndex &DWARFContext::getGdbIndex() {
+ if (GdbIndex)
+ return *GdbIndex;
+
+ DataExtractor GdbIndexData(DObj->getGdbIndexSection(), true /*LE*/, 0);
+ GdbIndex = std::make_unique<DWARFGdbIndex>();
+ GdbIndex->parse(GdbIndexData);
+ return *GdbIndex;
+}
+
+const DWARFDebugAbbrev *DWARFContext::getDebugAbbrev() {
+ if (Abbrev)
+ return Abbrev.get();
+
+ DataExtractor abbrData(DObj->getAbbrevSection(), isLittleEndian(), 0);
+
+ Abbrev.reset(new DWARFDebugAbbrev());
+ Abbrev->extract(abbrData);
+ return Abbrev.get();
+}
+
+const DWARFDebugAbbrev *DWARFContext::getDebugAbbrevDWO() {
+ if (AbbrevDWO)
+ return AbbrevDWO.get();
+
+ DataExtractor abbrData(DObj->getAbbrevDWOSection(), isLittleEndian(), 0);
+ AbbrevDWO.reset(new DWARFDebugAbbrev());
+ AbbrevDWO->extract(abbrData);
+ return AbbrevDWO.get();
+}
+
+const DWARFDebugLoc *DWARFContext::getDebugLoc() {
+ if (Loc)
+ return Loc.get();
+
+ // Assume all units have the same address byte size.
+ auto LocData =
+ getNumCompileUnits()
+ ? DWARFDataExtractor(*DObj, DObj->getLocSection(), isLittleEndian(),
+ getUnitAtIndex(0)->getAddressByteSize())
+ : DWARFDataExtractor("", isLittleEndian(), 0);
+ Loc.reset(new DWARFDebugLoc(std::move(LocData)));
+ return Loc.get();
+}
+
+const DWARFDebugAranges *DWARFContext::getDebugAranges() {
+ if (Aranges)
+ return Aranges.get();
+
+ Aranges.reset(new DWARFDebugAranges());
+ Aranges->generate(this);
+ return Aranges.get();
+}
+
+Expected<const DWARFDebugFrame *> DWARFContext::getDebugFrame() {
+ if (DebugFrame)
+ return DebugFrame.get();
+
+ // There's a "bug" in the DWARFv3 standard with respect to the target address
+ // size within debug frame sections. While DWARF is supposed to be independent
+ // of its container, FDEs have fields with size being "target address size",
+ // which isn't specified in DWARF in general. It's only specified for CUs, but
+ // .eh_frame can appear without a .debug_info section. Follow the example of
+ // other tools (libdwarf) and extract this from the container (ObjectFile
+ // provides this information). This problem is fixed in DWARFv4
+ // See this dwarf-discuss discussion for more details:
+ // http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
+ DWARFDataExtractor debugFrameData(*DObj, DObj->getFrameSection(),
+ isLittleEndian(), DObj->getAddressSize());
+ auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/false);
+ if (Error E = DF->parse(debugFrameData))
+ return std::move(E);
+
+ DebugFrame.swap(DF);
+ return DebugFrame.get();
+}
+
+Expected<const DWARFDebugFrame *> DWARFContext::getEHFrame() {
+ if (EHFrame)
+ return EHFrame.get();
+
+ DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
+ isLittleEndian(), DObj->getAddressSize());
+
+ auto DF = std::make_unique<DWARFDebugFrame>(getArch(), /*IsEH=*/true);
+ if (Error E = DF->parse(debugFrameData))
+ return std::move(E);
+ DebugFrame.swap(DF);
+ return DebugFrame.get();
+}
+
+const DWARFDebugMacro *DWARFContext::getDebugMacro() {
+ if (!Macro)
+ Macro = parseMacroOrMacinfo(MacroSection);
+ return Macro.get();
+}
+
+const DWARFDebugMacro *DWARFContext::getDebugMacroDWO() {
+ if (!MacroDWO)
+ MacroDWO = parseMacroOrMacinfo(MacroDwoSection);
+ return MacroDWO.get();
+}
+
+const DWARFDebugMacro *DWARFContext::getDebugMacinfo() {
+ if (!Macinfo)
+ Macinfo = parseMacroOrMacinfo(MacinfoSection);
+ return Macinfo.get();
+}
+
+const DWARFDebugMacro *DWARFContext::getDebugMacinfoDWO() {
+ if (!MacinfoDWO)
+ MacinfoDWO = parseMacroOrMacinfo(MacinfoDwoSection);
+ return MacinfoDWO.get();
+}
+
+template <typename T>
+static T &getAccelTable(std::unique_ptr<T> &Cache, const DWARFObject &Obj,
+ const DWARFSection &Section, StringRef StringSection,
+ bool IsLittleEndian) {
+ if (Cache)
+ return *Cache;
+ DWARFDataExtractor AccelSection(Obj, Section, IsLittleEndian, 0);
+ DataExtractor StrData(StringSection, IsLittleEndian, 0);
+ Cache.reset(new T(AccelSection, StrData));
+ if (Error E = Cache->extract())
+ llvm::consumeError(std::move(E));
+ return *Cache;
+}
+
+const DWARFDebugNames &DWARFContext::getDebugNames() {
+ return getAccelTable(Names, *DObj, DObj->getNamesSection(),
+ DObj->getStrSection(), isLittleEndian());
+}
+
+const AppleAcceleratorTable &DWARFContext::getAppleNames() {
+ return getAccelTable(AppleNames, *DObj, DObj->getAppleNamesSection(),
+ DObj->getStrSection(), isLittleEndian());
+}
+
+const AppleAcceleratorTable &DWARFContext::getAppleTypes() {
+ return getAccelTable(AppleTypes, *DObj, DObj->getAppleTypesSection(),
+ DObj->getStrSection(), isLittleEndian());
+}
+
+const AppleAcceleratorTable &DWARFContext::getAppleNamespaces() {
+ return getAccelTable(AppleNamespaces, *DObj,
+ DObj->getAppleNamespacesSection(),
+ DObj->getStrSection(), isLittleEndian());
+}
+
+const AppleAcceleratorTable &DWARFContext::getAppleObjC() {
+ return getAccelTable(AppleObjC, *DObj, DObj->getAppleObjCSection(),
+ DObj->getStrSection(), isLittleEndian());
+}
+
+const DWARFDebugLine::LineTable *
+DWARFContext::getLineTableForUnit(DWARFUnit *U) {
+ Expected<const DWARFDebugLine::LineTable *> ExpectedLineTable =
+ getLineTableForUnit(U, WarningHandler);
+ if (!ExpectedLineTable) {
+ WarningHandler(ExpectedLineTable.takeError());
+ return nullptr;
+ }
+ return *ExpectedLineTable;
+}
+
+Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
+ DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
+ if (!Line)
+ Line.reset(new DWARFDebugLine);
+
+ auto UnitDIE = U->getUnitDIE();
+ if (!UnitDIE)
+ return nullptr;
+
+ auto Offset = toSectionOffset(UnitDIE.find(DW_AT_stmt_list));
+ if (!Offset)
+ return nullptr; // No line table for this compile unit.
+
+ uint64_t stmtOffset = *Offset + U->getLineTableOffset();
+ // See if the line table is cached.
+ if (const DWARFLineTable *lt = Line->getLineTable(stmtOffset))
+ return lt;
+
+ // Make sure the offset is good before we try to parse.
+ if (stmtOffset >= U->getLineSection().Data.size())
+ return nullptr;
+
+ // We have to parse it first.
+ DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(),
+ U->getAddressByteSize());
+ return Line->getOrParseLineTable(lineData, stmtOffset, *this, U,
+ RecoverableErrorHandler);
+}
+
+void DWARFContext::parseNormalUnits() {
+ if (!NormalUnits.empty())
+ return;
+ DObj->forEachInfoSections([&](const DWARFSection &S) {
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_INFO);
+ });
+ NormalUnits.finishedInfoUnits();
+ DObj->forEachTypesSections([&](const DWARFSection &S) {
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_EXT_TYPES);
+ });
+}
+
+void DWARFContext::parseDWOUnits(bool Lazy) {
+ if (!DWOUnits.empty())
+ return;
+ DObj->forEachInfoDWOSections([&](const DWARFSection &S) {
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_INFO, Lazy);
+ });
+ DWOUnits.finishedInfoUnits();
+ DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_EXT_TYPES, Lazy);
+ });
+}
+
+DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint64_t Offset) {
+ parseNormalUnits();
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ NormalUnits.getUnitForOffset(Offset));
+}
+
+DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
+ // First, get the offset of the compile unit.
+ uint64_t CUOffset = getDebugAranges()->findAddress(Address);
+ // Retrieve the compile unit.
+ return getCompileUnitForOffset(CUOffset);
+}
+
+DWARFContext::DIEsForAddress DWARFContext::getDIEsForAddress(uint64_t Address) {
+ DIEsForAddress Result;
+
+ DWARFCompileUnit *CU = getCompileUnitForAddress(Address);
+ if (!CU)
+ return Result;
+
+ Result.CompileUnit = CU;
+ Result.FunctionDIE = CU->getSubroutineForAddress(Address);
+
+ std::vector<DWARFDie> Worklist;
+ Worklist.push_back(Result.FunctionDIE);
+ while (!Worklist.empty()) {
+ DWARFDie DIE = Worklist.back();
+ Worklist.pop_back();
+
+ if (!DIE.isValid())
+ continue;
+
+ if (DIE.getTag() == DW_TAG_lexical_block &&
+ DIE.addressRangeContainsAddress(Address)) {
+ Result.BlockDIE = DIE;
+ break;
+ }
+
+ for (auto Child : DIE)
+ Worklist.push_back(Child);
+ }
+
+ return Result;
+}
+
+/// TODO: change input parameter from "uint64_t Address"
+/// into "SectionedAddress Address"
+static bool getFunctionNameAndStartLineForAddress(DWARFCompileUnit *CU,
+ uint64_t Address,
+ FunctionNameKind Kind,
DILineInfoSpecifier::FileLineInfoKind FileNameKind,
- std::string &FunctionName,
+ std::string &FunctionName,
std::string &StartFile,
- uint32_t &StartLine) {
- // The address may correspond to instruction in some inlined function,
- // so we have to build the chain of inlined functions and take the
- // name of the topmost function in it.
- SmallVector<DWARFDie, 4> InlinedChain;
- CU->getInlinedChainForAddress(Address, InlinedChain);
- if (InlinedChain.empty())
- return false;
-
- const DWARFDie &DIE = InlinedChain[0];
- bool FoundResult = false;
- const char *Name = nullptr;
- if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
- FunctionName = Name;
- FoundResult = true;
- }
+ uint32_t &StartLine) {
+ // The address may correspond to instruction in some inlined function,
+ // so we have to build the chain of inlined functions and take the
+ // name of the topmost function in it.
+ SmallVector<DWARFDie, 4> InlinedChain;
+ CU->getInlinedChainForAddress(Address, InlinedChain);
+ if (InlinedChain.empty())
+ return false;
+
+ const DWARFDie &DIE = InlinedChain[0];
+ bool FoundResult = false;
+ const char *Name = nullptr;
+ if (Kind != FunctionNameKind::None && (Name = DIE.getSubroutineName(Kind))) {
+ FunctionName = Name;
+ FoundResult = true;
+ }
std::string DeclFile = DIE.getDeclFile(FileNameKind);
if (!DeclFile.empty()) {
StartFile = DeclFile;
FoundResult = true;
}
- if (auto DeclLineResult = DIE.getDeclLine()) {
- StartLine = DeclLineResult;
- FoundResult = true;
- }
-
- return FoundResult;
-}
-
-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>();
-}
-
-static Optional<int64_t>
-getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
- Optional<unsigned> FrameBaseReg) {
- if (!Expr.empty() &&
- (Expr[0] == DW_OP_fbreg ||
- (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
- unsigned Count;
- int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end());
- // A single DW_OP_fbreg or DW_OP_breg.
- if (Expr.size() == Count + 1)
- return Offset;
- // Same + DW_OP_deref (Fortran arrays look like this).
- if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
- return Offset;
- // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
- }
- return None;
-}
-
-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 (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName))
- Local.FunctionName = Name;
-
- Optional<unsigned> FrameBaseReg;
- if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
- if (Optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
- if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
- (*Expr)[0] <= DW_OP_reg31) {
- FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
- }
-
- if (Expected<std::vector<DWARFLocationExpression>> Loc =
- Die.getLocations(DW_AT_location)) {
- for (const auto &Entry : *Loc) {
- if (Optional<int64_t> FrameOffset =
- getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
- Local.FrameOffset = *FrameOffset;
- break;
- }
- }
- } else {
- // FIXME: missing DW_AT_location is OK here, but other errors should be
- // reported to the user.
- consumeError(Loc.takeError());
- }
-
- 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.Address);
- if (!CU)
- return Result;
-
+ if (auto DeclLineResult = DIE.getDeclLine()) {
+ StartLine = DeclLineResult;
+ FoundResult = true;
+ }
+
+ return FoundResult;
+}
+
+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>();
+}
+
+static Optional<int64_t>
+getExpressionFrameOffset(ArrayRef<uint8_t> Expr,
+ Optional<unsigned> FrameBaseReg) {
+ if (!Expr.empty() &&
+ (Expr[0] == DW_OP_fbreg ||
+ (FrameBaseReg && Expr[0] == DW_OP_breg0 + *FrameBaseReg))) {
+ unsigned Count;
+ int64_t Offset = decodeSLEB128(Expr.data() + 1, &Count, Expr.end());
+ // A single DW_OP_fbreg or DW_OP_breg.
+ if (Expr.size() == Count + 1)
+ return Offset;
+ // Same + DW_OP_deref (Fortran arrays look like this).
+ if (Expr.size() == Count + 2 && Expr[Count + 1] == DW_OP_deref)
+ return Offset;
+ // Fallthrough. Do not accept ex. (DW_OP_breg W29, DW_OP_stack_value)
+ }
+ return None;
+}
+
+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 (const char *Name = Subprogram.getSubroutineName(DINameKind::ShortName))
+ Local.FunctionName = Name;
+
+ Optional<unsigned> FrameBaseReg;
+ if (auto FrameBase = Subprogram.find(DW_AT_frame_base))
+ if (Optional<ArrayRef<uint8_t>> Expr = FrameBase->getAsBlock())
+ if (!Expr->empty() && (*Expr)[0] >= DW_OP_reg0 &&
+ (*Expr)[0] <= DW_OP_reg31) {
+ FrameBaseReg = (*Expr)[0] - DW_OP_reg0;
+ }
+
+ if (Expected<std::vector<DWARFLocationExpression>> Loc =
+ Die.getLocations(DW_AT_location)) {
+ for (const auto &Entry : *Loc) {
+ if (Optional<int64_t> FrameOffset =
+ getExpressionFrameOffset(Entry.Expr, FrameBaseReg)) {
+ Local.FrameOffset = *FrameOffset;
+ break;
+ }
+ }
+ } else {
+ // FIXME: missing DW_AT_location is OK here, but other errors should be
+ // reported to the user.
+ consumeError(Loc.takeError());
+ }
+
+ 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.Address);
+ if (!CU)
+ return Result;
+
getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
Result.FunctionName,
Result.StartFileName, Result.StartLine);
- if (Spec.FLIKind != FileLineInfoKind::None) {
- if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
- LineTable->getFileLineInfoForAddress(
- {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
- Spec.FLIKind, Result);
- }
- }
- return Result;
-}
-
-DILineInfoTable DWARFContext::getLineInfoForAddressRange(
- object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
- DILineInfoTable Lines;
- DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
- if (!CU)
- return Lines;
-
- uint32_t StartLine = 0;
+ if (Spec.FLIKind != FileLineInfoKind::None) {
+ if (const DWARFLineTable *LineTable = getLineTableForUnit(CU)) {
+ LineTable->getFileLineInfoForAddress(
+ {Address.Address, Address.SectionIndex}, CU->getCompilationDir(),
+ Spec.FLIKind, Result);
+ }
+ }
+ return Result;
+}
+
+DILineInfoTable DWARFContext::getLineInfoForAddressRange(
+ object::SectionedAddress Address, uint64_t Size, DILineInfoSpecifier Spec) {
+ DILineInfoTable Lines;
+ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return Lines;
+
+ uint32_t StartLine = 0;
std::string StartFileName;
- std::string FunctionName(DILineInfo::BadString);
+ std::string FunctionName(DILineInfo::BadString);
getFunctionNameAndStartLineForAddress(CU, Address.Address, Spec.FNKind, Spec.FLIKind,
FunctionName, StartFileName, StartLine);
-
- // If the Specifier says we don't need FileLineInfo, just
- // return the top-most function at the starting address.
- if (Spec.FLIKind == FileLineInfoKind::None) {
- DILineInfo Result;
- Result.FunctionName = FunctionName;
+
+ // If the Specifier says we don't need FileLineInfo, just
+ // return the top-most function at the starting address.
+ if (Spec.FLIKind == FileLineInfoKind::None) {
+ DILineInfo Result;
+ Result.FunctionName = FunctionName;
Result.StartFileName = StartFileName;
- Result.StartLine = StartLine;
- Lines.push_back(std::make_pair(Address.Address, Result));
- return Lines;
- }
-
- const DWARFLineTable *LineTable = getLineTableForUnit(CU);
-
- // Get the index of row we're looking for in the line table.
- std::vector<uint32_t> 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.
- const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
- DILineInfo Result;
- LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
- Spec.FLIKind, Result.FileName);
- Result.FunctionName = FunctionName;
- Result.Line = Row.Line;
- Result.Column = Row.Column;
+ Result.StartLine = StartLine;
+ Lines.push_back(std::make_pair(Address.Address, Result));
+ return Lines;
+ }
+
+ const DWARFLineTable *LineTable = getLineTableForUnit(CU);
+
+ // Get the index of row we're looking for in the line table.
+ std::vector<uint32_t> 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.
+ const DWARFDebugLine::Row &Row = LineTable->Rows[RowIndex];
+ DILineInfo Result;
+ LineTable->getFileNameByIndex(Row.File, CU->getCompilationDir(),
+ Spec.FLIKind, Result.FileName);
+ Result.FunctionName = FunctionName;
+ Result.Line = Row.Line;
+ Result.Column = Row.Column;
Result.StartFileName = StartFileName;
- Result.StartLine = StartLine;
- Lines.push_back(std::make_pair(Row.Address.Address, Result));
- }
-
- return Lines;
-}
-
-DIInliningInfo
-DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
- DILineInfoSpecifier Spec) {
- DIInliningInfo InliningInfo;
-
- DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
- if (!CU)
- return InliningInfo;
-
- const DWARFLineTable *LineTable = nullptr;
- SmallVector<DWARFDie, 4> 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.Address, Address.SectionIndex},
- CU->getCompilationDir(), Spec.FLIKind, Frame))
- InliningInfo.addFrame(Frame);
- }
- return InliningInfo;
- }
-
- uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
- for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
- DWARFDie &FunctionDIE = InlinedChain[i];
- DILineInfo Frame;
- // Get function name if necessary.
- if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
- Frame.FunctionName = Name;
- if (auto DeclLineResult = FunctionDIE.getDeclLine())
- Frame.StartLine = DeclLineResult;
+ Result.StartLine = StartLine;
+ Lines.push_back(std::make_pair(Row.Address.Address, Result));
+ }
+
+ return Lines;
+}
+
+DIInliningInfo
+DWARFContext::getInliningInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Spec) {
+ DIInliningInfo InliningInfo;
+
+ DWARFCompileUnit *CU = getCompileUnitForAddress(Address.Address);
+ if (!CU)
+ return InliningInfo;
+
+ const DWARFLineTable *LineTable = nullptr;
+ SmallVector<DWARFDie, 4> 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.Address, Address.SectionIndex},
+ CU->getCompilationDir(), Spec.FLIKind, Frame))
+ InliningInfo.addFrame(Frame);
+ }
+ return InliningInfo;
+ }
+
+ uint32_t CallFile = 0, CallLine = 0, CallColumn = 0, CallDiscriminator = 0;
+ for (uint32_t i = 0, n = InlinedChain.size(); i != n; i++) {
+ DWARFDie &FunctionDIE = InlinedChain[i];
+ DILineInfo Frame;
+ // Get function name if necessary.
+ if (const char *Name = FunctionDIE.getSubroutineName(Spec.FNKind))
+ Frame.FunctionName = Name;
+ if (auto DeclLineResult = FunctionDIE.getDeclLine())
+ Frame.StartLine = DeclLineResult;
Frame.StartFileName = FunctionDIE.getDeclFile(Spec.FLIKind);
- if (Spec.FLIKind != FileLineInfoKind::None) {
- if (i == 0) {
- // For the topmost frame, initialize the line table of this
- // compile unit and fetch file/line info from it.
- LineTable = getLineTableForUnit(CU);
- // For the topmost routine, get file/line info from line table.
- if (LineTable)
- 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.
- if (LineTable)
- LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
- Spec.FLIKind, Frame.FileName);
- Frame.Line = CallLine;
- Frame.Column = CallColumn;
- Frame.Discriminator = CallDiscriminator;
- }
- // Get call file/line/column of a current DIE.
- if (i + 1 < n) {
- FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
- CallDiscriminator);
- }
- }
- InliningInfo.addFrame(Frame);
- }
- return InliningInfo;
-}
-
-std::shared_ptr<DWARFContext>
-DWARFContext::getDWOContext(StringRef AbsolutePath) {
- if (auto S = DWP.lock()) {
- DWARFContext *Ctxt = S->Context.get();
- return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
- }
-
- std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
-
- if (auto S = Entry->lock()) {
- DWARFContext *Ctxt = S->Context.get();
- return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
- }
-
- Expected<OwningBinary<ObjectFile>> Obj = [&] {
- if (!CheckedForDWP) {
- SmallString<128> DWPName;
- auto Obj = object::ObjectFile::createObjectFile(
- this->DWPName.empty()
- ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
- : StringRef(this->DWPName));
- if (Obj) {
- Entry = &DWP;
- return Obj;
- } else {
- CheckedForDWP = true;
- // TODO: Should this error be handled (maybe in a high verbosity mode)
- // before falling back to .dwo files?
- consumeError(Obj.takeError());
- }
- }
-
- return object::ObjectFile::createObjectFile(AbsolutePath);
- }();
-
- if (!Obj) {
- // TODO: Actually report errors helpfully.
- consumeError(Obj.takeError());
- return nullptr;
- }
-
- auto S = std::make_shared<DWOFile>();
- S->File = std::move(Obj.get());
- S->Context = DWARFContext::create(*S->File.getBinary());
- *Entry = S;
- auto *Ctxt = S->Context.get();
- return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
-}
-
-static Error createError(const Twine &Reason, llvm::Error E) {
- return make_error<StringError>(Reason + toString(std::move(E)),
- inconvertibleErrorCode());
-}
-
-/// SymInfo contains information about symbol: it's address
-/// and section index which is -1LL for absolute symbols.
-struct SymInfo {
- uint64_t Address;
- uint64_t SectionIndex;
-};
-
-/// Returns the address of symbol relocation used against and a section index.
-/// Used for futher relocations computation. Symbol's section load address is
-static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
- const RelocationRef &Reloc,
- const LoadedObjectInfo *L,
- std::map<SymbolRef, SymInfo> &Cache) {
- SymInfo Ret = {0, (uint64_t)-1LL};
- object::section_iterator RSec = Obj.section_end();
- object::symbol_iterator Sym = Reloc.getSymbol();
-
- std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
- // First calculate the address of the symbol or section as it appears
- // in the object file
- if (Sym != Obj.symbol_end()) {
- bool New;
- std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
- if (!New)
- return CacheIt->second;
-
- Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
- if (!SymAddrOrErr)
- return createError("failed to compute symbol address: ",
- SymAddrOrErr.takeError());
-
- // Also remember what section this symbol is in for later
- auto SectOrErr = Sym->getSection();
- if (!SectOrErr)
- return createError("failed to get symbol section: ",
- SectOrErr.takeError());
-
- RSec = *SectOrErr;
- Ret.Address = *SymAddrOrErr;
- } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
- RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
- Ret.Address = RSec->getAddress();
- }
-
- if (RSec != Obj.section_end())
- Ret.SectionIndex = RSec->getIndex();
-
- // If we are given load addresses for the sections, we need to adjust:
- // SymAddr = (Address of Symbol Or Section in File) -
- // (Address of Section in File) +
- // (Load Address of Section)
- // RSec is now either the section being targeted or the section
- // containing the symbol being targeted. In either case,
- // we need to perform the same computation.
- if (L && RSec != Obj.section_end())
- if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
- Ret.Address += SectionLoadAddress - RSec->getAddress();
-
- if (CacheIt != Cache.end())
- CacheIt->second = Ret;
-
- return Ret;
-}
-
-static bool isRelocScattered(const object::ObjectFile &Obj,
- const RelocationRef &Reloc) {
- const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
- if (!MachObj)
- return false;
- // MachO also has relocations that point to sections and
- // scattered relocations.
- auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
- return MachObj->isRelocationScattered(RelocInfo);
-}
-
-namespace {
-struct DWARFSectionMap final : public DWARFSection {
- RelocAddrMap Relocs;
-};
-
-class DWARFObjInMemory final : public DWARFObject {
- bool IsLittleEndian;
- uint8_t AddressSize;
- StringRef FileName;
- const object::ObjectFile *Obj = nullptr;
- std::vector<SectionName> SectionNames;
-
- using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
- std::map<object::SectionRef, unsigned>>;
-
- InfoSectionMap InfoSections;
- InfoSectionMap TypesSections;
- InfoSectionMap InfoDWOSections;
- InfoSectionMap TypesDWOSections;
-
- DWARFSectionMap LocSection;
- DWARFSectionMap LoclistsSection;
- DWARFSectionMap LoclistsDWOSection;
- DWARFSectionMap LineSection;
- DWARFSectionMap RangesSection;
- DWARFSectionMap RnglistsSection;
- DWARFSectionMap StrOffsetsSection;
- DWARFSectionMap LineDWOSection;
- DWARFSectionMap FrameSection;
- DWARFSectionMap EHFrameSection;
- DWARFSectionMap LocDWOSection;
- DWARFSectionMap StrOffsetsDWOSection;
- DWARFSectionMap RangesDWOSection;
- DWARFSectionMap RnglistsDWOSection;
- DWARFSectionMap AddrSection;
- DWARFSectionMap AppleNamesSection;
- DWARFSectionMap AppleTypesSection;
- DWARFSectionMap AppleNamespacesSection;
- DWARFSectionMap AppleObjCSection;
- DWARFSectionMap NamesSection;
- DWARFSectionMap PubnamesSection;
- DWARFSectionMap PubtypesSection;
- DWARFSectionMap GnuPubnamesSection;
- DWARFSectionMap GnuPubtypesSection;
- DWARFSectionMap MacroSection;
-
- DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
- return StringSwitch<DWARFSectionMap *>(Name)
- .Case("debug_loc", &LocSection)
- .Case("debug_loclists", &LoclistsSection)
- .Case("debug_loclists.dwo", &LoclistsDWOSection)
- .Case("debug_line", &LineSection)
- .Case("debug_frame", &FrameSection)
- .Case("eh_frame", &EHFrameSection)
- .Case("debug_str_offsets", &StrOffsetsSection)
- .Case("debug_ranges", &RangesSection)
- .Case("debug_rnglists", &RnglistsSection)
- .Case("debug_loc.dwo", &LocDWOSection)
- .Case("debug_line.dwo", &LineDWOSection)
- .Case("debug_names", &NamesSection)
- .Case("debug_rnglists.dwo", &RnglistsDWOSection)
- .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
- .Case("debug_addr", &AddrSection)
- .Case("apple_names", &AppleNamesSection)
- .Case("debug_pubnames", &PubnamesSection)
- .Case("debug_pubtypes", &PubtypesSection)
- .Case("debug_gnu_pubnames", &GnuPubnamesSection)
- .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
- .Case("apple_types", &AppleTypesSection)
- .Case("apple_namespaces", &AppleNamespacesSection)
- .Case("apple_namespac", &AppleNamespacesSection)
- .Case("apple_objc", &AppleObjCSection)
- .Case("debug_macro", &MacroSection)
- .Default(nullptr);
- }
-
- StringRef AbbrevSection;
- StringRef ArangesSection;
- StringRef StrSection;
- StringRef MacinfoSection;
- StringRef MacinfoDWOSection;
- StringRef MacroDWOSection;
- StringRef AbbrevDWOSection;
- StringRef StrDWOSection;
- StringRef CUIndexSection;
- StringRef GdbIndexSection;
- StringRef TUIndexSection;
- StringRef LineStrSection;
-
- // A deque holding section data whose iterators are not invalidated when
- // new decompressed sections are inserted at the end.
- std::deque<SmallString<0>> UncompressedSections;
-
- StringRef *mapSectionToMember(StringRef Name) {
- if (DWARFSection *Sec = mapNameToDWARFSection(Name))
- return &Sec->Data;
- return StringSwitch<StringRef *>(Name)
- .Case("debug_abbrev", &AbbrevSection)
- .Case("debug_aranges", &ArangesSection)
- .Case("debug_str", &StrSection)
- .Case("debug_macinfo", &MacinfoSection)
- .Case("debug_macinfo.dwo", &MacinfoDWOSection)
- .Case("debug_macro.dwo", &MacroDWOSection)
- .Case("debug_abbrev.dwo", &AbbrevDWOSection)
- .Case("debug_str.dwo", &StrDWOSection)
- .Case("debug_cu_index", &CUIndexSection)
- .Case("debug_tu_index", &TUIndexSection)
- .Case("gdb_index", &GdbIndexSection)
- .Case("debug_line_str", &LineStrSection)
- // Any more debug info sections go here.
- .Default(nullptr);
- }
-
- /// If Sec is compressed section, decompresses and updates its contents
- /// provided by Data. Otherwise leaves it unchanged.
- Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
- StringRef &Data) {
- if (!Decompressor::isCompressed(Sec))
- return Error::success();
-
- Expected<Decompressor> Decompressor =
- Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
- if (!Decompressor)
- return Decompressor.takeError();
-
- SmallString<0> Out;
- if (auto Err = Decompressor->resizeAndDecompress(Out))
- return Err;
-
- UncompressedSections.push_back(std::move(Out));
- Data = UncompressedSections.back();
-
- return Error::success();
- }
-
-public:
- DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
- uint8_t AddrSize, bool IsLittleEndian)
- : IsLittleEndian(IsLittleEndian) {
- for (const auto &SecIt : Sections) {
- if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
- *SectionData = SecIt.second->getBuffer();
- else if (SecIt.first() == "debug_info")
- // Find debug_info and debug_types data by section rather than name as
- // there are multiple, comdat grouped, of these sections.
- InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
- else if (SecIt.first() == "debug_info.dwo")
- InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
- else if (SecIt.first() == "debug_types")
- TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
- else if (SecIt.first() == "debug_types.dwo")
- TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
- }
- }
- DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
- function_ref<void(Error)> HandleError, function_ref<void(Error)> HandleWarning )
- : IsLittleEndian(Obj.isLittleEndian()),
- AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
- Obj(&Obj) {
-
- StringMap<unsigned> SectionAmountMap;
- for (const SectionRef &Section : Obj.sections()) {
- StringRef Name;
- if (auto NameOrErr = Section.getName())
- Name = *NameOrErr;
- else
- consumeError(NameOrErr.takeError());
-
- ++SectionAmountMap[Name];
- SectionNames.push_back({ Name, true });
-
- // Skip BSS and Virtual sections, they aren't interesting.
- if (Section.isBSS() || Section.isVirtual())
- continue;
-
- // Skip sections stripped by dsymutil.
- if (Section.isStripped())
- continue;
-
- StringRef Data;
- Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
- if (!SecOrErr) {
- HandleError(createError("failed to get relocated section: ",
- SecOrErr.takeError()));
- continue;
- }
-
- // Try to obtain an already relocated version of this section.
- // Else use the unrelocated section from the object file. We'll have to
- // apply relocations ourselves later.
- section_iterator RelocatedSection = *SecOrErr;
- if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
- Expected<StringRef> E = Section.getContents();
- if (E)
- Data = *E;
- else
- // maybeDecompress below will error.
- consumeError(E.takeError());
- }
-
- if (auto Err = maybeDecompress(Section, Name, Data)) {
- HandleError(createError("failed to decompress '" + Name + "', ",
- std::move(Err)));
- continue;
- }
-
- // Compressed sections names in GNU style starts from ".z",
- // at this point section is decompressed and we drop compression prefix.
- Name = Name.substr(
- Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
-
- // Map platform specific debug section names to DWARF standard section
- // names.
- Name = Obj.mapDebugSectionName(Name);
-
- if (StringRef *SectionData = mapSectionToMember(Name)) {
- *SectionData = Data;
- if (Name == "debug_ranges") {
- // FIXME: Use the other dwo range section when we emit it.
- RangesDWOSection.Data = Data;
- }
+ if (Spec.FLIKind != FileLineInfoKind::None) {
+ if (i == 0) {
+ // For the topmost frame, initialize the line table of this
+ // compile unit and fetch file/line info from it.
+ LineTable = getLineTableForUnit(CU);
+ // For the topmost routine, get file/line info from line table.
+ if (LineTable)
+ 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.
+ if (LineTable)
+ LineTable->getFileNameByIndex(CallFile, CU->getCompilationDir(),
+ Spec.FLIKind, Frame.FileName);
+ Frame.Line = CallLine;
+ Frame.Column = CallColumn;
+ Frame.Discriminator = CallDiscriminator;
+ }
+ // Get call file/line/column of a current DIE.
+ if (i + 1 < n) {
+ FunctionDIE.getCallerFrame(CallFile, CallLine, CallColumn,
+ CallDiscriminator);
+ }
+ }
+ InliningInfo.addFrame(Frame);
+ }
+ return InliningInfo;
+}
+
+std::shared_ptr<DWARFContext>
+DWARFContext::getDWOContext(StringRef AbsolutePath) {
+ if (auto S = DWP.lock()) {
+ DWARFContext *Ctxt = S->Context.get();
+ return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
+ }
+
+ std::weak_ptr<DWOFile> *Entry = &DWOFiles[AbsolutePath];
+
+ if (auto S = Entry->lock()) {
+ DWARFContext *Ctxt = S->Context.get();
+ return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
+ }
+
+ Expected<OwningBinary<ObjectFile>> Obj = [&] {
+ if (!CheckedForDWP) {
+ SmallString<128> DWPName;
+ auto Obj = object::ObjectFile::createObjectFile(
+ this->DWPName.empty()
+ ? (DObj->getFileName() + ".dwp").toStringRef(DWPName)
+ : StringRef(this->DWPName));
+ if (Obj) {
+ Entry = &DWP;
+ return Obj;
+ } else {
+ CheckedForDWP = true;
+ // TODO: Should this error be handled (maybe in a high verbosity mode)
+ // before falling back to .dwo files?
+ consumeError(Obj.takeError());
+ }
+ }
+
+ return object::ObjectFile::createObjectFile(AbsolutePath);
+ }();
+
+ if (!Obj) {
+ // TODO: Actually report errors helpfully.
+ consumeError(Obj.takeError());
+ return nullptr;
+ }
+
+ auto S = std::make_shared<DWOFile>();
+ S->File = std::move(Obj.get());
+ S->Context = DWARFContext::create(*S->File.getBinary());
+ *Entry = S;
+ auto *Ctxt = S->Context.get();
+ return std::shared_ptr<DWARFContext>(std::move(S), Ctxt);
+}
+
+static Error createError(const Twine &Reason, llvm::Error E) {
+ return make_error<StringError>(Reason + toString(std::move(E)),
+ inconvertibleErrorCode());
+}
+
+/// SymInfo contains information about symbol: it's address
+/// and section index which is -1LL for absolute symbols.
+struct SymInfo {
+ uint64_t Address;
+ uint64_t SectionIndex;
+};
+
+/// Returns the address of symbol relocation used against and a section index.
+/// Used for futher relocations computation. Symbol's section load address is
+static Expected<SymInfo> getSymbolInfo(const object::ObjectFile &Obj,
+ const RelocationRef &Reloc,
+ const LoadedObjectInfo *L,
+ std::map<SymbolRef, SymInfo> &Cache) {
+ SymInfo Ret = {0, (uint64_t)-1LL};
+ object::section_iterator RSec = Obj.section_end();
+ object::symbol_iterator Sym = Reloc.getSymbol();
+
+ std::map<SymbolRef, SymInfo>::iterator CacheIt = Cache.end();
+ // First calculate the address of the symbol or section as it appears
+ // in the object file
+ if (Sym != Obj.symbol_end()) {
+ bool New;
+ std::tie(CacheIt, New) = Cache.insert({*Sym, {0, 0}});
+ if (!New)
+ return CacheIt->second;
+
+ Expected<uint64_t> SymAddrOrErr = Sym->getAddress();
+ if (!SymAddrOrErr)
+ return createError("failed to compute symbol address: ",
+ SymAddrOrErr.takeError());
+
+ // Also remember what section this symbol is in for later
+ auto SectOrErr = Sym->getSection();
+ if (!SectOrErr)
+ return createError("failed to get symbol section: ",
+ SectOrErr.takeError());
+
+ RSec = *SectOrErr;
+ Ret.Address = *SymAddrOrErr;
+ } else if (auto *MObj = dyn_cast<MachOObjectFile>(&Obj)) {
+ RSec = MObj->getRelocationSection(Reloc.getRawDataRefImpl());
+ Ret.Address = RSec->getAddress();
+ }
+
+ if (RSec != Obj.section_end())
+ Ret.SectionIndex = RSec->getIndex();
+
+ // If we are given load addresses for the sections, we need to adjust:
+ // SymAddr = (Address of Symbol Or Section in File) -
+ // (Address of Section in File) +
+ // (Load Address of Section)
+ // RSec is now either the section being targeted or the section
+ // containing the symbol being targeted. In either case,
+ // we need to perform the same computation.
+ if (L && RSec != Obj.section_end())
+ if (uint64_t SectionLoadAddress = L->getSectionLoadAddress(*RSec))
+ Ret.Address += SectionLoadAddress - RSec->getAddress();
+
+ if (CacheIt != Cache.end())
+ CacheIt->second = Ret;
+
+ return Ret;
+}
+
+static bool isRelocScattered(const object::ObjectFile &Obj,
+ const RelocationRef &Reloc) {
+ const MachOObjectFile *MachObj = dyn_cast<MachOObjectFile>(&Obj);
+ if (!MachObj)
+ return false;
+ // MachO also has relocations that point to sections and
+ // scattered relocations.
+ auto RelocInfo = MachObj->getRelocation(Reloc.getRawDataRefImpl());
+ return MachObj->isRelocationScattered(RelocInfo);
+}
+
+namespace {
+struct DWARFSectionMap final : public DWARFSection {
+ RelocAddrMap Relocs;
+};
+
+class DWARFObjInMemory final : public DWARFObject {
+ bool IsLittleEndian;
+ uint8_t AddressSize;
+ StringRef FileName;
+ const object::ObjectFile *Obj = nullptr;
+ std::vector<SectionName> SectionNames;
+
+ using InfoSectionMap = MapVector<object::SectionRef, DWARFSectionMap,
+ std::map<object::SectionRef, unsigned>>;
+
+ InfoSectionMap InfoSections;
+ InfoSectionMap TypesSections;
+ InfoSectionMap InfoDWOSections;
+ InfoSectionMap TypesDWOSections;
+
+ DWARFSectionMap LocSection;
+ DWARFSectionMap LoclistsSection;
+ DWARFSectionMap LoclistsDWOSection;
+ DWARFSectionMap LineSection;
+ DWARFSectionMap RangesSection;
+ DWARFSectionMap RnglistsSection;
+ DWARFSectionMap StrOffsetsSection;
+ DWARFSectionMap LineDWOSection;
+ DWARFSectionMap FrameSection;
+ DWARFSectionMap EHFrameSection;
+ DWARFSectionMap LocDWOSection;
+ DWARFSectionMap StrOffsetsDWOSection;
+ DWARFSectionMap RangesDWOSection;
+ DWARFSectionMap RnglistsDWOSection;
+ DWARFSectionMap AddrSection;
+ DWARFSectionMap AppleNamesSection;
+ DWARFSectionMap AppleTypesSection;
+ DWARFSectionMap AppleNamespacesSection;
+ DWARFSectionMap AppleObjCSection;
+ DWARFSectionMap NamesSection;
+ DWARFSectionMap PubnamesSection;
+ DWARFSectionMap PubtypesSection;
+ DWARFSectionMap GnuPubnamesSection;
+ DWARFSectionMap GnuPubtypesSection;
+ DWARFSectionMap MacroSection;
+
+ DWARFSectionMap *mapNameToDWARFSection(StringRef Name) {
+ return StringSwitch<DWARFSectionMap *>(Name)
+ .Case("debug_loc", &LocSection)
+ .Case("debug_loclists", &LoclistsSection)
+ .Case("debug_loclists.dwo", &LoclistsDWOSection)
+ .Case("debug_line", &LineSection)
+ .Case("debug_frame", &FrameSection)
+ .Case("eh_frame", &EHFrameSection)
+ .Case("debug_str_offsets", &StrOffsetsSection)
+ .Case("debug_ranges", &RangesSection)
+ .Case("debug_rnglists", &RnglistsSection)
+ .Case("debug_loc.dwo", &LocDWOSection)
+ .Case("debug_line.dwo", &LineDWOSection)
+ .Case("debug_names", &NamesSection)
+ .Case("debug_rnglists.dwo", &RnglistsDWOSection)
+ .Case("debug_str_offsets.dwo", &StrOffsetsDWOSection)
+ .Case("debug_addr", &AddrSection)
+ .Case("apple_names", &AppleNamesSection)
+ .Case("debug_pubnames", &PubnamesSection)
+ .Case("debug_pubtypes", &PubtypesSection)
+ .Case("debug_gnu_pubnames", &GnuPubnamesSection)
+ .Case("debug_gnu_pubtypes", &GnuPubtypesSection)
+ .Case("apple_types", &AppleTypesSection)
+ .Case("apple_namespaces", &AppleNamespacesSection)
+ .Case("apple_namespac", &AppleNamespacesSection)
+ .Case("apple_objc", &AppleObjCSection)
+ .Case("debug_macro", &MacroSection)
+ .Default(nullptr);
+ }
+
+ StringRef AbbrevSection;
+ StringRef ArangesSection;
+ StringRef StrSection;
+ StringRef MacinfoSection;
+ StringRef MacinfoDWOSection;
+ StringRef MacroDWOSection;
+ StringRef AbbrevDWOSection;
+ StringRef StrDWOSection;
+ StringRef CUIndexSection;
+ StringRef GdbIndexSection;
+ StringRef TUIndexSection;
+ StringRef LineStrSection;
+
+ // A deque holding section data whose iterators are not invalidated when
+ // new decompressed sections are inserted at the end.
+ std::deque<SmallString<0>> UncompressedSections;
+
+ StringRef *mapSectionToMember(StringRef Name) {
+ if (DWARFSection *Sec = mapNameToDWARFSection(Name))
+ return &Sec->Data;
+ return StringSwitch<StringRef *>(Name)
+ .Case("debug_abbrev", &AbbrevSection)
+ .Case("debug_aranges", &ArangesSection)
+ .Case("debug_str", &StrSection)
+ .Case("debug_macinfo", &MacinfoSection)
+ .Case("debug_macinfo.dwo", &MacinfoDWOSection)
+ .Case("debug_macro.dwo", &MacroDWOSection)
+ .Case("debug_abbrev.dwo", &AbbrevDWOSection)
+ .Case("debug_str.dwo", &StrDWOSection)
+ .Case("debug_cu_index", &CUIndexSection)
+ .Case("debug_tu_index", &TUIndexSection)
+ .Case("gdb_index", &GdbIndexSection)
+ .Case("debug_line_str", &LineStrSection)
+ // Any more debug info sections go here.
+ .Default(nullptr);
+ }
+
+ /// If Sec is compressed section, decompresses and updates its contents
+ /// provided by Data. Otherwise leaves it unchanged.
+ Error maybeDecompress(const object::SectionRef &Sec, StringRef Name,
+ StringRef &Data) {
+ if (!Decompressor::isCompressed(Sec))
+ return Error::success();
+
+ Expected<Decompressor> Decompressor =
+ Decompressor::create(Name, Data, IsLittleEndian, AddressSize == 8);
+ if (!Decompressor)
+ return Decompressor.takeError();
+
+ SmallString<0> Out;
+ if (auto Err = Decompressor->resizeAndDecompress(Out))
+ return Err;
+
+ UncompressedSections.push_back(std::move(Out));
+ Data = UncompressedSections.back();
+
+ return Error::success();
+ }
+
+public:
+ DWARFObjInMemory(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+ uint8_t AddrSize, bool IsLittleEndian)
+ : IsLittleEndian(IsLittleEndian) {
+ for (const auto &SecIt : Sections) {
+ if (StringRef *SectionData = mapSectionToMember(SecIt.first()))
+ *SectionData = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_info")
+ // Find debug_info and debug_types data by section rather than name as
+ // there are multiple, comdat grouped, of these sections.
+ InfoSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_info.dwo")
+ InfoDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_types")
+ TypesSections[SectionRef()].Data = SecIt.second->getBuffer();
+ else if (SecIt.first() == "debug_types.dwo")
+ TypesDWOSections[SectionRef()].Data = SecIt.second->getBuffer();
+ }
+ }
+ DWARFObjInMemory(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
+ function_ref<void(Error)> HandleError, function_ref<void(Error)> HandleWarning )
+ : IsLittleEndian(Obj.isLittleEndian()),
+ AddressSize(Obj.getBytesInAddress()), FileName(Obj.getFileName()),
+ Obj(&Obj) {
+
+ StringMap<unsigned> SectionAmountMap;
+ for (const SectionRef &Section : Obj.sections()) {
+ StringRef Name;
+ if (auto NameOrErr = Section.getName())
+ Name = *NameOrErr;
+ else
+ consumeError(NameOrErr.takeError());
+
+ ++SectionAmountMap[Name];
+ SectionNames.push_back({ Name, true });
+
+ // Skip BSS and Virtual sections, they aren't interesting.
+ if (Section.isBSS() || Section.isVirtual())
+ continue;
+
+ // Skip sections stripped by dsymutil.
+ if (Section.isStripped())
+ continue;
+
+ StringRef Data;
+ Expected<section_iterator> SecOrErr = Section.getRelocatedSection();
+ if (!SecOrErr) {
+ HandleError(createError("failed to get relocated section: ",
+ SecOrErr.takeError()));
+ continue;
+ }
+
+ // Try to obtain an already relocated version of this section.
+ // Else use the unrelocated section from the object file. We'll have to
+ // apply relocations ourselves later.
+ section_iterator RelocatedSection = *SecOrErr;
+ if (!L || !L->getLoadedSectionContents(*RelocatedSection, Data)) {
+ Expected<StringRef> E = Section.getContents();
+ if (E)
+ Data = *E;
+ else
+ // maybeDecompress below will error.
+ consumeError(E.takeError());
+ }
+
+ if (auto Err = maybeDecompress(Section, Name, Data)) {
+ HandleError(createError("failed to decompress '" + Name + "', ",
+ std::move(Err)));
+ continue;
+ }
+
+ // Compressed sections names in GNU style starts from ".z",
+ // at this point section is decompressed and we drop compression prefix.
+ Name = Name.substr(
+ Name.find_first_not_of("._z")); // Skip ".", "z" and "_" prefixes.
+
+ // Map platform specific debug section names to DWARF standard section
+ // names.
+ Name = Obj.mapDebugSectionName(Name);
+
+ if (StringRef *SectionData = mapSectionToMember(Name)) {
+ *SectionData = Data;
+ if (Name == "debug_ranges") {
+ // FIXME: Use the other dwo range section when we emit it.
+ RangesDWOSection.Data = Data;
+ }
} else if (InfoSectionMap *Sections =
StringSwitch<InfoSectionMap *>(Name)
.Case("debug_info", &InfoSections)
@@ -1716,288 +1716,288 @@ public:
.Case("debug_types", &TypesSections)
.Case("debug_types.dwo", &TypesDWOSections)
.Default(nullptr)) {
- // Find debug_info and debug_types data by section rather than name as
- // there are multiple, comdat grouped, of these sections.
+ // Find debug_info and debug_types data by section rather than name as
+ // there are multiple, comdat grouped, of these sections.
DWARFSectionMap &S = (*Sections)[Section];
S.Data = Data;
- }
-
- if (RelocatedSection == Obj.section_end())
- continue;
-
- StringRef RelSecName;
- if (auto NameOrErr = RelocatedSection->getName())
- RelSecName = *NameOrErr;
- else
- consumeError(NameOrErr.takeError());
-
- // If the section we're relocating was relocated already by the JIT,
- // then we used the relocated version above, so we do not need to process
- // relocations for it now.
- StringRef RelSecData;
- if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
- continue;
-
- // In Mach-o files, the relocations do not need to be applied if
- // there is no load offset to apply. The value read at the
- // relocation point already factors in the section address
- // (actually applying the relocations will produce wrong results
- // as the section address will be added twice).
- if (!L && isa<MachOObjectFile>(&Obj))
- continue;
-
- RelSecName = RelSecName.substr(
- RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
-
- // TODO: Add support for relocations in other sections as needed.
- // Record relocations for the debug_info and debug_line sections.
- DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
- RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
- if (!Map) {
- // Find debug_info and debug_types relocs by section rather than name
- // as there are multiple, comdat grouped, of these sections.
- if (RelSecName == "debug_info")
- Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
- .Relocs;
- else if (RelSecName == "debug_info.dwo")
- Map = &static_cast<DWARFSectionMap &>(
- InfoDWOSections[*RelocatedSection])
- .Relocs;
- else if (RelSecName == "debug_types")
- Map =
- &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
- .Relocs;
- else if (RelSecName == "debug_types.dwo")
- Map = &static_cast<DWARFSectionMap &>(
- TypesDWOSections[*RelocatedSection])
- .Relocs;
- else
- continue;
- }
-
- if (Section.relocation_begin() == Section.relocation_end())
- continue;
-
- // Symbol to [address, section index] cache mapping.
- std::map<SymbolRef, SymInfo> AddrCache;
+ }
+
+ if (RelocatedSection == Obj.section_end())
+ continue;
+
+ StringRef RelSecName;
+ if (auto NameOrErr = RelocatedSection->getName())
+ RelSecName = *NameOrErr;
+ else
+ consumeError(NameOrErr.takeError());
+
+ // If the section we're relocating was relocated already by the JIT,
+ // then we used the relocated version above, so we do not need to process
+ // relocations for it now.
+ StringRef RelSecData;
+ if (L && L->getLoadedSectionContents(*RelocatedSection, RelSecData))
+ continue;
+
+ // In Mach-o files, the relocations do not need to be applied if
+ // there is no load offset to apply. The value read at the
+ // relocation point already factors in the section address
+ // (actually applying the relocations will produce wrong results
+ // as the section address will be added twice).
+ if (!L && isa<MachOObjectFile>(&Obj))
+ continue;
+
+ RelSecName = RelSecName.substr(
+ RelSecName.find_first_not_of("._z")); // Skip . and _ prefixes.
+
+ // TODO: Add support for relocations in other sections as needed.
+ // Record relocations for the debug_info and debug_line sections.
+ DWARFSectionMap *Sec = mapNameToDWARFSection(RelSecName);
+ RelocAddrMap *Map = Sec ? &Sec->Relocs : nullptr;
+ if (!Map) {
+ // Find debug_info and debug_types relocs by section rather than name
+ // as there are multiple, comdat grouped, of these sections.
+ if (RelSecName == "debug_info")
+ Map = &static_cast<DWARFSectionMap &>(InfoSections[*RelocatedSection])
+ .Relocs;
+ else if (RelSecName == "debug_info.dwo")
+ Map = &static_cast<DWARFSectionMap &>(
+ InfoDWOSections[*RelocatedSection])
+ .Relocs;
+ else if (RelSecName == "debug_types")
+ Map =
+ &static_cast<DWARFSectionMap &>(TypesSections[*RelocatedSection])
+ .Relocs;
+ else if (RelSecName == "debug_types.dwo")
+ Map = &static_cast<DWARFSectionMap &>(
+ TypesDWOSections[*RelocatedSection])
+ .Relocs;
+ else
+ continue;
+ }
+
+ if (Section.relocation_begin() == Section.relocation_end())
+ continue;
+
+ // Symbol to [address, section index] cache mapping.
+ std::map<SymbolRef, SymInfo> AddrCache;
SupportsRelocation Supports;
- 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.
- if (isRelocScattered(Obj, Reloc))
- continue;
-
- Expected<SymInfo> SymInfoOrErr =
- getSymbolInfo(Obj, Reloc, L, AddrCache);
- if (!SymInfoOrErr) {
- HandleError(SymInfoOrErr.takeError());
- continue;
- }
-
- // 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) {
- HandleError(createError(
- "At most two relocations per offset are supported"));
- }
- entry.Reloc2 = Reloc;
- entry.SymbolValue2 = SymInfoOrErr->Address;
- }
- } else {
- SmallString<32> Type;
- Reloc.getTypeName(Type);
- // FIXME: Support more relocations & change this to an error
- HandleWarning(
- createError("failed to compute relocation: " + Type + ", ",
- errorCodeToError(object_error::parse_failed)));
- }
- }
- }
-
- for (SectionName &S : SectionNames)
- if (SectionAmountMap[S.Name] > 1)
- S.IsNameUnique = false;
- }
-
- Optional<RelocAddrEntry> find(const DWARFSection &S,
- uint64_t Pos) const override {
- auto &Sec = static_cast<const DWARFSectionMap &>(S);
- RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
- if (AI == Sec.Relocs.end())
- return None;
- return AI->second;
- }
-
- const object::ObjectFile *getFile() const override { return Obj; }
-
- ArrayRef<SectionName> getSectionNames() const override {
- return SectionNames;
- }
-
- bool isLittleEndian() const override { return IsLittleEndian; }
- StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
- const DWARFSection &getLineDWOSection() const override {
- return LineDWOSection;
- }
- const DWARFSection &getLocDWOSection() const override {
- return LocDWOSection;
- }
- StringRef getStrDWOSection() const override { return StrDWOSection; }
- const DWARFSection &getStrOffsetsDWOSection() const override {
- return StrOffsetsDWOSection;
- }
- const DWARFSection &getRangesDWOSection() const override {
- return RangesDWOSection;
- }
- const DWARFSection &getRnglistsDWOSection() const override {
- return RnglistsDWOSection;
- }
- const DWARFSection &getLoclistsDWOSection() const override {
- return LoclistsDWOSection;
- }
- const DWARFSection &getAddrSection() const override { return AddrSection; }
- StringRef getCUIndexSection() const override { return CUIndexSection; }
- StringRef getGdbIndexSection() const override { return GdbIndexSection; }
- StringRef getTUIndexSection() const override { return TUIndexSection; }
-
- // DWARF v5
- const DWARFSection &getStrOffsetsSection() const override {
- return StrOffsetsSection;
- }
- StringRef getLineStrSection() const override { return LineStrSection; }
-
- // Sections for DWARF5 split dwarf proposal.
- void forEachInfoDWOSections(
- function_ref<void(const DWARFSection &)> F) const override {
- for (auto &P : InfoDWOSections)
- F(P.second);
- }
- void forEachTypesDWOSections(
- function_ref<void(const DWARFSection &)> F) const override {
- for (auto &P : TypesDWOSections)
- F(P.second);
- }
-
- StringRef getAbbrevSection() const override { return AbbrevSection; }
- const DWARFSection &getLocSection() const override { return LocSection; }
- const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
- StringRef getArangesSection() const override { return ArangesSection; }
- const DWARFSection &getFrameSection() const override {
- return FrameSection;
- }
- const DWARFSection &getEHFrameSection() const override {
- return EHFrameSection;
- }
- const DWARFSection &getLineSection() const override { return LineSection; }
- StringRef getStrSection() const override { return StrSection; }
- const DWARFSection &getRangesSection() const override { return RangesSection; }
- const DWARFSection &getRnglistsSection() const override {
- return RnglistsSection;
- }
- const DWARFSection &getMacroSection() const override { return MacroSection; }
- StringRef getMacroDWOSection() const override { return MacroDWOSection; }
- StringRef getMacinfoSection() const override { return MacinfoSection; }
- StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
- const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
- const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
- const DWARFSection &getGnuPubnamesSection() const override {
- return GnuPubnamesSection;
- }
- const DWARFSection &getGnuPubtypesSection() const override {
- return GnuPubtypesSection;
- }
- const DWARFSection &getAppleNamesSection() const override {
- return AppleNamesSection;
- }
- const DWARFSection &getAppleTypesSection() const override {
- return AppleTypesSection;
- }
- const DWARFSection &getAppleNamespacesSection() const override {
- return AppleNamespacesSection;
- }
- const DWARFSection &getAppleObjCSection() const override {
- return AppleObjCSection;
- }
- const DWARFSection &getNamesSection() const override {
- return NamesSection;
- }
-
- StringRef getFileName() const override { return FileName; }
- uint8_t getAddressSize() const override { return AddressSize; }
- void forEachInfoSections(
- function_ref<void(const DWARFSection &)> F) const override {
- for (auto &P : InfoSections)
- F(P.second);
- }
- void forEachTypesSections(
- function_ref<void(const DWARFSection &)> F) const override {
- for (auto &P : TypesSections)
- F(P.second);
- }
-};
-} // namespace
-
-std::unique_ptr<DWARFContext>
-DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
- std::string DWPName,
- std::function<void(Error)> RecoverableErrorHandler,
- std::function<void(Error)> WarningHandler) {
- auto DObj =
- std::make_unique<DWARFObjInMemory>(Obj, L, RecoverableErrorHandler, WarningHandler);
- return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
- RecoverableErrorHandler,
- WarningHandler);
-}
-
-std::unique_ptr<DWARFContext>
-DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
- uint8_t AddrSize, bool isLittleEndian,
- std::function<void(Error)> RecoverableErrorHandler,
- std::function<void(Error)> WarningHandler) {
- auto DObj =
- std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
- return std::make_unique<DWARFContext>(
- std::move(DObj), "", RecoverableErrorHandler, WarningHandler);
-}
-
-Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
- // Detect the architecture from the object file. We usually don't need OS
- // info to lookup a target and create register info.
- Triple TT;
- TT.setArch(Triple::ArchType(Obj.getArch()));
- TT.setVendor(Triple::UnknownVendor);
- TT.setOS(Triple::UnknownOS);
- std::string TargetLookupError;
- const Target *TheTarget =
- TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
- if (!TargetLookupError.empty())
- return createStringError(errc::invalid_argument,
- TargetLookupError.c_str());
- RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
- return Error::success();
-}
-
-uint8_t DWARFContext::getCUAddrSize() {
- // In theory, different compile units may have different address byte
- // sizes, but for simplicity we just use the address byte size of the
- // first compile unit. In practice the address size field is repeated across
- // various DWARF headers (at least in version 5) to make it easier to dump
- // them independently, not to enable varying the address size.
+ 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.
+ if (isRelocScattered(Obj, Reloc))
+ continue;
+
+ Expected<SymInfo> SymInfoOrErr =
+ getSymbolInfo(Obj, Reloc, L, AddrCache);
+ if (!SymInfoOrErr) {
+ HandleError(SymInfoOrErr.takeError());
+ continue;
+ }
+
+ // 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) {
+ HandleError(createError(
+ "At most two relocations per offset are supported"));
+ }
+ entry.Reloc2 = Reloc;
+ entry.SymbolValue2 = SymInfoOrErr->Address;
+ }
+ } else {
+ SmallString<32> Type;
+ Reloc.getTypeName(Type);
+ // FIXME: Support more relocations & change this to an error
+ HandleWarning(
+ createError("failed to compute relocation: " + Type + ", ",
+ errorCodeToError(object_error::parse_failed)));
+ }
+ }
+ }
+
+ for (SectionName &S : SectionNames)
+ if (SectionAmountMap[S.Name] > 1)
+ S.IsNameUnique = false;
+ }
+
+ Optional<RelocAddrEntry> find(const DWARFSection &S,
+ uint64_t Pos) const override {
+ auto &Sec = static_cast<const DWARFSectionMap &>(S);
+ RelocAddrMap::const_iterator AI = Sec.Relocs.find(Pos);
+ if (AI == Sec.Relocs.end())
+ return None;
+ return AI->second;
+ }
+
+ const object::ObjectFile *getFile() const override { return Obj; }
+
+ ArrayRef<SectionName> getSectionNames() const override {
+ return SectionNames;
+ }
+
+ bool isLittleEndian() const override { return IsLittleEndian; }
+ StringRef getAbbrevDWOSection() const override { return AbbrevDWOSection; }
+ const DWARFSection &getLineDWOSection() const override {
+ return LineDWOSection;
+ }
+ const DWARFSection &getLocDWOSection() const override {
+ return LocDWOSection;
+ }
+ StringRef getStrDWOSection() const override { return StrDWOSection; }
+ const DWARFSection &getStrOffsetsDWOSection() const override {
+ return StrOffsetsDWOSection;
+ }
+ const DWARFSection &getRangesDWOSection() const override {
+ return RangesDWOSection;
+ }
+ const DWARFSection &getRnglistsDWOSection() const override {
+ return RnglistsDWOSection;
+ }
+ const DWARFSection &getLoclistsDWOSection() const override {
+ return LoclistsDWOSection;
+ }
+ const DWARFSection &getAddrSection() const override { return AddrSection; }
+ StringRef getCUIndexSection() const override { return CUIndexSection; }
+ StringRef getGdbIndexSection() const override { return GdbIndexSection; }
+ StringRef getTUIndexSection() const override { return TUIndexSection; }
+
+ // DWARF v5
+ const DWARFSection &getStrOffsetsSection() const override {
+ return StrOffsetsSection;
+ }
+ StringRef getLineStrSection() const override { return LineStrSection; }
+
+ // Sections for DWARF5 split dwarf proposal.
+ void forEachInfoDWOSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : InfoDWOSections)
+ F(P.second);
+ }
+ void forEachTypesDWOSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : TypesDWOSections)
+ F(P.second);
+ }
+
+ StringRef getAbbrevSection() const override { return AbbrevSection; }
+ const DWARFSection &getLocSection() const override { return LocSection; }
+ const DWARFSection &getLoclistsSection() const override { return LoclistsSection; }
+ StringRef getArangesSection() const override { return ArangesSection; }
+ const DWARFSection &getFrameSection() const override {
+ return FrameSection;
+ }
+ const DWARFSection &getEHFrameSection() const override {
+ return EHFrameSection;
+ }
+ const DWARFSection &getLineSection() const override { return LineSection; }
+ StringRef getStrSection() const override { return StrSection; }
+ const DWARFSection &getRangesSection() const override { return RangesSection; }
+ const DWARFSection &getRnglistsSection() const override {
+ return RnglistsSection;
+ }
+ const DWARFSection &getMacroSection() const override { return MacroSection; }
+ StringRef getMacroDWOSection() const override { return MacroDWOSection; }
+ StringRef getMacinfoSection() const override { return MacinfoSection; }
+ StringRef getMacinfoDWOSection() const override { return MacinfoDWOSection; }
+ const DWARFSection &getPubnamesSection() const override { return PubnamesSection; }
+ const DWARFSection &getPubtypesSection() const override { return PubtypesSection; }
+ const DWARFSection &getGnuPubnamesSection() const override {
+ return GnuPubnamesSection;
+ }
+ const DWARFSection &getGnuPubtypesSection() const override {
+ return GnuPubtypesSection;
+ }
+ const DWARFSection &getAppleNamesSection() const override {
+ return AppleNamesSection;
+ }
+ const DWARFSection &getAppleTypesSection() const override {
+ return AppleTypesSection;
+ }
+ const DWARFSection &getAppleNamespacesSection() const override {
+ return AppleNamespacesSection;
+ }
+ const DWARFSection &getAppleObjCSection() const override {
+ return AppleObjCSection;
+ }
+ const DWARFSection &getNamesSection() const override {
+ return NamesSection;
+ }
+
+ StringRef getFileName() const override { return FileName; }
+ uint8_t getAddressSize() const override { return AddressSize; }
+ void forEachInfoSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : InfoSections)
+ F(P.second);
+ }
+ void forEachTypesSections(
+ function_ref<void(const DWARFSection &)> F) const override {
+ for (auto &P : TypesSections)
+ F(P.second);
+ }
+};
+} // namespace
+
+std::unique_ptr<DWARFContext>
+DWARFContext::create(const object::ObjectFile &Obj, const LoadedObjectInfo *L,
+ std::string DWPName,
+ std::function<void(Error)> RecoverableErrorHandler,
+ std::function<void(Error)> WarningHandler) {
+ auto DObj =
+ std::make_unique<DWARFObjInMemory>(Obj, L, RecoverableErrorHandler, WarningHandler);
+ return std::make_unique<DWARFContext>(std::move(DObj), std::move(DWPName),
+ RecoverableErrorHandler,
+ WarningHandler);
+}
+
+std::unique_ptr<DWARFContext>
+DWARFContext::create(const StringMap<std::unique_ptr<MemoryBuffer>> &Sections,
+ uint8_t AddrSize, bool isLittleEndian,
+ std::function<void(Error)> RecoverableErrorHandler,
+ std::function<void(Error)> WarningHandler) {
+ auto DObj =
+ std::make_unique<DWARFObjInMemory>(Sections, AddrSize, isLittleEndian);
+ return std::make_unique<DWARFContext>(
+ std::move(DObj), "", RecoverableErrorHandler, WarningHandler);
+}
+
+Error DWARFContext::loadRegisterInfo(const object::ObjectFile &Obj) {
+ // Detect the architecture from the object file. We usually don't need OS
+ // info to lookup a target and create register info.
+ Triple TT;
+ TT.setArch(Triple::ArchType(Obj.getArch()));
+ TT.setVendor(Triple::UnknownVendor);
+ TT.setOS(Triple::UnknownOS);
+ std::string TargetLookupError;
+ const Target *TheTarget =
+ TargetRegistry::lookupTarget(TT.str(), TargetLookupError);
+ if (!TargetLookupError.empty())
+ return createStringError(errc::invalid_argument,
+ TargetLookupError.c_str());
+ RegInfo.reset(TheTarget->createMCRegInfo(TT.str()));
+ return Error::success();
+}
+
+uint8_t DWARFContext::getCUAddrSize() {
+ // In theory, different compile units may have different address byte
+ // sizes, but for simplicity we just use the address byte size of the
+ // first compile unit. In practice the address size field is repeated across
+ // various DWARF headers (at least in version 5) to make it easier to dump
+ // them independently, not to enable varying the address size.
auto CUs = compile_units();
- return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
-}
+ return CUs.empty() ? 0 : (*CUs.begin())->getAddressByteSize();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index da6f6ad903..e640b47d58 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -1,135 +1,135 @@
-//===- DWARFDataExtractor.cpp ---------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-
-using namespace llvm;
-
-std::pair<uint64_t, dwarf::DwarfFormat>
-DWARFDataExtractor::getInitialLength(uint64_t *Off, Error *Err) const {
- ErrorAsOutParameter ErrAsOut(Err);
- if (Err && *Err)
- return {0, dwarf::DWARF32};
-
- Cursor C(*Off);
- uint64_t Length = getRelocatedValue(C, 4);
- dwarf::DwarfFormat Format = dwarf::DWARF32;
- if (Length == dwarf::DW_LENGTH_DWARF64) {
- Length = getRelocatedValue(C, 8);
- Format = dwarf::DWARF64;
- } else if (Length >= dwarf::DW_LENGTH_lo_reserved) {
- cantFail(C.takeError());
- if (Err)
- *Err = createStringError(
- errc::invalid_argument,
- "unsupported reserved unit length of value 0x%8.8" PRIx64, Length);
- return {0, dwarf::DWARF32};
- }
-
- if (C) {
- *Off = C.tell();
- return {Length, Format};
- }
- if (Err)
- *Err = C.takeError();
- else
- consumeError(C.takeError());
- return {0, dwarf::DWARF32};
-}
-
-uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
- uint64_t *SecNdx,
- Error *Err) const {
- if (SecNdx)
- *SecNdx = object::SectionedAddress::UndefSection;
- if (!Section)
- return getUnsigned(Off, Size, Err);
-
- ErrorAsOutParameter ErrAsOut(Err);
- Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
+//===- DWARFDataExtractor.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+
+using namespace llvm;
+
+std::pair<uint64_t, dwarf::DwarfFormat>
+DWARFDataExtractor::getInitialLength(uint64_t *Off, Error *Err) const {
+ ErrorAsOutParameter ErrAsOut(Err);
+ if (Err && *Err)
+ return {0, dwarf::DWARF32};
+
+ Cursor C(*Off);
+ uint64_t Length = getRelocatedValue(C, 4);
+ dwarf::DwarfFormat Format = dwarf::DWARF32;
+ if (Length == dwarf::DW_LENGTH_DWARF64) {
+ Length = getRelocatedValue(C, 8);
+ Format = dwarf::DWARF64;
+ } else if (Length >= dwarf::DW_LENGTH_lo_reserved) {
+ cantFail(C.takeError());
+ if (Err)
+ *Err = createStringError(
+ errc::invalid_argument,
+ "unsupported reserved unit length of value 0x%8.8" PRIx64, Length);
+ return {0, dwarf::DWARF32};
+ }
+
+ if (C) {
+ *Off = C.tell();
+ return {Length, Format};
+ }
+ if (Err)
+ *Err = C.takeError();
+ else
+ consumeError(C.takeError());
+ return {0, dwarf::DWARF32};
+}
+
+uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint64_t *Off,
+ uint64_t *SecNdx,
+ Error *Err) const {
+ if (SecNdx)
+ *SecNdx = object::SectionedAddress::UndefSection;
+ if (!Section)
+ return getUnsigned(Off, Size, Err);
+
+ ErrorAsOutParameter ErrAsOut(Err);
+ Optional<RelocAddrEntry> E = Obj->find(*Section, *Off);
uint64_t LocData = getUnsigned(Off, Size, Err);
- if (!E || (Err && *Err))
+ if (!E || (Err && *Err))
return LocData;
- if (SecNdx)
- *SecNdx = E->SectionIndex;
+ if (SecNdx)
+ *SecNdx = E->SectionIndex;
uint64_t R =
object::resolveRelocation(E->Resolver, E->Reloc, E->SymbolValue, LocData);
- if (E->Reloc2)
+ if (E->Reloc2)
R = object::resolveRelocation(E->Resolver, *E->Reloc2, E->SymbolValue2, R);
- return R;
-}
-
-Optional<uint64_t>
-DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
- uint64_t PCRelOffset) const {
- if (Encoding == dwarf::DW_EH_PE_omit)
- return None;
-
- uint64_t Result = 0;
- uint64_t OldOffset = *Offset;
- // First get value
- switch (Encoding & 0x0F) {
- case dwarf::DW_EH_PE_absptr:
- switch (getAddressSize()) {
- case 2:
- case 4:
- case 8:
- Result = getUnsigned(Offset, getAddressSize());
- break;
- default:
- return None;
- }
- break;
- case dwarf::DW_EH_PE_uleb128:
- Result = getULEB128(Offset);
- break;
- case dwarf::DW_EH_PE_sleb128:
- Result = getSLEB128(Offset);
- break;
- case dwarf::DW_EH_PE_udata2:
- Result = getUnsigned(Offset, 2);
- break;
- case dwarf::DW_EH_PE_udata4:
- Result = getUnsigned(Offset, 4);
- break;
- case dwarf::DW_EH_PE_udata8:
- Result = getUnsigned(Offset, 8);
- break;
- case dwarf::DW_EH_PE_sdata2:
- Result = getSigned(Offset, 2);
- break;
- case dwarf::DW_EH_PE_sdata4:
+ return R;
+}
+
+Optional<uint64_t>
+DWARFDataExtractor::getEncodedPointer(uint64_t *Offset, uint8_t Encoding,
+ uint64_t PCRelOffset) const {
+ if (Encoding == dwarf::DW_EH_PE_omit)
+ return None;
+
+ uint64_t Result = 0;
+ uint64_t OldOffset = *Offset;
+ // First get value
+ switch (Encoding & 0x0F) {
+ case dwarf::DW_EH_PE_absptr:
+ switch (getAddressSize()) {
+ case 2:
+ case 4:
+ case 8:
+ Result = getUnsigned(Offset, getAddressSize());
+ break;
+ default:
+ return None;
+ }
+ break;
+ case dwarf::DW_EH_PE_uleb128:
+ Result = getULEB128(Offset);
+ break;
+ case dwarf::DW_EH_PE_sleb128:
+ Result = getSLEB128(Offset);
+ break;
+ case dwarf::DW_EH_PE_udata2:
+ Result = getUnsigned(Offset, 2);
+ break;
+ case dwarf::DW_EH_PE_udata4:
+ Result = getUnsigned(Offset, 4);
+ break;
+ case dwarf::DW_EH_PE_udata8:
+ Result = getUnsigned(Offset, 8);
+ break;
+ case dwarf::DW_EH_PE_sdata2:
+ Result = getSigned(Offset, 2);
+ break;
+ case dwarf::DW_EH_PE_sdata4:
Result = SignExtend64<32>(getRelocatedValue(4, Offset));
- break;
- case dwarf::DW_EH_PE_sdata8:
+ break;
+ case dwarf::DW_EH_PE_sdata8:
Result = getRelocatedValue(8, Offset);
- break;
- default:
- return None;
- }
- // Then add relative offset, if required
- switch (Encoding & 0x70) {
- case dwarf::DW_EH_PE_absptr:
- // do nothing
- break;
- case dwarf::DW_EH_PE_pcrel:
- Result += PCRelOffset;
- break;
- case dwarf::DW_EH_PE_datarel:
- case dwarf::DW_EH_PE_textrel:
- case dwarf::DW_EH_PE_funcrel:
- case dwarf::DW_EH_PE_aligned:
- default:
- *Offset = OldOffset;
- return None;
- }
-
- return Result;
-}
+ break;
+ default:
+ return None;
+ }
+ // Then add relative offset, if required
+ switch (Encoding & 0x70) {
+ case dwarf::DW_EH_PE_absptr:
+ // do nothing
+ break;
+ case dwarf::DW_EH_PE_pcrel:
+ Result += PCRelOffset;
+ break;
+ case dwarf::DW_EH_PE_datarel:
+ case dwarf::DW_EH_PE_textrel:
+ case dwarf::DW_EH_PE_funcrel:
+ case dwarf::DW_EH_PE_aligned:
+ default:
+ *Offset = OldOffset;
+ return None;
+ }
+
+ return Result;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
index 4afac2f995..3e426d6340 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAbbrev.cpp
@@ -1,138 +1,138 @@
-//===- DWARFDebugAbbrev.cpp -----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cinttypes>
-#include <cstdint>
-
-using namespace llvm;
-
-DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
- clear();
-}
-
-void DWARFAbbreviationDeclarationSet::clear() {
- Offset = 0;
- FirstAbbrCode = 0;
- Decls.clear();
-}
-
-bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
- uint64_t *OffsetPtr) {
- clear();
- const uint64_t BeginOffset = *OffsetPtr;
- Offset = BeginOffset;
- DWARFAbbreviationDeclaration AbbrDecl;
- uint32_t PrevAbbrCode = 0;
- while (AbbrDecl.extract(Data, OffsetPtr)) {
- if (FirstAbbrCode == 0) {
- FirstAbbrCode = AbbrDecl.getCode();
- } else {
- if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
- // Codes are not consecutive, can't do O(1) lookups.
- FirstAbbrCode = UINT32_MAX;
- }
- }
- PrevAbbrCode = AbbrDecl.getCode();
- Decls.push_back(std::move(AbbrDecl));
- }
- return BeginOffset != *OffsetPtr;
-}
-
-void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
- for (const auto &Decl : Decls)
- Decl.dump(OS);
-}
-
-const DWARFAbbreviationDeclaration *
-DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
- uint32_t AbbrCode) const {
- if (FirstAbbrCode == UINT32_MAX) {
- for (const auto &Decl : Decls) {
- if (Decl.getCode() == AbbrCode)
- return &Decl;
- }
- return nullptr;
- }
- if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
- return nullptr;
- return &Decls[AbbrCode - FirstAbbrCode];
-}
-
-DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
-
-void DWARFDebugAbbrev::clear() {
- AbbrDeclSets.clear();
- PrevAbbrOffsetPos = AbbrDeclSets.end();
-}
-
-void DWARFDebugAbbrev::extract(DataExtractor Data) {
- clear();
- this->Data = Data;
-}
-
-void DWARFDebugAbbrev::parse() const {
- if (!Data)
- return;
- uint64_t Offset = 0;
- auto I = AbbrDeclSets.begin();
- while (Data->isValidOffset(Offset)) {
- while (I != AbbrDeclSets.end() && I->first < Offset)
- ++I;
- uint64_t CUAbbrOffset = Offset;
- DWARFAbbreviationDeclarationSet AbbrDecls;
- if (!AbbrDecls.extract(*Data, &Offset))
- break;
- AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
- }
- Data = None;
-}
-
-void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
- parse();
-
- if (AbbrDeclSets.empty()) {
- OS << "< EMPTY >\n";
- return;
- }
-
- for (const auto &I : AbbrDeclSets) {
- OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
- I.second.dump(OS);
- }
-}
-
-const DWARFAbbreviationDeclarationSet*
-DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
- const auto End = AbbrDeclSets.end();
- if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
- return &(PrevAbbrOffsetPos->second);
- }
-
- const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
- if (Pos != End) {
- PrevAbbrOffsetPos = Pos;
- return &(Pos->second);
- }
-
- if (Data && CUAbbrOffset < Data->getData().size()) {
- uint64_t Offset = CUAbbrOffset;
- DWARFAbbreviationDeclarationSet AbbrDecls;
- if (!AbbrDecls.extract(*Data, &Offset))
- return nullptr;
- PrevAbbrOffsetPos =
- AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
- .first;
- return &PrevAbbrOffsetPos->second;
- }
-
- return nullptr;
-}
+//===- DWARFDebugAbbrev.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cinttypes>
+#include <cstdint>
+
+using namespace llvm;
+
+DWARFAbbreviationDeclarationSet::DWARFAbbreviationDeclarationSet() {
+ clear();
+}
+
+void DWARFAbbreviationDeclarationSet::clear() {
+ Offset = 0;
+ FirstAbbrCode = 0;
+ Decls.clear();
+}
+
+bool DWARFAbbreviationDeclarationSet::extract(DataExtractor Data,
+ uint64_t *OffsetPtr) {
+ clear();
+ const uint64_t BeginOffset = *OffsetPtr;
+ Offset = BeginOffset;
+ DWARFAbbreviationDeclaration AbbrDecl;
+ uint32_t PrevAbbrCode = 0;
+ while (AbbrDecl.extract(Data, OffsetPtr)) {
+ if (FirstAbbrCode == 0) {
+ FirstAbbrCode = AbbrDecl.getCode();
+ } else {
+ if (PrevAbbrCode + 1 != AbbrDecl.getCode()) {
+ // Codes are not consecutive, can't do O(1) lookups.
+ FirstAbbrCode = UINT32_MAX;
+ }
+ }
+ PrevAbbrCode = AbbrDecl.getCode();
+ Decls.push_back(std::move(AbbrDecl));
+ }
+ return BeginOffset != *OffsetPtr;
+}
+
+void DWARFAbbreviationDeclarationSet::dump(raw_ostream &OS) const {
+ for (const auto &Decl : Decls)
+ Decl.dump(OS);
+}
+
+const DWARFAbbreviationDeclaration *
+DWARFAbbreviationDeclarationSet::getAbbreviationDeclaration(
+ uint32_t AbbrCode) const {
+ if (FirstAbbrCode == UINT32_MAX) {
+ for (const auto &Decl : Decls) {
+ if (Decl.getCode() == AbbrCode)
+ return &Decl;
+ }
+ return nullptr;
+ }
+ if (AbbrCode < FirstAbbrCode || AbbrCode >= FirstAbbrCode + Decls.size())
+ return nullptr;
+ return &Decls[AbbrCode - FirstAbbrCode];
+}
+
+DWARFDebugAbbrev::DWARFDebugAbbrev() { clear(); }
+
+void DWARFDebugAbbrev::clear() {
+ AbbrDeclSets.clear();
+ PrevAbbrOffsetPos = AbbrDeclSets.end();
+}
+
+void DWARFDebugAbbrev::extract(DataExtractor Data) {
+ clear();
+ this->Data = Data;
+}
+
+void DWARFDebugAbbrev::parse() const {
+ if (!Data)
+ return;
+ uint64_t Offset = 0;
+ auto I = AbbrDeclSets.begin();
+ while (Data->isValidOffset(Offset)) {
+ while (I != AbbrDeclSets.end() && I->first < Offset)
+ ++I;
+ uint64_t CUAbbrOffset = Offset;
+ DWARFAbbreviationDeclarationSet AbbrDecls;
+ if (!AbbrDecls.extract(*Data, &Offset))
+ break;
+ AbbrDeclSets.insert(I, std::make_pair(CUAbbrOffset, std::move(AbbrDecls)));
+ }
+ Data = None;
+}
+
+void DWARFDebugAbbrev::dump(raw_ostream &OS) const {
+ parse();
+
+ if (AbbrDeclSets.empty()) {
+ OS << "< EMPTY >\n";
+ return;
+ }
+
+ for (const auto &I : AbbrDeclSets) {
+ OS << format("Abbrev table for offset: 0x%8.8" PRIx64 "\n", I.first);
+ I.second.dump(OS);
+ }
+}
+
+const DWARFAbbreviationDeclarationSet*
+DWARFDebugAbbrev::getAbbreviationDeclarationSet(uint64_t CUAbbrOffset) const {
+ const auto End = AbbrDeclSets.end();
+ if (PrevAbbrOffsetPos != End && PrevAbbrOffsetPos->first == CUAbbrOffset) {
+ return &(PrevAbbrOffsetPos->second);
+ }
+
+ const auto Pos = AbbrDeclSets.find(CUAbbrOffset);
+ if (Pos != End) {
+ PrevAbbrOffsetPos = Pos;
+ return &(Pos->second);
+ }
+
+ if (Data && CUAbbrOffset < Data->getData().size()) {
+ uint64_t Offset = CUAbbrOffset;
+ DWARFAbbreviationDeclarationSet AbbrDecls;
+ if (!AbbrDecls.extract(*Data, &Offset))
+ return nullptr;
+ PrevAbbrOffsetPos =
+ AbbrDeclSets.insert(std::make_pair(CUAbbrOffset, std::move(AbbrDecls)))
+ .first;
+ return &PrevAbbrOffsetPos->second;
+ }
+
+ return nullptr;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
index dcf2aefeb3..9ce43fbae4 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAddr.cpp
@@ -1,174 +1,174 @@
-//===- DWARFDebugAddr.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-
-using namespace llvm;
-
-Error DWARFDebugAddrTable::extractAddresses(const DWARFDataExtractor &Data,
- uint64_t *OffsetPtr,
- uint64_t EndOffset) {
- assert(EndOffset >= *OffsetPtr);
- uint64_t DataSize = EndOffset - *OffsetPtr;
- assert(Data.isValidOffsetForDataOfSize(*OffsetPtr, DataSize));
- if (AddrSize != 4 && AddrSize != 8)
- return createStringError(errc::not_supported,
- "address table at offset 0x%" PRIx64
- " has unsupported address size %" PRIu8
- " (4 and 8 are supported)",
- Offset, AddrSize);
- if (DataSize % AddrSize != 0) {
- invalidateLength();
- return createStringError(errc::invalid_argument,
- "address table at offset 0x%" PRIx64
- " contains data of size 0x%" PRIx64
- " which is not a multiple of addr size %" PRIu8,
- Offset, DataSize, AddrSize);
- }
- Addrs.clear();
- size_t Count = DataSize / AddrSize;
- Addrs.reserve(Count);
- while (Count--)
- Addrs.push_back(Data.getRelocatedValue(AddrSize, OffsetPtr));
- return Error::success();
-}
-
-Error DWARFDebugAddrTable::extractV5(const DWARFDataExtractor &Data,
- uint64_t *OffsetPtr, uint8_t CUAddrSize,
- std::function<void(Error)> WarnCallback) {
- Offset = *OffsetPtr;
- llvm::Error Err = Error::success();
- std::tie(Length, Format) = Data.getInitialLength(OffsetPtr, &Err);
- if (Err) {
- invalidateLength();
- return createStringError(errc::invalid_argument,
- "parsing address table at offset 0x%" PRIx64
- ": %s",
- Offset, toString(std::move(Err)).c_str());
- }
-
- if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, Length)) {
- uint64_t DiagnosticLength = Length;
- invalidateLength();
- return createStringError(
- errc::invalid_argument,
- "section is not large enough to contain an address table "
- "at offset 0x%" PRIx64 " with a unit_length value of 0x%" PRIx64,
- Offset, DiagnosticLength);
- }
- uint64_t EndOffset = *OffsetPtr + Length;
- // Ensure that we can read the remaining header fields.
- if (Length < 4) {
- uint64_t DiagnosticLength = Length;
- invalidateLength();
- return createStringError(
- errc::invalid_argument,
- "address table at offset 0x%" PRIx64
- " has a unit_length value of 0x%" PRIx64
- ", which is too small to contain a complete header",
- Offset, DiagnosticLength);
- }
-
- Version = Data.getU16(OffsetPtr);
- AddrSize = Data.getU8(OffsetPtr);
- SegSize = Data.getU8(OffsetPtr);
-
- // Perform a basic validation of the header fields.
- if (Version != 5)
- return createStringError(errc::not_supported,
- "address table at offset 0x%" PRIx64
- " has unsupported version %" PRIu16,
- Offset, Version);
- // TODO: add support for non-zero segment selector size.
- if (SegSize != 0)
- return createStringError(errc::not_supported,
- "address table at offset 0x%" PRIx64
- " has unsupported segment selector size %" PRIu8,
- Offset, SegSize);
-
- if (Error Err = extractAddresses(Data, OffsetPtr, EndOffset))
- return Err;
- if (CUAddrSize && AddrSize != CUAddrSize) {
- WarnCallback(createStringError(
- errc::invalid_argument,
- "address table at offset 0x%" PRIx64 " has address size %" PRIu8
- " which is different from CU address size %" PRIu8,
- Offset, AddrSize, CUAddrSize));
- }
- return Error::success();
-}
-
-Error DWARFDebugAddrTable::extractPreStandard(const DWARFDataExtractor &Data,
- uint64_t *OffsetPtr,
- uint16_t CUVersion,
- uint8_t CUAddrSize) {
- assert(CUVersion > 0 && CUVersion < 5);
-
- Offset = *OffsetPtr;
- Length = 0;
- Version = CUVersion;
- AddrSize = CUAddrSize;
- SegSize = 0;
-
- return extractAddresses(Data, OffsetPtr, Data.size());
-}
-
-Error DWARFDebugAddrTable::extract(const DWARFDataExtractor &Data,
- uint64_t *OffsetPtr,
- uint16_t CUVersion,
- uint8_t CUAddrSize,
- std::function<void(Error)> WarnCallback) {
- if (CUVersion > 0 && CUVersion < 5)
- return extractPreStandard(Data, OffsetPtr, CUVersion, CUAddrSize);
- if (CUVersion == 0)
- WarnCallback(createStringError(errc::invalid_argument,
- "DWARF version is not defined in CU,"
- " assuming version 5"));
- return extractV5(Data, OffsetPtr, CUAddrSize, WarnCallback);
-}
-
-void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
- if (DumpOpts.Verbose)
- OS << format("0x%8.8" PRIx64 ": ", Offset);
- if (Length) {
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
- OS << "Address table header: "
- << format("length = 0x%0*" PRIx64, OffsetDumpWidth, Length)
- << ", format = " << dwarf::FormatString(Format)
- << format(", version = 0x%4.4" PRIx16, Version)
- << format(", addr_size = 0x%2.2" PRIx8, AddrSize)
- << format(", seg_size = 0x%2.2" PRIx8, SegSize) << "\n";
- }
-
- if (Addrs.size() > 0) {
- const char *AddrFmt =
- (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";
- }
-}
-
-Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const {
- if (Index < Addrs.size())
- return Addrs[Index];
- return createStringError(errc::invalid_argument,
- "Index %" PRIu32 " is out of range of the "
- "address table at offset 0x%" PRIx64,
- Index, Offset);
-}
-
-Optional<uint64_t> DWARFDebugAddrTable::getFullLength() const {
- if (Length == 0)
- return None;
- return Length + dwarf::getUnitLengthFieldByteSize(Format);
-}
-
+//===- DWARFDebugAddr.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugAddr.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+
+using namespace llvm;
+
+Error DWARFDebugAddrTable::extractAddresses(const DWARFDataExtractor &Data,
+ uint64_t *OffsetPtr,
+ uint64_t EndOffset) {
+ assert(EndOffset >= *OffsetPtr);
+ uint64_t DataSize = EndOffset - *OffsetPtr;
+ assert(Data.isValidOffsetForDataOfSize(*OffsetPtr, DataSize));
+ if (AddrSize != 4 && AddrSize != 8)
+ return createStringError(errc::not_supported,
+ "address table at offset 0x%" PRIx64
+ " has unsupported address size %" PRIu8
+ " (4 and 8 are supported)",
+ Offset, AddrSize);
+ if (DataSize % AddrSize != 0) {
+ invalidateLength();
+ return createStringError(errc::invalid_argument,
+ "address table at offset 0x%" PRIx64
+ " contains data of size 0x%" PRIx64
+ " which is not a multiple of addr size %" PRIu8,
+ Offset, DataSize, AddrSize);
+ }
+ Addrs.clear();
+ size_t Count = DataSize / AddrSize;
+ Addrs.reserve(Count);
+ while (Count--)
+ Addrs.push_back(Data.getRelocatedValue(AddrSize, OffsetPtr));
+ return Error::success();
+}
+
+Error DWARFDebugAddrTable::extractV5(const DWARFDataExtractor &Data,
+ uint64_t *OffsetPtr, uint8_t CUAddrSize,
+ std::function<void(Error)> WarnCallback) {
+ Offset = *OffsetPtr;
+ llvm::Error Err = Error::success();
+ std::tie(Length, Format) = Data.getInitialLength(OffsetPtr, &Err);
+ if (Err) {
+ invalidateLength();
+ return createStringError(errc::invalid_argument,
+ "parsing address table at offset 0x%" PRIx64
+ ": %s",
+ Offset, toString(std::move(Err)).c_str());
+ }
+
+ if (!Data.isValidOffsetForDataOfSize(*OffsetPtr, Length)) {
+ uint64_t DiagnosticLength = Length;
+ invalidateLength();
+ return createStringError(
+ errc::invalid_argument,
+ "section is not large enough to contain an address table "
+ "at offset 0x%" PRIx64 " with a unit_length value of 0x%" PRIx64,
+ Offset, DiagnosticLength);
+ }
+ uint64_t EndOffset = *OffsetPtr + Length;
+ // Ensure that we can read the remaining header fields.
+ if (Length < 4) {
+ uint64_t DiagnosticLength = Length;
+ invalidateLength();
+ return createStringError(
+ errc::invalid_argument,
+ "address table at offset 0x%" PRIx64
+ " has a unit_length value of 0x%" PRIx64
+ ", which is too small to contain a complete header",
+ Offset, DiagnosticLength);
+ }
+
+ Version = Data.getU16(OffsetPtr);
+ AddrSize = Data.getU8(OffsetPtr);
+ SegSize = Data.getU8(OffsetPtr);
+
+ // Perform a basic validation of the header fields.
+ if (Version != 5)
+ return createStringError(errc::not_supported,
+ "address table at offset 0x%" PRIx64
+ " has unsupported version %" PRIu16,
+ Offset, Version);
+ // TODO: add support for non-zero segment selector size.
+ if (SegSize != 0)
+ return createStringError(errc::not_supported,
+ "address table at offset 0x%" PRIx64
+ " has unsupported segment selector size %" PRIu8,
+ Offset, SegSize);
+
+ if (Error Err = extractAddresses(Data, OffsetPtr, EndOffset))
+ return Err;
+ if (CUAddrSize && AddrSize != CUAddrSize) {
+ WarnCallback(createStringError(
+ errc::invalid_argument,
+ "address table at offset 0x%" PRIx64 " has address size %" PRIu8
+ " which is different from CU address size %" PRIu8,
+ Offset, AddrSize, CUAddrSize));
+ }
+ return Error::success();
+}
+
+Error DWARFDebugAddrTable::extractPreStandard(const DWARFDataExtractor &Data,
+ uint64_t *OffsetPtr,
+ uint16_t CUVersion,
+ uint8_t CUAddrSize) {
+ assert(CUVersion > 0 && CUVersion < 5);
+
+ Offset = *OffsetPtr;
+ Length = 0;
+ Version = CUVersion;
+ AddrSize = CUAddrSize;
+ SegSize = 0;
+
+ return extractAddresses(Data, OffsetPtr, Data.size());
+}
+
+Error DWARFDebugAddrTable::extract(const DWARFDataExtractor &Data,
+ uint64_t *OffsetPtr,
+ uint16_t CUVersion,
+ uint8_t CUAddrSize,
+ std::function<void(Error)> WarnCallback) {
+ if (CUVersion > 0 && CUVersion < 5)
+ return extractPreStandard(Data, OffsetPtr, CUVersion, CUAddrSize);
+ if (CUVersion == 0)
+ WarnCallback(createStringError(errc::invalid_argument,
+ "DWARF version is not defined in CU,"
+ " assuming version 5"));
+ return extractV5(Data, OffsetPtr, CUAddrSize, WarnCallback);
+}
+
+void DWARFDebugAddrTable::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
+ if (DumpOpts.Verbose)
+ OS << format("0x%8.8" PRIx64 ": ", Offset);
+ if (Length) {
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
+ OS << "Address table header: "
+ << format("length = 0x%0*" PRIx64, OffsetDumpWidth, Length)
+ << ", format = " << dwarf::FormatString(Format)
+ << format(", version = 0x%4.4" PRIx16, Version)
+ << format(", addr_size = 0x%2.2" PRIx8, AddrSize)
+ << format(", seg_size = 0x%2.2" PRIx8, SegSize) << "\n";
+ }
+
+ if (Addrs.size() > 0) {
+ const char *AddrFmt =
+ (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";
+ }
+}
+
+Expected<uint64_t> DWARFDebugAddrTable::getAddrEntry(uint32_t Index) const {
+ if (Index < Addrs.size())
+ return Addrs[Index];
+ return createStringError(errc::invalid_argument,
+ "Index %" PRIu32 " is out of range of the "
+ "address table at offset 0x%" PRIx64,
+ Index, Offset);
+}
+
+Optional<uint64_t> DWARFDebugAddrTable::getFullLength() const {
+ if (Length == 0)
+ return None;
+ return Length + dwarf::getUnitLengthFieldByteSize(Format);
+}
+
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
index 598e3ecee3..292383f039 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugArangeSet.cpp
@@ -1,179 +1,179 @@
-//===- DWARFDebugArangeSet.cpp --------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
-#include "llvm/BinaryFormat/Dwarf.h"
+//===- DWARFDebugArangeSet.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cassert>
-#include <cinttypes>
-#include <cstdint>
-#include <cstring>
-
-using namespace llvm;
-
-void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS,
- uint32_t AddressSize) const {
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cassert>
+#include <cinttypes>
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+
+void DWARFDebugArangeSet::Descriptor::dump(raw_ostream &OS,
+ uint32_t AddressSize) const {
OS << '[';
DWARFFormValue::dumpAddress(OS, AddressSize, Address);
OS << ", ";
DWARFFormValue::dumpAddress(OS, AddressSize, getEndAddress());
OS << ')';
-}
-
-void DWARFDebugArangeSet::clear() {
- Offset = -1ULL;
- std::memset(&HeaderData, 0, sizeof(Header));
- ArangeDescriptors.clear();
-}
-
-Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
+}
+
+void DWARFDebugArangeSet::clear() {
+ Offset = -1ULL;
+ std::memset(&HeaderData, 0, sizeof(Header));
+ ArangeDescriptors.clear();
+}
+
+Error DWARFDebugArangeSet::extract(DWARFDataExtractor data,
uint64_t *offset_ptr,
function_ref<void(Error)> WarningHandler) {
- assert(data.isValidOffset(*offset_ptr));
- ArangeDescriptors.clear();
- Offset = *offset_ptr;
-
- // 7.21 Address Range Table (extract)
- // Each set of entries in the table of address ranges contained in
- // the .debug_aranges section begins with a header containing:
- // 1. unit_length (initial length)
- // A 4-byte (32-bit DWARF) or 12-byte (64-bit DWARF) length containing
- // the length of the set of entries for this compilation unit,
- // not including the length field itself.
- // 2. version (uhalf)
- // The value in this field is 2.
- // 3. debug_info_offset (section offset)
- // A 4-byte (32-bit DWARF) or 8-byte (64-bit DWARF) offset into the
- // .debug_info section of the compilation unit header.
- // 4. address_size (ubyte)
- // 5. segment_selector_size (ubyte)
- // This header is followed by a series of tuples. Each tuple consists of
- // a segment, an address and a length. The segment selector size is given by
- // the segment_selector_size field of the header; the address and length
- // size are each given by the address_size field of the header. Each set of
- // tuples is terminated by a 0 for the segment, a 0 for the address and 0
- // for the length. If the segment_selector_size field in the header is zero,
- // the segment selectors are omitted from all tuples, including
- // the terminating tuple.
-
- Error Err = Error::success();
- std::tie(HeaderData.Length, HeaderData.Format) =
- data.getInitialLength(offset_ptr, &Err);
- HeaderData.Version = data.getU16(offset_ptr, &Err);
- HeaderData.CuOffset = data.getUnsigned(
- offset_ptr, dwarf::getDwarfOffsetByteSize(HeaderData.Format), &Err);
- HeaderData.AddrSize = data.getU8(offset_ptr, &Err);
- HeaderData.SegSize = data.getU8(offset_ptr, &Err);
- if (Err) {
- return createStringError(errc::invalid_argument,
- "parsing address ranges table at offset 0x%" PRIx64
- ": %s",
- Offset, toString(std::move(Err)).c_str());
- }
-
- // Perform basic validation of the header fields.
- uint64_t full_length =
- dwarf::getUnitLengthFieldByteSize(HeaderData.Format) + HeaderData.Length;
- if (!data.isValidOffsetForDataOfSize(Offset, full_length))
- return createStringError(errc::invalid_argument,
- "the length of address range table at offset "
- "0x%" PRIx64 " exceeds section size",
- Offset);
- if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
- return createStringError(errc::invalid_argument,
- "address range table at offset 0x%" PRIx64
- " has unsupported address size: %d "
- "(4 and 8 supported)",
- Offset, HeaderData.AddrSize);
- if (HeaderData.SegSize != 0)
- return createStringError(errc::not_supported,
- "non-zero segment selector size in address range "
- "table at offset 0x%" PRIx64 " is not supported",
- Offset);
-
- // The first tuple following the header in each set begins at an offset that
- // is a multiple of the size of a single tuple (that is, twice the size of
- // an address because we do not support non-zero segment selector sizes).
- // Therefore, the full length should also be a multiple of the tuple size.
- const uint32_t tuple_size = HeaderData.AddrSize * 2;
- if (full_length % tuple_size != 0)
- return createStringError(
- errc::invalid_argument,
- "address range table at offset 0x%" PRIx64
- " has length that is not a multiple of the tuple size",
- Offset);
-
- // The header is padded, if necessary, to the appropriate boundary.
- const uint32_t header_size = *offset_ptr - Offset;
- uint32_t first_tuple_offset = 0;
- while (first_tuple_offset < header_size)
- first_tuple_offset += tuple_size;
-
- // There should be space for at least one tuple.
- if (full_length <= first_tuple_offset)
- return createStringError(
- errc::invalid_argument,
- "address range table at offset 0x%" PRIx64
- " has an insufficient length to contain any entries",
- Offset);
-
- *offset_ptr = Offset + first_tuple_offset;
-
- Descriptor arangeDescriptor;
-
- static_assert(sizeof(arangeDescriptor.Address) ==
- sizeof(arangeDescriptor.Length),
- "Different datatypes for addresses and sizes!");
- assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize);
-
- uint64_t end_offset = Offset + full_length;
- while (*offset_ptr < end_offset) {
- uint64_t EntryOffset = *offset_ptr;
- arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
- arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
-
- // Each set of tuples is terminated by a 0 for the address and 0
- // for the length.
- if (arangeDescriptor.Length == 0 && arangeDescriptor.Address == 0) {
- if (*offset_ptr == end_offset)
- return ErrorSuccess();
+ assert(data.isValidOffset(*offset_ptr));
+ ArangeDescriptors.clear();
+ Offset = *offset_ptr;
+
+ // 7.21 Address Range Table (extract)
+ // Each set of entries in the table of address ranges contained in
+ // the .debug_aranges section begins with a header containing:
+ // 1. unit_length (initial length)
+ // A 4-byte (32-bit DWARF) or 12-byte (64-bit DWARF) length containing
+ // the length of the set of entries for this compilation unit,
+ // not including the length field itself.
+ // 2. version (uhalf)
+ // The value in this field is 2.
+ // 3. debug_info_offset (section offset)
+ // A 4-byte (32-bit DWARF) or 8-byte (64-bit DWARF) offset into the
+ // .debug_info section of the compilation unit header.
+ // 4. address_size (ubyte)
+ // 5. segment_selector_size (ubyte)
+ // This header is followed by a series of tuples. Each tuple consists of
+ // a segment, an address and a length. The segment selector size is given by
+ // the segment_selector_size field of the header; the address and length
+ // size are each given by the address_size field of the header. Each set of
+ // tuples is terminated by a 0 for the segment, a 0 for the address and 0
+ // for the length. If the segment_selector_size field in the header is zero,
+ // the segment selectors are omitted from all tuples, including
+ // the terminating tuple.
+
+ Error Err = Error::success();
+ std::tie(HeaderData.Length, HeaderData.Format) =
+ data.getInitialLength(offset_ptr, &Err);
+ HeaderData.Version = data.getU16(offset_ptr, &Err);
+ HeaderData.CuOffset = data.getUnsigned(
+ offset_ptr, dwarf::getDwarfOffsetByteSize(HeaderData.Format), &Err);
+ HeaderData.AddrSize = data.getU8(offset_ptr, &Err);
+ HeaderData.SegSize = data.getU8(offset_ptr, &Err);
+ if (Err) {
+ return createStringError(errc::invalid_argument,
+ "parsing address ranges table at offset 0x%" PRIx64
+ ": %s",
+ Offset, toString(std::move(Err)).c_str());
+ }
+
+ // Perform basic validation of the header fields.
+ uint64_t full_length =
+ dwarf::getUnitLengthFieldByteSize(HeaderData.Format) + HeaderData.Length;
+ if (!data.isValidOffsetForDataOfSize(Offset, full_length))
+ return createStringError(errc::invalid_argument,
+ "the length of address range table at offset "
+ "0x%" PRIx64 " exceeds section size",
+ Offset);
+ if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
+ return createStringError(errc::invalid_argument,
+ "address range table at offset 0x%" PRIx64
+ " has unsupported address size: %d "
+ "(4 and 8 supported)",
+ Offset, HeaderData.AddrSize);
+ if (HeaderData.SegSize != 0)
+ return createStringError(errc::not_supported,
+ "non-zero segment selector size in address range "
+ "table at offset 0x%" PRIx64 " is not supported",
+ Offset);
+
+ // The first tuple following the header in each set begins at an offset that
+ // is a multiple of the size of a single tuple (that is, twice the size of
+ // an address because we do not support non-zero segment selector sizes).
+ // Therefore, the full length should also be a multiple of the tuple size.
+ const uint32_t tuple_size = HeaderData.AddrSize * 2;
+ if (full_length % tuple_size != 0)
+ return createStringError(
+ errc::invalid_argument,
+ "address range table at offset 0x%" PRIx64
+ " has length that is not a multiple of the tuple size",
+ Offset);
+
+ // The header is padded, if necessary, to the appropriate boundary.
+ const uint32_t header_size = *offset_ptr - Offset;
+ uint32_t first_tuple_offset = 0;
+ while (first_tuple_offset < header_size)
+ first_tuple_offset += tuple_size;
+
+ // There should be space for at least one tuple.
+ if (full_length <= first_tuple_offset)
+ return createStringError(
+ errc::invalid_argument,
+ "address range table at offset 0x%" PRIx64
+ " has an insufficient length to contain any entries",
+ Offset);
+
+ *offset_ptr = Offset + first_tuple_offset;
+
+ Descriptor arangeDescriptor;
+
+ static_assert(sizeof(arangeDescriptor.Address) ==
+ sizeof(arangeDescriptor.Length),
+ "Different datatypes for addresses and sizes!");
+ assert(sizeof(arangeDescriptor.Address) >= HeaderData.AddrSize);
+
+ uint64_t end_offset = Offset + full_length;
+ while (*offset_ptr < end_offset) {
+ uint64_t EntryOffset = *offset_ptr;
+ arangeDescriptor.Address = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
+ arangeDescriptor.Length = data.getUnsigned(offset_ptr, HeaderData.AddrSize);
+
+ // Each set of tuples is terminated by a 0 for the address and 0
+ // for the length.
+ if (arangeDescriptor.Length == 0 && arangeDescriptor.Address == 0) {
+ if (*offset_ptr == end_offset)
+ return ErrorSuccess();
WarningHandler(createStringError(
- errc::invalid_argument,
- "address range table at offset 0x%" PRIx64
- " has a premature terminator entry at offset 0x%" PRIx64,
+ errc::invalid_argument,
+ "address range table at offset 0x%" PRIx64
+ " has a premature terminator entry at offset 0x%" PRIx64,
Offset, EntryOffset));
- }
-
- ArangeDescriptors.push_back(arangeDescriptor);
- }
-
- return createStringError(errc::invalid_argument,
- "address range table at offset 0x%" PRIx64
- " is not terminated by null entry",
- Offset);
-}
-
-void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(HeaderData.Format);
- OS << "Address Range Header: "
- << format("length = 0x%0*" PRIx64 ", ", OffsetDumpWidth, HeaderData.Length)
- << "format = " << dwarf::FormatString(HeaderData.Format) << ", "
- << format("version = 0x%4.4x, ", HeaderData.Version)
- << format("cu_offset = 0x%0*" PRIx64 ", ", OffsetDumpWidth,
- HeaderData.CuOffset)
- << format("addr_size = 0x%2.2x, ", HeaderData.AddrSize)
- << format("seg_size = 0x%2.2x\n", HeaderData.SegSize);
-
- for (const auto &Desc : ArangeDescriptors) {
- Desc.dump(OS, HeaderData.AddrSize);
- OS << '\n';
- }
-}
+ }
+
+ ArangeDescriptors.push_back(arangeDescriptor);
+ }
+
+ return createStringError(errc::invalid_argument,
+ "address range table at offset 0x%" PRIx64
+ " is not terminated by null entry",
+ Offset);
+}
+
+void DWARFDebugArangeSet::dump(raw_ostream &OS) const {
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(HeaderData.Format);
+ OS << "Address Range Header: "
+ << format("length = 0x%0*" PRIx64 ", ", OffsetDumpWidth, HeaderData.Length)
+ << "format = " << dwarf::FormatString(HeaderData.Format) << ", "
+ << format("version = 0x%4.4x, ", HeaderData.Version)
+ << format("cu_offset = 0x%0*" PRIx64 ", ", OffsetDumpWidth,
+ HeaderData.CuOffset)
+ << format("addr_size = 0x%2.2x, ", HeaderData.AddrSize)
+ << format("seg_size = 0x%2.2x\n", HeaderData.SegSize);
+
+ for (const auto &Desc : ArangeDescriptors) {
+ Desc.dump(OS, HeaderData.AddrSize);
+ OS << '\n';
+ }
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
index e0db469752..57367b3948 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugAranges.cpp
@@ -1,128 +1,128 @@
-//===- DWARFDebugAranges.cpp ----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
-#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
-#include "llvm/Support/DataExtractor.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <set>
-#include <vector>
-
-using namespace llvm;
-
-void DWARFDebugAranges::extract(
- DWARFDataExtractor DebugArangesData,
- function_ref<void(Error)> RecoverableErrorHandler) {
- if (!DebugArangesData.isValidOffset(0))
- return;
- uint64_t Offset = 0;
- DWARFDebugArangeSet Set;
-
- while (DebugArangesData.isValidOffset(Offset)) {
+//===- DWARFDebugAranges.cpp ----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
+#include "llvm/Support/DataExtractor.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <set>
+#include <vector>
+
+using namespace llvm;
+
+void DWARFDebugAranges::extract(
+ DWARFDataExtractor DebugArangesData,
+ function_ref<void(Error)> RecoverableErrorHandler) {
+ if (!DebugArangesData.isValidOffset(0))
+ return;
+ uint64_t Offset = 0;
+ DWARFDebugArangeSet Set;
+
+ while (DebugArangesData.isValidOffset(Offset)) {
if (Error E =
Set.extract(DebugArangesData, &Offset, RecoverableErrorHandler)) {
- RecoverableErrorHandler(std::move(E));
- return;
- }
- uint64_t CUOffset = Set.getCompileUnitDIEOffset();
- for (const auto &Desc : Set.descriptors()) {
- uint64_t LowPC = Desc.Address;
- uint64_t HighPC = Desc.getEndAddress();
- appendRange(CUOffset, LowPC, HighPC);
- }
- ParsedCUOffsets.insert(CUOffset);
- }
-}
-
-void DWARFDebugAranges::generate(DWARFContext *CTX) {
- clear();
- if (!CTX)
- return;
-
- // Extract aranges from .debug_aranges section.
- DWARFDataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(),
- CTX->isLittleEndian(), 0);
- extract(ArangesData, CTX->getRecoverableErrorHandler());
-
- // Generate aranges from DIEs: even if .debug_aranges section is present,
- // it may describe only a small subset of compilation units, so we need to
- // manually build aranges for the rest of them.
- for (const auto &CU : CTX->compile_units()) {
- uint64_t CUOffset = CU->getOffset();
- if (ParsedCUOffsets.insert(CUOffset).second) {
- Expected<DWARFAddressRangesVector> CURanges = CU->collectAddressRanges();
- if (!CURanges)
- CTX->getRecoverableErrorHandler()(CURanges.takeError());
- else
- for (const auto &R : *CURanges)
- appendRange(CUOffset, R.LowPC, R.HighPC);
- }
- }
-
- construct();
-}
-
-void DWARFDebugAranges::clear() {
- Endpoints.clear();
- Aranges.clear();
- ParsedCUOffsets.clear();
-}
-
-void DWARFDebugAranges::appendRange(uint64_t CUOffset, uint64_t LowPC,
- uint64_t HighPC) {
- if (LowPC >= HighPC)
- return;
- Endpoints.emplace_back(LowPC, CUOffset, true);
- Endpoints.emplace_back(HighPC, CUOffset, false);
-}
-
-void DWARFDebugAranges::construct() {
- std::multiset<uint64_t> ValidCUs; // Maintain the set of CUs describing
- // a current address range.
- llvm::sort(Endpoints);
- uint64_t PrevAddress = -1ULL;
- for (const auto &E : Endpoints) {
- if (PrevAddress < E.Address && !ValidCUs.empty()) {
- // If the address range between two endpoints is described by some
- // CU, first try to extend the last range in Aranges. If we can't
- // do it, start a new range.
- if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress &&
- ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) {
- Aranges.back().setHighPC(E.Address);
- } else {
- Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin());
- }
- }
- // Update the set of valid CUs.
- if (E.IsRangeStart) {
- ValidCUs.insert(E.CUOffset);
- } else {
- auto CUPos = ValidCUs.find(E.CUOffset);
- assert(CUPos != ValidCUs.end());
- ValidCUs.erase(CUPos);
- }
- PrevAddress = E.Address;
- }
- assert(ValidCUs.empty());
-
- // Endpoints are not needed now.
- Endpoints.clear();
- Endpoints.shrink_to_fit();
-}
-
-uint64_t DWARFDebugAranges::findAddress(uint64_t Address) const {
- RangeCollIterator It =
- partition_point(Aranges, [=](Range R) { return R.HighPC() <= Address; });
- if (It != Aranges.end() && It->LowPC <= Address)
- return It->CUOffset;
- return -1ULL;
-}
+ RecoverableErrorHandler(std::move(E));
+ return;
+ }
+ uint64_t CUOffset = Set.getCompileUnitDIEOffset();
+ for (const auto &Desc : Set.descriptors()) {
+ uint64_t LowPC = Desc.Address;
+ uint64_t HighPC = Desc.getEndAddress();
+ appendRange(CUOffset, LowPC, HighPC);
+ }
+ ParsedCUOffsets.insert(CUOffset);
+ }
+}
+
+void DWARFDebugAranges::generate(DWARFContext *CTX) {
+ clear();
+ if (!CTX)
+ return;
+
+ // Extract aranges from .debug_aranges section.
+ DWARFDataExtractor ArangesData(CTX->getDWARFObj().getArangesSection(),
+ CTX->isLittleEndian(), 0);
+ extract(ArangesData, CTX->getRecoverableErrorHandler());
+
+ // Generate aranges from DIEs: even if .debug_aranges section is present,
+ // it may describe only a small subset of compilation units, so we need to
+ // manually build aranges for the rest of them.
+ for (const auto &CU : CTX->compile_units()) {
+ uint64_t CUOffset = CU->getOffset();
+ if (ParsedCUOffsets.insert(CUOffset).second) {
+ Expected<DWARFAddressRangesVector> CURanges = CU->collectAddressRanges();
+ if (!CURanges)
+ CTX->getRecoverableErrorHandler()(CURanges.takeError());
+ else
+ for (const auto &R : *CURanges)
+ appendRange(CUOffset, R.LowPC, R.HighPC);
+ }
+ }
+
+ construct();
+}
+
+void DWARFDebugAranges::clear() {
+ Endpoints.clear();
+ Aranges.clear();
+ ParsedCUOffsets.clear();
+}
+
+void DWARFDebugAranges::appendRange(uint64_t CUOffset, uint64_t LowPC,
+ uint64_t HighPC) {
+ if (LowPC >= HighPC)
+ return;
+ Endpoints.emplace_back(LowPC, CUOffset, true);
+ Endpoints.emplace_back(HighPC, CUOffset, false);
+}
+
+void DWARFDebugAranges::construct() {
+ std::multiset<uint64_t> ValidCUs; // Maintain the set of CUs describing
+ // a current address range.
+ llvm::sort(Endpoints);
+ uint64_t PrevAddress = -1ULL;
+ for (const auto &E : Endpoints) {
+ if (PrevAddress < E.Address && !ValidCUs.empty()) {
+ // If the address range between two endpoints is described by some
+ // CU, first try to extend the last range in Aranges. If we can't
+ // do it, start a new range.
+ if (!Aranges.empty() && Aranges.back().HighPC() == PrevAddress &&
+ ValidCUs.find(Aranges.back().CUOffset) != ValidCUs.end()) {
+ Aranges.back().setHighPC(E.Address);
+ } else {
+ Aranges.emplace_back(PrevAddress, E.Address, *ValidCUs.begin());
+ }
+ }
+ // Update the set of valid CUs.
+ if (E.IsRangeStart) {
+ ValidCUs.insert(E.CUOffset);
+ } else {
+ auto CUPos = ValidCUs.find(E.CUOffset);
+ assert(CUPos != ValidCUs.end());
+ ValidCUs.erase(CUPos);
+ }
+ PrevAddress = E.Address;
+ }
+ assert(ValidCUs.empty());
+
+ // Endpoints are not needed now.
+ Endpoints.clear();
+ Endpoints.shrink_to_fit();
+}
+
+uint64_t DWARFDebugAranges::findAddress(uint64_t Address) const {
+ RangeCollIterator It =
+ partition_point(Aranges, [=](Range R) { return R.HighPC() <= Address; });
+ if (It != Aranges.end() && It->LowPC <= Address)
+ return It->CUOffset;
+ return -1ULL;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
index b74ecac681..6a6749c33c 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
@@ -1,35 +1,35 @@
-//===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===//
-//
-// 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/DWARFDebugFrame.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/Dwarf.h"
+//===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===//
+//
+// 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/DWARFDebugFrame.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <cinttypes>
-#include <cstdint>
-#include <string>
-#include <vector>
-
-using namespace llvm;
-using namespace dwarf;
-
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cinttypes>
+#include <cstdint>
+#include <string>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+
static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
unsigned RegNum) {
if (MRI) {
@@ -42,575 +42,575 @@ static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
}
OS << "reg" << RegNum;
}
-
-// See DWARF standard v3, section 7.23
-const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
-const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
-
-Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
- uint64_t EndOffset) {
- DataExtractor::Cursor C(*Offset);
- while (C && C.tell() < EndOffset) {
- uint8_t Opcode = Data.getRelocatedValue(C, 1);
- if (!C)
- break;
-
- // Some instructions have a primary opcode encoded in the top bits.
- if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
- // If it's a primary opcode, the first operand is encoded in the bottom
- // bits of the opcode itself.
- uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
- switch (Primary) {
- case DW_CFA_advance_loc:
- case DW_CFA_restore:
- addInstruction(Primary, Op1);
- break;
- case DW_CFA_offset:
- addInstruction(Primary, Op1, Data.getULEB128(C));
- break;
- default:
- llvm_unreachable("invalid primary CFI opcode");
- }
- continue;
- }
-
- // Extended opcode - its value is Opcode itself.
- switch (Opcode) {
- default:
- return createStringError(errc::illegal_byte_sequence,
- "invalid extended CFI opcode 0x%" PRIx8, Opcode);
- case DW_CFA_nop:
- case DW_CFA_remember_state:
- case DW_CFA_restore_state:
- case DW_CFA_GNU_window_save:
- // No operands
- addInstruction(Opcode);
- break;
- case DW_CFA_set_loc:
- // Operands: Address
- addInstruction(Opcode, Data.getRelocatedAddress(C));
- break;
- case DW_CFA_advance_loc1:
- // Operands: 1-byte delta
- addInstruction(Opcode, Data.getRelocatedValue(C, 1));
- break;
- case DW_CFA_advance_loc2:
- // Operands: 2-byte delta
- addInstruction(Opcode, Data.getRelocatedValue(C, 2));
- break;
- case DW_CFA_advance_loc4:
- // Operands: 4-byte delta
- addInstruction(Opcode, Data.getRelocatedValue(C, 4));
- break;
- case DW_CFA_restore_extended:
- case DW_CFA_undefined:
- case DW_CFA_same_value:
- case DW_CFA_def_cfa_register:
- case DW_CFA_def_cfa_offset:
- case DW_CFA_GNU_args_size:
- // Operands: ULEB128
- addInstruction(Opcode, Data.getULEB128(C));
- break;
- case DW_CFA_def_cfa_offset_sf:
- // Operands: SLEB128
- addInstruction(Opcode, Data.getSLEB128(C));
- break;
- case DW_CFA_offset_extended:
- case DW_CFA_register:
- case DW_CFA_def_cfa:
- case DW_CFA_val_offset: {
- // Operands: ULEB128, ULEB128
- // Note: We can not embed getULEB128 directly into function
- // argument list. getULEB128 changes Offset and order of evaluation
- // for arguments is unspecified.
- uint64_t op1 = Data.getULEB128(C);
- uint64_t op2 = Data.getULEB128(C);
- addInstruction(Opcode, op1, op2);
- break;
- }
- case DW_CFA_offset_extended_sf:
- case DW_CFA_def_cfa_sf:
- case DW_CFA_val_offset_sf: {
- // Operands: ULEB128, SLEB128
- // Note: see comment for the previous case
- uint64_t op1 = Data.getULEB128(C);
- uint64_t op2 = (uint64_t)Data.getSLEB128(C);
- addInstruction(Opcode, op1, op2);
- break;
- }
- case DW_CFA_def_cfa_expression: {
- uint64_t ExprLength = Data.getULEB128(C);
- addInstruction(Opcode, 0);
- StringRef Expression = Data.getBytes(C, ExprLength);
-
- DataExtractor Extractor(Expression, Data.isLittleEndian(),
- Data.getAddressSize());
- // Note. We do not pass the DWARF format to DWARFExpression, because
- // DW_OP_call_ref, the only operation which depends on the format, is
- // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
- Instructions.back().Expression =
- DWARFExpression(Extractor, Data.getAddressSize());
- break;
- }
- case DW_CFA_expression:
- case DW_CFA_val_expression: {
- uint64_t RegNum = Data.getULEB128(C);
- addInstruction(Opcode, RegNum, 0);
-
- uint64_t BlockLength = Data.getULEB128(C);
- StringRef Expression = Data.getBytes(C, BlockLength);
- DataExtractor Extractor(Expression, Data.isLittleEndian(),
- Data.getAddressSize());
- // Note. We do not pass the DWARF format to DWARFExpression, because
- // DW_OP_call_ref, the only operation which depends on the format, is
- // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
- Instructions.back().Expression =
- DWARFExpression(Extractor, Data.getAddressSize());
- break;
- }
- }
- }
-
- *Offset = C.tell();
- return C.takeError();
-}
-
-namespace {
-
-
-} // end anonymous namespace
-
-ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
- static OperandType OpTypes[DW_CFA_restore+1][2];
- static bool Initialized = false;
- if (Initialized) {
- return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
- }
- Initialized = true;
-
-#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
- do { \
- OpTypes[OP][0] = OPTYPE0; \
- OpTypes[OP][1] = OPTYPE1; \
- } while (false)
-#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
-#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
-
- DECLARE_OP1(DW_CFA_set_loc, OT_Address);
- DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
- DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
- DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
- DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
- DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
- DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
- DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
- DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
- DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
- DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
- DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
- DECLARE_OP1(DW_CFA_undefined, OT_Register);
- DECLARE_OP1(DW_CFA_same_value, OT_Register);
- DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
- DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
- DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
- DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
- DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
- DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
- DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
- DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
- DECLARE_OP1(DW_CFA_restore, OT_Register);
- DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
- DECLARE_OP0(DW_CFA_remember_state);
- DECLARE_OP0(DW_CFA_restore_state);
- DECLARE_OP0(DW_CFA_GNU_window_save);
- DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
- DECLARE_OP0(DW_CFA_nop);
-
-#undef DECLARE_OP0
-#undef DECLARE_OP1
-#undef DECLARE_OP2
-
- return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
-}
-
-/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
+
+// See DWARF standard v3, section 7.23
+const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
+const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
+
+Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
+ uint64_t EndOffset) {
+ DataExtractor::Cursor C(*Offset);
+ while (C && C.tell() < EndOffset) {
+ uint8_t Opcode = Data.getRelocatedValue(C, 1);
+ if (!C)
+ break;
+
+ // Some instructions have a primary opcode encoded in the top bits.
+ if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
+ // If it's a primary opcode, the first operand is encoded in the bottom
+ // bits of the opcode itself.
+ uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
+ switch (Primary) {
+ case DW_CFA_advance_loc:
+ case DW_CFA_restore:
+ addInstruction(Primary, Op1);
+ break;
+ case DW_CFA_offset:
+ addInstruction(Primary, Op1, Data.getULEB128(C));
+ break;
+ default:
+ llvm_unreachable("invalid primary CFI opcode");
+ }
+ continue;
+ }
+
+ // Extended opcode - its value is Opcode itself.
+ switch (Opcode) {
+ default:
+ return createStringError(errc::illegal_byte_sequence,
+ "invalid extended CFI opcode 0x%" PRIx8, Opcode);
+ case DW_CFA_nop:
+ case DW_CFA_remember_state:
+ case DW_CFA_restore_state:
+ case DW_CFA_GNU_window_save:
+ // No operands
+ addInstruction(Opcode);
+ break;
+ case DW_CFA_set_loc:
+ // Operands: Address
+ addInstruction(Opcode, Data.getRelocatedAddress(C));
+ break;
+ case DW_CFA_advance_loc1:
+ // Operands: 1-byte delta
+ addInstruction(Opcode, Data.getRelocatedValue(C, 1));
+ break;
+ case DW_CFA_advance_loc2:
+ // Operands: 2-byte delta
+ addInstruction(Opcode, Data.getRelocatedValue(C, 2));
+ break;
+ case DW_CFA_advance_loc4:
+ // Operands: 4-byte delta
+ addInstruction(Opcode, Data.getRelocatedValue(C, 4));
+ break;
+ case DW_CFA_restore_extended:
+ case DW_CFA_undefined:
+ case DW_CFA_same_value:
+ case DW_CFA_def_cfa_register:
+ case DW_CFA_def_cfa_offset:
+ case DW_CFA_GNU_args_size:
+ // Operands: ULEB128
+ addInstruction(Opcode, Data.getULEB128(C));
+ break;
+ case DW_CFA_def_cfa_offset_sf:
+ // Operands: SLEB128
+ addInstruction(Opcode, Data.getSLEB128(C));
+ break;
+ case DW_CFA_offset_extended:
+ case DW_CFA_register:
+ case DW_CFA_def_cfa:
+ case DW_CFA_val_offset: {
+ // Operands: ULEB128, ULEB128
+ // Note: We can not embed getULEB128 directly into function
+ // argument list. getULEB128 changes Offset and order of evaluation
+ // for arguments is unspecified.
+ uint64_t op1 = Data.getULEB128(C);
+ uint64_t op2 = Data.getULEB128(C);
+ addInstruction(Opcode, op1, op2);
+ break;
+ }
+ case DW_CFA_offset_extended_sf:
+ case DW_CFA_def_cfa_sf:
+ case DW_CFA_val_offset_sf: {
+ // Operands: ULEB128, SLEB128
+ // Note: see comment for the previous case
+ uint64_t op1 = Data.getULEB128(C);
+ uint64_t op2 = (uint64_t)Data.getSLEB128(C);
+ addInstruction(Opcode, op1, op2);
+ break;
+ }
+ case DW_CFA_def_cfa_expression: {
+ uint64_t ExprLength = Data.getULEB128(C);
+ addInstruction(Opcode, 0);
+ StringRef Expression = Data.getBytes(C, ExprLength);
+
+ DataExtractor Extractor(Expression, Data.isLittleEndian(),
+ Data.getAddressSize());
+ // Note. We do not pass the DWARF format to DWARFExpression, because
+ // DW_OP_call_ref, the only operation which depends on the format, is
+ // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
+ Instructions.back().Expression =
+ DWARFExpression(Extractor, Data.getAddressSize());
+ break;
+ }
+ case DW_CFA_expression:
+ case DW_CFA_val_expression: {
+ uint64_t RegNum = Data.getULEB128(C);
+ addInstruction(Opcode, RegNum, 0);
+
+ uint64_t BlockLength = Data.getULEB128(C);
+ StringRef Expression = Data.getBytes(C, BlockLength);
+ DataExtractor Extractor(Expression, Data.isLittleEndian(),
+ Data.getAddressSize());
+ // Note. We do not pass the DWARF format to DWARFExpression, because
+ // DW_OP_call_ref, the only operation which depends on the format, is
+ // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
+ Instructions.back().Expression =
+ DWARFExpression(Extractor, Data.getAddressSize());
+ break;
+ }
+ }
+ }
+
+ *Offset = C.tell();
+ return C.takeError();
+}
+
+namespace {
+
+
+} // end anonymous namespace
+
+ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
+ static OperandType OpTypes[DW_CFA_restore+1][2];
+ static bool Initialized = false;
+ if (Initialized) {
+ return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
+ }
+ Initialized = true;
+
+#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
+ do { \
+ OpTypes[OP][0] = OPTYPE0; \
+ OpTypes[OP][1] = OPTYPE1; \
+ } while (false)
+#define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
+#define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
+
+ DECLARE_OP1(DW_CFA_set_loc, OT_Address);
+ DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
+ DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
+ DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
+ DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
+ DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
+ DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
+ DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
+ DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
+ DECLARE_OP1(DW_CFA_undefined, OT_Register);
+ DECLARE_OP1(DW_CFA_same_value, OT_Register);
+ DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
+ DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
+ DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
+ DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
+ DECLARE_OP1(DW_CFA_restore, OT_Register);
+ DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
+ DECLARE_OP0(DW_CFA_remember_state);
+ DECLARE_OP0(DW_CFA_restore_state);
+ DECLARE_OP0(DW_CFA_GNU_window_save);
+ DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
+ DECLARE_OP0(DW_CFA_nop);
+
+#undef DECLARE_OP0
+#undef DECLARE_OP1
+#undef DECLARE_OP2
+
+ return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
+}
+
+/// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
const MCRegisterInfo *MRI, bool IsEH,
const Instruction &Instr, unsigned OperandIdx,
uint64_t Operand) const {
- assert(OperandIdx < 2);
- uint8_t Opcode = Instr.Opcode;
- OperandType Type = getOperandTypes()[Opcode][OperandIdx];
-
- switch (Type) {
- case OT_Unset: {
- OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
- auto OpcodeName = CallFrameString(Opcode, Arch);
- if (!OpcodeName.empty())
- OS << " " << OpcodeName;
- else
- OS << format(" Opcode %x", Opcode);
- break;
- }
- case OT_None:
- break;
- case OT_Address:
- OS << format(" %" PRIx64, Operand);
- break;
- case OT_Offset:
- // The offsets are all encoded in a unsigned form, but in practice
- // consumers use them signed. It's most certainly legacy due to
- // the lack of signed variants in the first Dwarf standards.
- OS << format(" %+" PRId64, int64_t(Operand));
- break;
- case OT_FactoredCodeOffset: // Always Unsigned
- if (CodeAlignmentFactor)
- OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
- else
- OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
- break;
- case OT_SignedFactDataOffset:
- if (DataAlignmentFactor)
- OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
- else
- OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
- break;
- case OT_UnsignedFactDataOffset:
- if (DataAlignmentFactor)
- OS << format(" %" PRId64, Operand * DataAlignmentFactor);
- else
- OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
- break;
- case OT_Register:
+ assert(OperandIdx < 2);
+ uint8_t Opcode = Instr.Opcode;
+ OperandType Type = getOperandTypes()[Opcode][OperandIdx];
+
+ switch (Type) {
+ case OT_Unset: {
+ OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
+ auto OpcodeName = CallFrameString(Opcode, Arch);
+ if (!OpcodeName.empty())
+ OS << " " << OpcodeName;
+ else
+ OS << format(" Opcode %x", Opcode);
+ break;
+ }
+ case OT_None:
+ break;
+ case OT_Address:
+ OS << format(" %" PRIx64, Operand);
+ break;
+ case OT_Offset:
+ // The offsets are all encoded in a unsigned form, but in practice
+ // consumers use them signed. It's most certainly legacy due to
+ // the lack of signed variants in the first Dwarf standards.
+ OS << format(" %+" PRId64, int64_t(Operand));
+ break;
+ case OT_FactoredCodeOffset: // Always Unsigned
+ if (CodeAlignmentFactor)
+ OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
+ else
+ OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
+ break;
+ case OT_SignedFactDataOffset:
+ if (DataAlignmentFactor)
+ OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
+ else
+ OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
+ break;
+ case OT_UnsignedFactDataOffset:
+ if (DataAlignmentFactor)
+ OS << format(" %" PRId64, Operand * DataAlignmentFactor);
+ else
+ OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
+ break;
+ case OT_Register:
OS << ' ';
printRegister(OS, MRI, IsEH, Operand);
- break;
- case OT_Expression:
- assert(Instr.Expression && "missing DWARFExpression object");
- OS << " ";
+ break;
+ case OT_Expression:
+ assert(Instr.Expression && "missing DWARFExpression object");
+ OS << " ";
Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
- break;
- }
-}
-
+ break;
+ }
+}
+
void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
const MCRegisterInfo *MRI, bool IsEH,
- unsigned IndentLevel) const {
- for (const auto &Instr : Instructions) {
- uint8_t Opcode = Instr.Opcode;
- if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
- Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
- OS.indent(2 * IndentLevel);
- OS << CallFrameString(Opcode, Arch) << ":";
- for (unsigned i = 0; i < Instr.Ops.size(); ++i)
+ unsigned IndentLevel) const {
+ for (const auto &Instr : Instructions) {
+ uint8_t Opcode = Instr.Opcode;
+ if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
+ Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
+ OS.indent(2 * IndentLevel);
+ OS << CallFrameString(Opcode, Arch) << ":";
+ for (unsigned i = 0; i < Instr.Ops.size(); ++i)
printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
- OS << '\n';
- }
-}
-
-// Returns the CIE identifier to be used by the requested format.
-// CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5.
-// For CIE ID in .eh_frame sections see
-// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
-constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
- if (IsEH)
- return 0;
- if (IsDWARF64)
- return DW64_CIE_ID;
- return DW_CIE_ID;
-}
-
+ OS << '\n';
+ }
+}
+
+// Returns the CIE identifier to be used by the requested format.
+// CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5.
+// For CIE ID in .eh_frame sections see
+// https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
+constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
+ if (IsEH)
+ return 0;
+ if (IsDWARF64)
+ return DW64_CIE_ID;
+ return DW_CIE_ID;
+}
+
void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
const MCRegisterInfo *MRI, bool IsEH) const {
- // A CIE with a zero length is a terminator entry in the .eh_frame section.
- if (IsEH && Length == 0) {
- OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
- return;
- }
-
- OS << format("%08" PRIx64, Offset)
- << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
- << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8,
- getCIEId(IsDWARF64, IsEH))
- << " CIE\n"
- << " Format: " << FormatString(IsDWARF64) << "\n"
- << format(" Version: %d\n", Version)
- << " Augmentation: \"" << Augmentation << "\"\n";
- if (Version >= 4) {
- OS << format(" Address size: %u\n", (uint32_t)AddressSize);
- OS << format(" Segment desc size: %u\n",
- (uint32_t)SegmentDescriptorSize);
- }
- OS << format(" Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
- 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: %016" PRIx64 "\n", *Personality);
- if (!AugmentationData.empty()) {
- OS << " Augmentation data: ";
- for (uint8_t Byte : AugmentationData)
- OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
- OS << "\n";
- }
- OS << "\n";
+ // A CIE with a zero length is a terminator entry in the .eh_frame section.
+ if (IsEH && Length == 0) {
+ OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
+ return;
+ }
+
+ OS << format("%08" PRIx64, Offset)
+ << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
+ << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8,
+ getCIEId(IsDWARF64, IsEH))
+ << " CIE\n"
+ << " Format: " << FormatString(IsDWARF64) << "\n"
+ << format(" Version: %d\n", Version)
+ << " Augmentation: \"" << Augmentation << "\"\n";
+ if (Version >= 4) {
+ OS << format(" Address size: %u\n", (uint32_t)AddressSize);
+ OS << format(" Segment desc size: %u\n",
+ (uint32_t)SegmentDescriptorSize);
+ }
+ OS << format(" Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
+ 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: %016" PRIx64 "\n", *Personality);
+ if (!AugmentationData.empty()) {
+ OS << " Augmentation data: ";
+ for (uint8_t Byte : AugmentationData)
+ OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
+ OS << "\n";
+ }
+ OS << "\n";
CFIs.dump(OS, DumpOpts, MRI, IsEH);
- OS << "\n";
-}
-
+ OS << "\n";
+}
+
void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
const MCRegisterInfo *MRI, bool IsEH) const {
- OS << format("%08" PRIx64, Offset)
- << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
- << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
- << " FDE cie=";
- if (LinkedCIE)
- OS << format("%08" PRIx64, LinkedCIE->getOffset());
- else
- OS << "<invalid offset>";
- OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation,
- InitialLocation + AddressRange);
- OS << " Format: " << FormatString(IsDWARF64) << "\n";
- if (LSDAAddress)
- OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
+ OS << format("%08" PRIx64, Offset)
+ << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
+ << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
+ << " FDE cie=";
+ if (LinkedCIE)
+ OS << format("%08" PRIx64, LinkedCIE->getOffset());
+ else
+ OS << "<invalid offset>";
+ OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation,
+ InitialLocation + AddressRange);
+ OS << " Format: " << FormatString(IsDWARF64) << "\n";
+ if (LSDAAddress)
+ OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
CFIs.dump(OS, DumpOpts, MRI, IsEH);
- OS << "\n";
-}
-
-DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
- bool IsEH, uint64_t EHFrameAddress)
- : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
-
-DWARFDebugFrame::~DWARFDebugFrame() = default;
-
-static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
- uint64_t Offset, int Length) {
- errs() << "DUMP: ";
- for (int i = 0; i < Length; ++i) {
- uint8_t c = Data.getU8(&Offset);
- errs().write_hex(c); errs() << " ";
- }
- errs() << "\n";
-}
-
-Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
- uint64_t Offset = 0;
- DenseMap<uint64_t, CIE *> CIEs;
-
- while (Data.isValidOffset(Offset)) {
- uint64_t StartOffset = Offset;
-
- uint64_t Length;
- DwarfFormat Format;
- std::tie(Length, Format) = Data.getInitialLength(&Offset);
- bool IsDWARF64 = Format == DWARF64;
-
- // If the Length is 0, then this CIE is a terminator. We add it because some
- // dumper tools might need it to print something special for such entries
- // (e.g. llvm-objdump --dwarf=frames prints "ZERO terminator").
- if (Length == 0) {
- auto Cie = std::make_unique<CIE>(
- IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0,
- SmallString<8>(), 0, 0, None, None, Arch);
- CIEs[StartOffset] = Cie.get();
- Entries.push_back(std::move(Cie));
- break;
- }
-
- // At this point, Offset points to the next field after Length.
- // Length is the structure size excluding itself. Compute an offset one
- // past the end of the structure (needed to know how many instructions to
- // read).
- uint64_t StartStructureOffset = Offset;
- uint64_t EndStructureOffset = Offset + Length;
-
- // The Id field's size depends on the DWARF format
- Error Err = Error::success();
- uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset,
- /*SectionIndex=*/nullptr, &Err);
- if (Err)
- return Err;
-
- if (Id == getCIEId(IsDWARF64, IsEH)) {
- uint8_t Version = Data.getU8(&Offset);
- const char *Augmentation = Data.getCStr(&Offset);
- StringRef AugmentationString(Augmentation ? Augmentation : "");
- // TODO: we should provide a way to report a warning and continue dumping.
- if (IsEH && Version != 1)
- return createStringError(errc::not_supported,
- "unsupported CIE version: %" PRIu8, Version);
-
- uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
- Data.getU8(&Offset);
- Data.setAddressSize(AddressSize);
- uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
- uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
- int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
- uint64_t ReturnAddressRegister =
- Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset);
-
- // Parse the augmentation data for EH CIEs
- StringRef AugmentationData("");
- uint32_t FDEPointerEncoding = DW_EH_PE_absptr;
- uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
- Optional<uint64_t> Personality;
- Optional<uint32_t> PersonalityEncoding;
- if (IsEH) {
- Optional<uint64_t> AugmentationLength;
- uint64_t StartAugmentationOffset;
- uint64_t EndAugmentationOffset;
-
- // Walk the augmentation string to get all the augmentation data.
- for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
- switch (AugmentationString[i]) {
- default:
- return createStringError(
- errc::invalid_argument,
- "unknown augmentation character in entry at 0x%" PRIx64,
- StartOffset);
- case 'L':
- LSDAPointerEncoding = Data.getU8(&Offset);
- break;
- case 'P': {
- if (Personality)
- return createStringError(
- errc::invalid_argument,
- "duplicate personality in entry at 0x%" PRIx64, StartOffset);
- PersonalityEncoding = Data.getU8(&Offset);
- Personality = Data.getEncodedPointer(
- &Offset, *PersonalityEncoding,
- EHFrameAddress ? EHFrameAddress + Offset : 0);
- break;
- }
- case 'R':
- FDEPointerEncoding = Data.getU8(&Offset);
- break;
- case 'S':
- // Current frame is a signal trampoline.
- break;
- case 'z':
- if (i)
- return createStringError(
- errc::invalid_argument,
- "'z' must be the first character at 0x%" PRIx64, StartOffset);
- // Parse the augmentation length first. We only parse it if
- // the string contains a 'z'.
- AugmentationLength = Data.getULEB128(&Offset);
- StartAugmentationOffset = Offset;
- EndAugmentationOffset = Offset + *AugmentationLength;
- break;
- case 'B':
- // B-Key is used for signing functions associated with this
- // augmentation string
- break;
- }
- }
-
- if (AugmentationLength.hasValue()) {
- if (Offset != EndAugmentationOffset)
- return createStringError(errc::invalid_argument,
- "parsing augmentation data at 0x%" PRIx64
- " failed",
- StartOffset);
- AugmentationData = Data.getData().slice(StartAugmentationOffset,
- EndAugmentationOffset);
- }
- }
-
- auto Cie = std::make_unique<CIE>(
- IsDWARF64, StartOffset, Length, Version, AugmentationString,
- AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
- DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
- FDEPointerEncoding, LSDAPointerEncoding, Personality,
- PersonalityEncoding, Arch);
- CIEs[StartOffset] = Cie.get();
- Entries.emplace_back(std::move(Cie));
- } else {
- // FDE
- uint64_t CIEPointer = Id;
- uint64_t InitialLocation = 0;
- uint64_t AddressRange = 0;
- Optional<uint64_t> LSDAAddress;
- CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
-
- if (IsEH) {
- // The address size is encoded in the CIE we reference.
- if (!Cie)
- return createStringError(errc::invalid_argument,
- "parsing FDE data at 0x%" PRIx64
- " failed due to missing CIE",
- StartOffset);
+ OS << "\n";
+}
+
+DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
+ bool IsEH, uint64_t EHFrameAddress)
+ : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
+
+DWARFDebugFrame::~DWARFDebugFrame() = default;
+
+static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
+ uint64_t Offset, int Length) {
+ errs() << "DUMP: ";
+ for (int i = 0; i < Length; ++i) {
+ uint8_t c = Data.getU8(&Offset);
+ errs().write_hex(c); errs() << " ";
+ }
+ errs() << "\n";
+}
+
+Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
+ uint64_t Offset = 0;
+ DenseMap<uint64_t, CIE *> CIEs;
+
+ while (Data.isValidOffset(Offset)) {
+ uint64_t StartOffset = Offset;
+
+ uint64_t Length;
+ DwarfFormat Format;
+ std::tie(Length, Format) = Data.getInitialLength(&Offset);
+ bool IsDWARF64 = Format == DWARF64;
+
+ // If the Length is 0, then this CIE is a terminator. We add it because some
+ // dumper tools might need it to print something special for such entries
+ // (e.g. llvm-objdump --dwarf=frames prints "ZERO terminator").
+ if (Length == 0) {
+ auto Cie = std::make_unique<CIE>(
+ IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0,
+ SmallString<8>(), 0, 0, None, None, Arch);
+ CIEs[StartOffset] = Cie.get();
+ Entries.push_back(std::move(Cie));
+ break;
+ }
+
+ // At this point, Offset points to the next field after Length.
+ // Length is the structure size excluding itself. Compute an offset one
+ // past the end of the structure (needed to know how many instructions to
+ // read).
+ uint64_t StartStructureOffset = Offset;
+ uint64_t EndStructureOffset = Offset + Length;
+
+ // The Id field's size depends on the DWARF format
+ Error Err = Error::success();
+ uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset,
+ /*SectionIndex=*/nullptr, &Err);
+ if (Err)
+ return Err;
+
+ if (Id == getCIEId(IsDWARF64, IsEH)) {
+ uint8_t Version = Data.getU8(&Offset);
+ const char *Augmentation = Data.getCStr(&Offset);
+ StringRef AugmentationString(Augmentation ? Augmentation : "");
+ // TODO: we should provide a way to report a warning and continue dumping.
+ if (IsEH && Version != 1)
+ return createStringError(errc::not_supported,
+ "unsupported CIE version: %" PRIu8, Version);
+
+ uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
+ Data.getU8(&Offset);
+ Data.setAddressSize(AddressSize);
+ uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
+ uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
+ int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
+ uint64_t ReturnAddressRegister =
+ Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset);
+
+ // Parse the augmentation data for EH CIEs
+ StringRef AugmentationData("");
+ uint32_t FDEPointerEncoding = DW_EH_PE_absptr;
+ uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
+ Optional<uint64_t> Personality;
+ Optional<uint32_t> PersonalityEncoding;
+ if (IsEH) {
+ Optional<uint64_t> AugmentationLength;
+ uint64_t StartAugmentationOffset;
+ uint64_t EndAugmentationOffset;
+
+ // Walk the augmentation string to get all the augmentation data.
+ for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
+ switch (AugmentationString[i]) {
+ default:
+ return createStringError(
+ errc::invalid_argument,
+ "unknown augmentation character in entry at 0x%" PRIx64,
+ StartOffset);
+ case 'L':
+ LSDAPointerEncoding = Data.getU8(&Offset);
+ break;
+ case 'P': {
+ if (Personality)
+ return createStringError(
+ errc::invalid_argument,
+ "duplicate personality in entry at 0x%" PRIx64, StartOffset);
+ PersonalityEncoding = Data.getU8(&Offset);
+ Personality = Data.getEncodedPointer(
+ &Offset, *PersonalityEncoding,
+ EHFrameAddress ? EHFrameAddress + Offset : 0);
+ break;
+ }
+ case 'R':
+ FDEPointerEncoding = Data.getU8(&Offset);
+ break;
+ case 'S':
+ // Current frame is a signal trampoline.
+ break;
+ case 'z':
+ if (i)
+ return createStringError(
+ errc::invalid_argument,
+ "'z' must be the first character at 0x%" PRIx64, StartOffset);
+ // Parse the augmentation length first. We only parse it if
+ // the string contains a 'z'.
+ AugmentationLength = Data.getULEB128(&Offset);
+ StartAugmentationOffset = Offset;
+ EndAugmentationOffset = Offset + *AugmentationLength;
+ break;
+ case 'B':
+ // B-Key is used for signing functions associated with this
+ // augmentation string
+ break;
+ }
+ }
+
+ if (AugmentationLength.hasValue()) {
+ if (Offset != EndAugmentationOffset)
+ return createStringError(errc::invalid_argument,
+ "parsing augmentation data at 0x%" PRIx64
+ " failed",
+ StartOffset);
+ AugmentationData = Data.getData().slice(StartAugmentationOffset,
+ EndAugmentationOffset);
+ }
+ }
+
+ auto Cie = std::make_unique<CIE>(
+ IsDWARF64, StartOffset, Length, Version, AugmentationString,
+ AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
+ DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
+ FDEPointerEncoding, LSDAPointerEncoding, Personality,
+ PersonalityEncoding, Arch);
+ CIEs[StartOffset] = Cie.get();
+ Entries.emplace_back(std::move(Cie));
+ } else {
+ // FDE
+ uint64_t CIEPointer = Id;
+ uint64_t InitialLocation = 0;
+ uint64_t AddressRange = 0;
+ Optional<uint64_t> LSDAAddress;
+ CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
+
+ if (IsEH) {
+ // The address size is encoded in the CIE we reference.
+ if (!Cie)
+ return createStringError(errc::invalid_argument,
+ "parsing FDE data at 0x%" PRIx64
+ " failed due to missing CIE",
+ StartOffset);
if (auto Val =
Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
EHFrameAddress + Offset)) {
- InitialLocation = *Val;
- }
- if (auto Val = Data.getEncodedPointer(
- &Offset, Cie->getFDEPointerEncoding(), 0)) {
- AddressRange = *Val;
- }
-
- StringRef AugmentationString = Cie->getAugmentationString();
- if (!AugmentationString.empty()) {
- // Parse the augmentation length and data for this FDE.
- uint64_t AugmentationLength = Data.getULEB128(&Offset);
-
- uint64_t EndAugmentationOffset = Offset + AugmentationLength;
-
- // Decode the LSDA if the CIE augmentation string said we should.
- if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
- LSDAAddress = Data.getEncodedPointer(
- &Offset, Cie->getLSDAPointerEncoding(),
- EHFrameAddress ? Offset + EHFrameAddress : 0);
- }
-
- if (Offset != EndAugmentationOffset)
- return createStringError(errc::invalid_argument,
- "parsing augmentation data at 0x%" PRIx64
- " failed",
- StartOffset);
- }
- } else {
- InitialLocation = Data.getRelocatedAddress(&Offset);
- AddressRange = Data.getRelocatedAddress(&Offset);
- }
-
- Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer,
- InitialLocation, AddressRange, Cie,
- LSDAAddress, Arch));
- }
-
- if (Error E =
- Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset))
- return E;
-
- if (Offset != EndStructureOffset)
- return createStringError(
- errc::invalid_argument,
- "parsing entry instructions at 0x%" PRIx64 " failed", StartOffset);
- }
-
- return Error::success();
-}
-
-FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
- 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;
-}
-
+ InitialLocation = *Val;
+ }
+ if (auto Val = Data.getEncodedPointer(
+ &Offset, Cie->getFDEPointerEncoding(), 0)) {
+ AddressRange = *Val;
+ }
+
+ StringRef AugmentationString = Cie->getAugmentationString();
+ if (!AugmentationString.empty()) {
+ // Parse the augmentation length and data for this FDE.
+ uint64_t AugmentationLength = Data.getULEB128(&Offset);
+
+ uint64_t EndAugmentationOffset = Offset + AugmentationLength;
+
+ // Decode the LSDA if the CIE augmentation string said we should.
+ if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
+ LSDAAddress = Data.getEncodedPointer(
+ &Offset, Cie->getLSDAPointerEncoding(),
+ EHFrameAddress ? Offset + EHFrameAddress : 0);
+ }
+
+ if (Offset != EndAugmentationOffset)
+ return createStringError(errc::invalid_argument,
+ "parsing augmentation data at 0x%" PRIx64
+ " failed",
+ StartOffset);
+ }
+ } else {
+ InitialLocation = Data.getRelocatedAddress(&Offset);
+ AddressRange = Data.getRelocatedAddress(&Offset);
+ }
+
+ Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer,
+ InitialLocation, AddressRange, Cie,
+ LSDAAddress, Arch));
+ }
+
+ if (Error E =
+ Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset))
+ return E;
+
+ if (Offset != EndStructureOffset)
+ return createStringError(
+ errc::invalid_argument,
+ "parsing entry instructions at 0x%" PRIx64 " failed", StartOffset);
+ }
+
+ return Error::success();
+}
+
+FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
+ 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;
+}
+
void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
const MCRegisterInfo *MRI,
- Optional<uint64_t> Offset) const {
- if (Offset) {
- if (auto *Entry = getEntryAtOffset(*Offset))
+ Optional<uint64_t> Offset) const {
+ if (Offset) {
+ if (auto *Entry = getEntryAtOffset(*Offset))
Entry->dump(OS, DumpOpts, MRI, IsEH);
- return;
- }
-
- OS << "\n";
- for (const auto &Entry : Entries)
+ return;
+ }
+
+ OS << "\n";
+ for (const auto &Entry : Entries)
Entry->dump(OS, DumpOpts, MRI, IsEH);
-}
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
index 2b7d0c3363..b72c5071ea 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugInfoEntry.cpp
@@ -1,70 +1,70 @@
-//===- DWARFDebugInfoEntry.cpp --------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/DataExtractor.h"
-#include <cstddef>
-#include <cstdint>
-
-using namespace llvm;
-using namespace dwarf;
-
-bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
- uint64_t *OffsetPtr) {
- DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
- const uint64_t UEndOffset = U.getNextUnitOffset();
- return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0);
-}
-
-bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
- const DWARFDataExtractor &DebugInfoData,
- uint64_t UEndOffset, uint32_t D) {
- Offset = *OffsetPtr;
- Depth = D;
- if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
- return false;
- uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
- if (0 == AbbrCode) {
- // NULL debug tag entry.
- AbbrevDecl = nullptr;
- return true;
- }
+//===- DWARFDebugInfoEntry.cpp --------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/DataExtractor.h"
+#include <cstddef>
+#include <cstdint>
+
+using namespace llvm;
+using namespace dwarf;
+
+bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U,
+ uint64_t *OffsetPtr) {
+ DWARFDataExtractor DebugInfoData = U.getDebugInfoExtractor();
+ const uint64_t UEndOffset = U.getNextUnitOffset();
+ return extractFast(U, OffsetPtr, DebugInfoData, UEndOffset, 0);
+}
+
+bool DWARFDebugInfoEntry::extractFast(const DWARFUnit &U, uint64_t *OffsetPtr,
+ const DWARFDataExtractor &DebugInfoData,
+ uint64_t UEndOffset, uint32_t D) {
+ Offset = *OffsetPtr;
+ Depth = D;
+ if (Offset >= UEndOffset || !DebugInfoData.isValidOffset(Offset))
+ return false;
+ uint64_t AbbrCode = DebugInfoData.getULEB128(OffsetPtr);
+ if (0 == AbbrCode) {
+ // NULL debug tag entry.
+ AbbrevDecl = nullptr;
+ return true;
+ }
if (const auto *AbbrevSet = U.getAbbreviations())
AbbrevDecl = AbbrevSet->getAbbreviationDeclaration(AbbrCode);
- if (nullptr == AbbrevDecl) {
- // Restore the original offset.
- *OffsetPtr = Offset;
- return false;
- }
- // See if all attributes in this DIE have fixed byte sizes. If so, we can
- // just add this size to the offset to skip to the next DIE.
- if (Optional<size_t> FixedSize = AbbrevDecl->getFixedAttributesByteSize(U)) {
- *OffsetPtr += *FixedSize;
- return true;
- }
-
- // Skip all data in the .debug_info for the attributes
- for (const auto &AttrSpec : AbbrevDecl->attributes()) {
- // Check if this attribute has a fixed byte size.
- if (auto FixedSize = AttrSpec.getByteSize(U)) {
- // Attribute byte size if fixed, just add the size to the offset.
- *OffsetPtr += *FixedSize;
- } else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData,
- OffsetPtr, U.getFormParams())) {
- // We failed to skip this attribute's value, restore the original offset
- // and return the failure status.
- *OffsetPtr = Offset;
- return false;
- }
- }
- return true;
-}
+ if (nullptr == AbbrevDecl) {
+ // Restore the original offset.
+ *OffsetPtr = Offset;
+ return false;
+ }
+ // See if all attributes in this DIE have fixed byte sizes. If so, we can
+ // just add this size to the offset to skip to the next DIE.
+ if (Optional<size_t> FixedSize = AbbrevDecl->getFixedAttributesByteSize(U)) {
+ *OffsetPtr += *FixedSize;
+ return true;
+ }
+
+ // Skip all data in the .debug_info for the attributes
+ for (const auto &AttrSpec : AbbrevDecl->attributes()) {
+ // Check if this attribute has a fixed byte size.
+ if (auto FixedSize = AttrSpec.getByteSize(U)) {
+ // Attribute byte size if fixed, just add the size to the offset.
+ *OffsetPtr += *FixedSize;
+ } else if (!DWARFFormValue::skipValue(AttrSpec.Form, DebugInfoData,
+ OffsetPtr, U.getFormParams())) {
+ // We failed to skip this attribute's value, restore the original offset
+ // and return the failure status.
+ *OffsetPtr = Offset;
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
index bda41b1f34..34c5256488 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLine.cpp
@@ -1,84 +1,84 @@
-//===- DWARFDebugLine.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/WithColor.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <cinttypes>
-#include <cstdint>
-#include <cstdio>
-#include <utility>
-
-using namespace llvm;
-using namespace dwarf;
-
-using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
-
-namespace {
-
-struct ContentDescriptor {
- dwarf::LineNumberEntryFormat Type;
- dwarf::Form Form;
-};
-
-using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
-
-} // end anonymous namespace
-
-static bool versionIsSupported(uint16_t Version) {
- return Version >= 2 && Version <= 5;
-}
-
-void DWARFDebugLine::ContentTypeTracker::trackContentType(
- dwarf::LineNumberEntryFormat ContentType) {
- switch (ContentType) {
- case dwarf::DW_LNCT_timestamp:
- HasModTime = true;
- break;
- case dwarf::DW_LNCT_size:
- HasLength = true;
- break;
- case dwarf::DW_LNCT_MD5:
- HasMD5 = true;
- break;
- case dwarf::DW_LNCT_LLVM_source:
- HasSource = true;
- break;
- default:
- // We only care about values we consider optional, and new values may be
- // added in the vendor extension range, so we do not match exhaustively.
- break;
- }
-}
-
-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();
-}
-
+//===- DWARFDebugLine.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cinttypes>
+#include <cstdint>
+#include <cstdio>
+#include <utility>
+
+using namespace llvm;
+using namespace dwarf;
+
+using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
+
+namespace {
+
+struct ContentDescriptor {
+ dwarf::LineNumberEntryFormat Type;
+ dwarf::Form Form;
+};
+
+using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
+
+} // end anonymous namespace
+
+static bool versionIsSupported(uint16_t Version) {
+ return Version >= 2 && Version <= 5;
+}
+
+void DWARFDebugLine::ContentTypeTracker::trackContentType(
+ dwarf::LineNumberEntryFormat ContentType) {
+ switch (ContentType) {
+ case dwarf::DW_LNCT_timestamp:
+ HasModTime = true;
+ break;
+ case dwarf::DW_LNCT_size:
+ HasLength = true;
+ break;
+ case dwarf::DW_LNCT_MD5:
+ HasMD5 = true;
+ break;
+ case dwarf::DW_LNCT_LLVM_source:
+ HasSource = true;
+ break;
+ default:
+ // We only care about values we consider optional, and new values may be
+ // added in the vendor extension range, so we do not match exhaustively.
+ break;
+ }
+}
+
+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();
+}
+
Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const {
if (FileNames.empty())
return None;
@@ -91,698 +91,698 @@ Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const {
return 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;
- MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
- OpcodeBase = 0;
- FormParams = dwarf::FormParams({0, 0, DWARF32});
- ContentTypes = ContentTypeTracker();
- StandardOpcodeLengths.clear();
- IncludeDirectories.clear();
- FileNames.clear();
-}
-
-void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
- DIDumpOptions DumpOptions) const {
- if (!totalLengthIsValid())
- return;
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(FormParams.Format);
- OS << "Line table prologue:\n"
- << format(" total_length: 0x%0*" PRIx64 "\n", OffsetDumpWidth,
- TotalLength)
- << " format: " << dwarf::FormatString(FormParams.Format) << "\n"
- << format(" version: %u\n", getVersion());
- if (!versionIsSupported(getVersion()))
- return;
- if (getVersion() >= 5)
- OS << format(" address_size: %u\n", getAddressSize())
- << format(" seg_select_size: %u\n", SegSelectorSize);
- OS << format(" prologue_length: 0x%0*" PRIx64 "\n", OffsetDumpWidth,
- PrologueLength)
- << format(" min_inst_length: %u\n", MinInstLength)
- << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
- << format(" default_is_stmt: %u\n", DefaultIsStmt)
- << format(" line_base: %i\n", LineBase)
- << format(" line_range: %u\n", LineRange)
- << format(" opcode_base: %u\n", OpcodeBase);
-
- for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
- OS << formatv("standard_opcode_lengths[{0}] = {1}\n",
- static_cast<dwarf::LineNumberOps>(I + 1),
- StandardOpcodeLengths[I]);
-
- if (!IncludeDirectories.empty()) {
- // DWARF v5 starts directory indexes at 0.
- uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
- for (uint32_t I = 0; I != IncludeDirectories.size(); ++I) {
- OS << format("include_directories[%3u] = ", I + DirBase);
- IncludeDirectories[I].dump(OS, DumpOptions);
- OS << '\n';
- }
- }
-
- if (!FileNames.empty()) {
- // DWARF v5 starts file indexes at 0.
- uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
- for (uint32_t I = 0; I != FileNames.size(); ++I) {
- const FileNameEntry &FileEntry = FileNames[I];
- OS << format("file_names[%3u]:\n", I + FileBase);
- OS << " name: ";
- FileEntry.Name.dump(OS, DumpOptions);
- OS << '\n'
- << format(" dir_index: %" PRIu64 "\n", FileEntry.DirIdx);
- if (ContentTypes.HasMD5)
- OS << " md5_checksum: " << FileEntry.Checksum.digest() << '\n';
- if (ContentTypes.HasModTime)
- OS << format(" mod_time: 0x%8.8" PRIx64 "\n", FileEntry.ModTime);
- if (ContentTypes.HasLength)
- OS << format(" length: 0x%8.8" PRIx64 "\n", FileEntry.Length);
- if (ContentTypes.HasSource) {
- OS << " source: ";
- FileEntry.Source.dump(OS, DumpOptions);
- OS << '\n';
- }
- }
- }
-}
-
-// Parse v2-v4 directory and file tables.
-static Error
-parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
- uint64_t *OffsetPtr,
- DWARFDebugLine::ContentTypeTracker &ContentTypes,
- std::vector<DWARFFormValue> &IncludeDirectories,
- std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
- while (true) {
- Error Err = Error::success();
- StringRef S = DebugLineData.getCStrRef(OffsetPtr, &Err);
- if (Err) {
- consumeError(std::move(Err));
- return createStringError(errc::invalid_argument,
- "include directories table was not null "
- "terminated before the end of the prologue");
- }
- if (S.empty())
- break;
- DWARFFormValue Dir =
- DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, S.data());
- IncludeDirectories.push_back(Dir);
- }
-
- ContentTypes.HasModTime = true;
- ContentTypes.HasLength = true;
-
- while (true) {
- Error Err = Error::success();
- StringRef Name = DebugLineData.getCStrRef(OffsetPtr, &Err);
- if (!Err && Name.empty())
- break;
-
- DWARFDebugLine::FileNameEntry FileEntry;
- FileEntry.Name =
- DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name.data());
- FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr, &Err);
- FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr, &Err);
- FileEntry.Length = DebugLineData.getULEB128(OffsetPtr, &Err);
-
- if (Err) {
- consumeError(std::move(Err));
- return createStringError(
- errc::invalid_argument,
- "file names table was not null terminated before "
- "the end of the prologue");
- }
- FileNames.push_back(FileEntry);
- }
-
- return Error::success();
-}
-
-// Parse v5 directory/file entry content descriptions.
-// Returns the descriptors, or an error if we did not find a path or ran off
-// the end of the prologue.
-static llvm::Expected<ContentDescriptors>
-parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
- DWARFDebugLine::ContentTypeTracker *ContentTypes) {
- Error Err = Error::success();
- ContentDescriptors Descriptors;
- int FormatCount = DebugLineData.getU8(OffsetPtr, &Err);
- bool HasPath = false;
- for (int I = 0; I != FormatCount && !Err; ++I) {
- ContentDescriptor Descriptor;
- Descriptor.Type =
- dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr, &Err));
- Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr, &Err));
- if (Descriptor.Type == dwarf::DW_LNCT_path)
- HasPath = true;
- if (ContentTypes)
- ContentTypes->trackContentType(Descriptor.Type);
- Descriptors.push_back(Descriptor);
- }
-
- if (Err)
- return createStringError(errc::invalid_argument,
- "failed to parse entry content descriptors: %s",
- toString(std::move(Err)).c_str());
-
- if (!HasPath)
- return createStringError(errc::invalid_argument,
- "failed to parse entry content descriptions"
- " because no path was found");
- return Descriptors;
-}
-
-static Error
-parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
- uint64_t *OffsetPtr, const dwarf::FormParams &FormParams,
- const DWARFContext &Ctx, const DWARFUnit *U,
- DWARFDebugLine::ContentTypeTracker &ContentTypes,
- std::vector<DWARFFormValue> &IncludeDirectories,
- std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
- // Get the directory entry description.
- llvm::Expected<ContentDescriptors> DirDescriptors =
- parseV5EntryFormat(DebugLineData, OffsetPtr, nullptr);
- if (!DirDescriptors)
- return DirDescriptors.takeError();
-
- // Get the directory entries, according to the format described above.
- uint64_t DirEntryCount = DebugLineData.getULEB128(OffsetPtr);
- for (uint64_t I = 0; I != DirEntryCount; ++I) {
- for (auto Descriptor : *DirDescriptors) {
- DWARFFormValue Value(Descriptor.Form);
- switch (Descriptor.Type) {
- case DW_LNCT_path:
- if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
- return createStringError(errc::invalid_argument,
- "failed to parse directory entry because "
- "extracting the form value failed");
- IncludeDirectories.push_back(Value);
- break;
- default:
- if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
- return createStringError(errc::invalid_argument,
- "failed to parse directory entry because "
- "skipping the form value failed");
- }
- }
- }
-
- // Get the file entry description.
- llvm::Expected<ContentDescriptors> FileDescriptors =
- parseV5EntryFormat(DebugLineData, OffsetPtr, &ContentTypes);
- if (!FileDescriptors)
- return FileDescriptors.takeError();
-
- // Get the file entries, according to the format described above.
- uint64_t FileEntryCount = DebugLineData.getULEB128(OffsetPtr);
- for (uint64_t I = 0; I != FileEntryCount; ++I) {
- DWARFDebugLine::FileNameEntry FileEntry;
- for (auto Descriptor : *FileDescriptors) {
- DWARFFormValue Value(Descriptor.Form);
- if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
- return createStringError(errc::invalid_argument,
- "failed to parse file entry because "
- "extracting the form value failed");
- switch (Descriptor.Type) {
- case DW_LNCT_path:
- FileEntry.Name = Value;
- break;
- case DW_LNCT_LLVM_source:
- FileEntry.Source = Value;
- break;
- case DW_LNCT_directory_index:
- FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue();
- break;
- case DW_LNCT_timestamp:
- FileEntry.ModTime = Value.getAsUnsignedConstant().getValue();
- break;
- case DW_LNCT_size:
- FileEntry.Length = Value.getAsUnsignedConstant().getValue();
- break;
- case DW_LNCT_MD5:
- if (!Value.getAsBlock() || Value.getAsBlock().getValue().size() != 16)
- return createStringError(
- errc::invalid_argument,
- "failed to parse file entry because the MD5 hash is invalid");
- std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
- FileEntry.Checksum.Bytes.begin());
- break;
- default:
- break;
- }
- }
- FileNames.push_back(FileEntry);
- }
- return Error::success();
-}
-
-uint64_t DWARFDebugLine::Prologue::getLength() const {
- uint64_t Length = PrologueLength + sizeofTotalLength() +
- sizeof(getVersion()) + sizeofPrologueLength();
- if (getVersion() >= 5)
- Length += 2; // Address + Segment selector sizes.
- return Length;
-}
-
-Error DWARFDebugLine::Prologue::parse(
- DWARFDataExtractor DebugLineData, uint64_t *OffsetPtr,
- function_ref<void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx,
- const DWARFUnit *U) {
- const uint64_t PrologueOffset = *OffsetPtr;
-
- clear();
- DataExtractor::Cursor Cursor(*OffsetPtr);
- std::tie(TotalLength, FormParams.Format) =
- DebugLineData.getInitialLength(Cursor);
-
- DebugLineData =
- DWARFDataExtractor(DebugLineData, Cursor.tell() + TotalLength);
- FormParams.Version = DebugLineData.getU16(Cursor);
- if (Cursor && !versionIsSupported(getVersion())) {
- // Treat this error as unrecoverable - we cannot be sure what any of
- // the data represents including the length field, so cannot skip it or make
- // any reasonable assumptions.
- *OffsetPtr = Cursor.tell();
- return createStringError(
- errc::not_supported,
- "parsing line table prologue at offset 0x%8.8" PRIx64
- ": unsupported version %" PRIu16,
- PrologueOffset, getVersion());
- }
-
- if (getVersion() >= 5) {
- FormParams.AddrSize = DebugLineData.getU8(Cursor);
- assert((!Cursor || DebugLineData.getAddressSize() == 0 ||
- DebugLineData.getAddressSize() == getAddressSize()) &&
- "Line table header and data extractor disagree");
- SegSelectorSize = DebugLineData.getU8(Cursor);
- }
-
- PrologueLength =
- DebugLineData.getRelocatedValue(Cursor, sizeofPrologueLength());
- const uint64_t EndPrologueOffset = PrologueLength + Cursor.tell();
- DebugLineData = DWARFDataExtractor(DebugLineData, EndPrologueOffset);
- MinInstLength = DebugLineData.getU8(Cursor);
- if (getVersion() >= 4)
- MaxOpsPerInst = DebugLineData.getU8(Cursor);
- DefaultIsStmt = DebugLineData.getU8(Cursor);
- LineBase = DebugLineData.getU8(Cursor);
- LineRange = DebugLineData.getU8(Cursor);
- OpcodeBase = DebugLineData.getU8(Cursor);
-
- if (Cursor && OpcodeBase == 0) {
- // If the opcode base is 0, we cannot read the standard opcode lengths (of
- // which there are supposed to be one fewer than the opcode base). Assume
- // there are no standard opcodes and continue parsing.
- RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "parsing line table prologue at offset 0x%8.8" PRIx64
- " found opcode base of 0. Assuming no standard opcodes",
- PrologueOffset));
- } else if (Cursor) {
- StandardOpcodeLengths.reserve(OpcodeBase - 1);
- for (uint32_t I = 1; I < OpcodeBase; ++I) {
- uint8_t OpLen = DebugLineData.getU8(Cursor);
- StandardOpcodeLengths.push_back(OpLen);
- }
- }
-
- *OffsetPtr = Cursor.tell();
- // A corrupt file name or directory table does not prevent interpretation of
- // the main line program, so check the cursor state now so that its errors can
- // be handled separately.
- if (!Cursor)
- return createStringError(
- errc::invalid_argument,
- "parsing line table prologue at offset 0x%8.8" PRIx64 ": %s",
- PrologueOffset, toString(Cursor.takeError()).c_str());
-
- Error E =
- getVersion() >= 5
- ? parseV5DirFileTables(DebugLineData, OffsetPtr, FormParams, Ctx, U,
- ContentTypes, IncludeDirectories, FileNames)
- : parseV2DirFileTables(DebugLineData, OffsetPtr, ContentTypes,
- IncludeDirectories, FileNames);
- if (E) {
- RecoverableErrorHandler(joinErrors(
- createStringError(
- errc::invalid_argument,
- "parsing line table prologue at 0x%8.8" PRIx64
- " found an invalid directory or file table description at"
- " 0x%8.8" PRIx64,
- PrologueOffset, *OffsetPtr),
- std::move(E)));
- return Error::success();
- }
-
- assert(*OffsetPtr <= EndPrologueOffset);
- if (*OffsetPtr != EndPrologueOffset) {
- RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "unknown data in line table prologue at offset 0x%8.8" PRIx64
- ": parsing ended (at offset 0x%8.8" PRIx64
- ") before reaching the prologue end at offset 0x%8.8" PRIx64,
- PrologueOffset, *OffsetPtr, EndPrologueOffset));
- }
- return Error::success();
-}
-
-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.Address = 0;
- Address.SectionIndex = object::SectionedAddress::UndefSection;
- Line = 1;
- Column = 0;
- File = 1;
- Isa = 0;
- Discriminator = 0;
- IsStmt = DefaultIsStmt;
- BasicBlock = false;
- EndSequence = false;
- PrologueEnd = false;
- EpilogueBegin = false;
-}
-
-void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS, unsigned Indent) {
- OS.indent(Indent)
- << "Address Line Column File ISA Discriminator Flags\n";
- OS.indent(Indent)
- << "------------------ ------ ------ ------ --- ------------- "
- "-------------\n";
-}
-
-void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
- 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" : "")
- << (EpilogueBegin ? " epilogue_begin" : "")
- << (EndSequence ? " end_sequence" : "") << '\n';
-}
-
-DWARFDebugLine::Sequence::Sequence() { reset(); }
-
-void DWARFDebugLine::Sequence::reset() {
- LowPC = 0;
- HighPC = 0;
- SectionIndex = object::SectionedAddress::UndefSection;
- FirstRowIndex = 0;
- LastRowIndex = 0;
- Empty = true;
-}
-
-DWARFDebugLine::LineTable::LineTable() { clear(); }
-
-void DWARFDebugLine::LineTable::dump(raw_ostream &OS,
- DIDumpOptions DumpOptions) const {
- Prologue.dump(OS, DumpOptions);
-
- if (!Rows.empty()) {
- OS << '\n';
- Row::dumpTableHeader(OS, 0);
- for (const Row &R : Rows) {
- R.dump(OS);
- }
- }
-
- // Terminate the table with a final blank line to clearly delineate it from
- // later dumps.
- OS << '\n';
-}
-
-void DWARFDebugLine::LineTable::clear() {
- Prologue.clear();
- Rows.clear();
- Sequences.clear();
-}
-
-DWARFDebugLine::ParsingState::ParsingState(
- struct LineTable *LT, uint64_t TableOffset,
- function_ref<void(Error)> ErrorHandler)
- : LineTable(LT), LineTableOffset(TableOffset), ErrorHandler(ErrorHandler) {
- resetRowAndSequence();
-}
-
-void DWARFDebugLine::ParsingState::resetRowAndSequence() {
- Row.reset(LineTable->Prologue.DefaultIsStmt);
- Sequence.reset();
-}
-
-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.Address;
- Sequence.FirstRowIndex = RowNumber;
- }
- LineTable->appendRow(Row);
- if (Row.EndSequence) {
- // Record the end of instruction sequence.
- Sequence.HighPC = Row.Address.Address;
- Sequence.LastRowIndex = RowNumber + 1;
- Sequence.SectionIndex = Row.Address.SectionIndex;
- if (Sequence.isValid())
- LineTable->appendSequence(Sequence);
- Sequence.reset();
- }
- Row.postAppend();
-}
-
-const DWARFDebugLine::LineTable *
-DWARFDebugLine::getLineTable(uint64_t Offset) const {
- LineTableConstIter Pos = LineTableMap.find(Offset);
- if (Pos != LineTableMap.end())
- return &Pos->second;
- return nullptr;
-}
-
-Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
- DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx,
- const DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
- if (!DebugLineData.isValidOffset(Offset))
- return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx64
- " is not a valid debug line section offset",
- Offset);
-
- std::pair<LineTableIter, bool> Pos =
- LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
- LineTable *LT = &Pos.first->second;
- if (Pos.second) {
- if (Error Err =
- LT->parse(DebugLineData, &Offset, Ctx, U, RecoverableErrorHandler))
- return std::move(Err);
- return LT;
- }
- return LT;
-}
-
-static StringRef getOpcodeName(uint8_t Opcode, uint8_t OpcodeBase) {
- assert(Opcode != 0);
- if (Opcode < OpcodeBase)
- return LNStandardString(Opcode);
- return "special";
-}
-
-uint64_t DWARFDebugLine::ParsingState::advanceAddr(uint64_t OperationAdvance,
- uint8_t Opcode,
- uint64_t OpcodeOffset) {
- StringRef OpcodeName = getOpcodeName(Opcode, LineTable->Prologue.OpcodeBase);
- // For versions less than 4, the MaxOpsPerInst member is set to 0, as the
- // maximum_operations_per_instruction field wasn't introduced until DWARFv4.
- // Don't warn about bad values in this situation.
- if (ReportAdvanceAddrProblem && LineTable->Prologue.getVersion() >= 4 &&
- LineTable->Prologue.MaxOpsPerInst != 1)
- ErrorHandler(createStringError(
- errc::not_supported,
- "line table program at offset 0x%8.8" PRIx64
- " contains a %s opcode at offset 0x%8.8" PRIx64
- ", but the prologue maximum_operations_per_instruction value is %" PRId8
- ", which is unsupported. Assuming a value of 1 instead",
- LineTableOffset, OpcodeName.data(), OpcodeOffset,
- LineTable->Prologue.MaxOpsPerInst));
- if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0)
- ErrorHandler(
- createStringError(errc::invalid_argument,
- "line table program at offset 0x%8.8" PRIx64
- " contains a %s opcode at offset 0x%8.8" PRIx64
- ", but the prologue minimum_instruction_length value "
- "is 0, which prevents any address advancing",
- LineTableOffset, OpcodeName.data(), OpcodeOffset));
- ReportAdvanceAddrProblem = false;
- uint64_t AddrOffset = OperationAdvance * LineTable->Prologue.MinInstLength;
- Row.Address.Address += AddrOffset;
- return AddrOffset;
-}
-
-DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode
-DWARFDebugLine::ParsingState::advanceAddrForOpcode(uint8_t Opcode,
- uint64_t OpcodeOffset) {
- assert(Opcode == DW_LNS_const_add_pc ||
- Opcode >= LineTable->Prologue.OpcodeBase);
- if (ReportBadLineRange && LineTable->Prologue.LineRange == 0) {
- StringRef OpcodeName =
- getOpcodeName(Opcode, LineTable->Prologue.OpcodeBase);
- ErrorHandler(
- createStringError(errc::not_supported,
- "line table program at offset 0x%8.8" PRIx64
- " contains a %s opcode at offset 0x%8.8" PRIx64
- ", but the prologue line_range value is 0. The "
- "address and line will not be adjusted",
- LineTableOffset, OpcodeName.data(), OpcodeOffset));
- ReportBadLineRange = false;
- }
-
- uint8_t OpcodeValue = Opcode;
- if (Opcode == DW_LNS_const_add_pc)
- OpcodeValue = 255;
- uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
- uint64_t OperationAdvance =
- LineTable->Prologue.LineRange != 0
- ? AdjustedOpcode / LineTable->Prologue.LineRange
- : 0;
- uint64_t AddrOffset = advanceAddr(OperationAdvance, Opcode, OpcodeOffset);
- return {AddrOffset, AdjustedOpcode};
-}
-
-DWARFDebugLine::ParsingState::AddrAndLineDelta
-DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
- uint64_t OpcodeOffset) {
- // A special opcode value is chosen based on the amount that needs
- // to be added to the line and address registers. The maximum line
- // increment for a special opcode is the value of the line_base
- // field in the header, plus the value of the line_range field,
- // minus 1 (line base + line range - 1). If the desired line
- // increment is greater than the maximum line increment, a standard
- // opcode must be used instead of a special opcode. The "address
- // advance" is calculated by dividing the desired address increment
- // by the minimum_instruction_length field from the header. The
- // special opcode is then calculated using the following formula:
- //
- // opcode = (desired line increment - line_base) +
- // (line_range * address advance) + opcode_base
- //
- // If the resulting opcode is greater than 255, a standard opcode
- // must be used instead.
- //
- // To decode a special opcode, subtract the opcode_base from the
- // opcode itself to give the adjusted opcode. The amount to
- // increment the address register is the result of the adjusted
- // opcode divided by the line_range multiplied by the
- // minimum_instruction_length field from the header. That is:
- //
- // address increment = (adjusted opcode / line_range) *
- // minimum_instruction_length
- //
- // The amount to increment the line register is the line_base plus
- // the result of the adjusted opcode modulo the line_range. That is:
- //
- // line increment = line_base + (adjusted opcode % line_range)
-
- DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode AddrAdvanceResult =
- advanceAddrForOpcode(Opcode, OpcodeOffset);
- int32_t LineOffset = 0;
- if (LineTable->Prologue.LineRange != 0)
- LineOffset =
- LineTable->Prologue.LineBase +
- (AddrAdvanceResult.AdjustedOpcode % LineTable->Prologue.LineRange);
- Row.Line += LineOffset;
- return {AddrAdvanceResult.AddrDelta, LineOffset};
-}
-
-/// Parse a ULEB128 using the specified \p Cursor. \returns the parsed value on
-/// success, or None if \p Cursor is in a failing state.
-template <typename T>
-static Optional<T> parseULEB128(DWARFDataExtractor &Data,
- DataExtractor::Cursor &Cursor) {
- T Value = Data.getULEB128(Cursor);
- if (Cursor)
- return Value;
- return None;
-}
-
-Error DWARFDebugLine::LineTable::parse(
- DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
- const DWARFContext &Ctx, const DWARFUnit *U,
- function_ref<void(Error)> RecoverableErrorHandler, raw_ostream *OS,
- bool Verbose) {
- assert((OS || !Verbose) && "cannot have verbose output without stream");
- const uint64_t DebugLineOffset = *OffsetPtr;
-
- clear();
-
- Error PrologueErr =
- Prologue.parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
-
- if (OS) {
- DIDumpOptions DumpOptions;
- DumpOptions.Verbose = Verbose;
- Prologue.dump(*OS, DumpOptions);
- }
-
- if (PrologueErr) {
- // Ensure there is a blank line after the prologue to clearly delineate it
- // from later dumps.
- if (OS)
- *OS << "\n";
- return PrologueErr;
- }
-
- uint64_t ProgramLength = Prologue.TotalLength + Prologue.sizeofTotalLength();
- if (!DebugLineData.isValidOffsetForDataOfSize(DebugLineOffset,
- ProgramLength)) {
- assert(DebugLineData.size() > DebugLineOffset &&
- "prologue parsing should handle invalid offset");
- uint64_t BytesRemaining = DebugLineData.size() - DebugLineOffset;
- RecoverableErrorHandler(
- createStringError(errc::invalid_argument,
- "line table program with offset 0x%8.8" PRIx64
- " has length 0x%8.8" PRIx64 " but only 0x%8.8" PRIx64
- " bytes are available",
- DebugLineOffset, ProgramLength, BytesRemaining));
- // Continue by capping the length at the number of remaining bytes.
- ProgramLength = BytesRemaining;
- }
-
- // Create a DataExtractor which can only see the data up to the end of the
- // table, to prevent reading past the end.
- const uint64_t EndOffset = DebugLineOffset + ProgramLength;
- DWARFDataExtractor TableData(DebugLineData, EndOffset);
-
- // See if we should tell the data extractor the address size.
- if (TableData.getAddressSize() == 0)
- TableData.setAddressSize(Prologue.getAddressSize());
- else
- assert(Prologue.getAddressSize() == 0 ||
- Prologue.getAddressSize() == TableData.getAddressSize());
-
- ParsingState State(this, DebugLineOffset, RecoverableErrorHandler);
-
- *OffsetPtr = DebugLineOffset + Prologue.getLength();
- if (OS && *OffsetPtr < EndOffset) {
- *OS << '\n';
- Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
- }
+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;
+ MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
+ OpcodeBase = 0;
+ FormParams = dwarf::FormParams({0, 0, DWARF32});
+ ContentTypes = ContentTypeTracker();
+ StandardOpcodeLengths.clear();
+ IncludeDirectories.clear();
+ FileNames.clear();
+}
+
+void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
+ DIDumpOptions DumpOptions) const {
+ if (!totalLengthIsValid())
+ return;
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(FormParams.Format);
+ OS << "Line table prologue:\n"
+ << format(" total_length: 0x%0*" PRIx64 "\n", OffsetDumpWidth,
+ TotalLength)
+ << " format: " << dwarf::FormatString(FormParams.Format) << "\n"
+ << format(" version: %u\n", getVersion());
+ if (!versionIsSupported(getVersion()))
+ return;
+ if (getVersion() >= 5)
+ OS << format(" address_size: %u\n", getAddressSize())
+ << format(" seg_select_size: %u\n", SegSelectorSize);
+ OS << format(" prologue_length: 0x%0*" PRIx64 "\n", OffsetDumpWidth,
+ PrologueLength)
+ << format(" min_inst_length: %u\n", MinInstLength)
+ << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
+ << format(" default_is_stmt: %u\n", DefaultIsStmt)
+ << format(" line_base: %i\n", LineBase)
+ << format(" line_range: %u\n", LineRange)
+ << format(" opcode_base: %u\n", OpcodeBase);
+
+ for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
+ OS << formatv("standard_opcode_lengths[{0}] = {1}\n",
+ static_cast<dwarf::LineNumberOps>(I + 1),
+ StandardOpcodeLengths[I]);
+
+ if (!IncludeDirectories.empty()) {
+ // DWARF v5 starts directory indexes at 0.
+ uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
+ for (uint32_t I = 0; I != IncludeDirectories.size(); ++I) {
+ OS << format("include_directories[%3u] = ", I + DirBase);
+ IncludeDirectories[I].dump(OS, DumpOptions);
+ OS << '\n';
+ }
+ }
+
+ if (!FileNames.empty()) {
+ // DWARF v5 starts file indexes at 0.
+ uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
+ for (uint32_t I = 0; I != FileNames.size(); ++I) {
+ const FileNameEntry &FileEntry = FileNames[I];
+ OS << format("file_names[%3u]:\n", I + FileBase);
+ OS << " name: ";
+ FileEntry.Name.dump(OS, DumpOptions);
+ OS << '\n'
+ << format(" dir_index: %" PRIu64 "\n", FileEntry.DirIdx);
+ if (ContentTypes.HasMD5)
+ OS << " md5_checksum: " << FileEntry.Checksum.digest() << '\n';
+ if (ContentTypes.HasModTime)
+ OS << format(" mod_time: 0x%8.8" PRIx64 "\n", FileEntry.ModTime);
+ if (ContentTypes.HasLength)
+ OS << format(" length: 0x%8.8" PRIx64 "\n", FileEntry.Length);
+ if (ContentTypes.HasSource) {
+ OS << " source: ";
+ FileEntry.Source.dump(OS, DumpOptions);
+ OS << '\n';
+ }
+ }
+ }
+}
+
+// Parse v2-v4 directory and file tables.
+static Error
+parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
+ uint64_t *OffsetPtr,
+ DWARFDebugLine::ContentTypeTracker &ContentTypes,
+ std::vector<DWARFFormValue> &IncludeDirectories,
+ std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
+ while (true) {
+ Error Err = Error::success();
+ StringRef S = DebugLineData.getCStrRef(OffsetPtr, &Err);
+ if (Err) {
+ consumeError(std::move(Err));
+ return createStringError(errc::invalid_argument,
+ "include directories table was not null "
+ "terminated before the end of the prologue");
+ }
+ if (S.empty())
+ break;
+ DWARFFormValue Dir =
+ DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, S.data());
+ IncludeDirectories.push_back(Dir);
+ }
+
+ ContentTypes.HasModTime = true;
+ ContentTypes.HasLength = true;
+
+ while (true) {
+ Error Err = Error::success();
+ StringRef Name = DebugLineData.getCStrRef(OffsetPtr, &Err);
+ if (!Err && Name.empty())
+ break;
+
+ DWARFDebugLine::FileNameEntry FileEntry;
+ FileEntry.Name =
+ DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name.data());
+ FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr, &Err);
+ FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr, &Err);
+ FileEntry.Length = DebugLineData.getULEB128(OffsetPtr, &Err);
+
+ if (Err) {
+ consumeError(std::move(Err));
+ return createStringError(
+ errc::invalid_argument,
+ "file names table was not null terminated before "
+ "the end of the prologue");
+ }
+ FileNames.push_back(FileEntry);
+ }
+
+ return Error::success();
+}
+
+// Parse v5 directory/file entry content descriptions.
+// Returns the descriptors, or an error if we did not find a path or ran off
+// the end of the prologue.
+static llvm::Expected<ContentDescriptors>
+parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
+ DWARFDebugLine::ContentTypeTracker *ContentTypes) {
+ Error Err = Error::success();
+ ContentDescriptors Descriptors;
+ int FormatCount = DebugLineData.getU8(OffsetPtr, &Err);
+ bool HasPath = false;
+ for (int I = 0; I != FormatCount && !Err; ++I) {
+ ContentDescriptor Descriptor;
+ Descriptor.Type =
+ dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr, &Err));
+ Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr, &Err));
+ if (Descriptor.Type == dwarf::DW_LNCT_path)
+ HasPath = true;
+ if (ContentTypes)
+ ContentTypes->trackContentType(Descriptor.Type);
+ Descriptors.push_back(Descriptor);
+ }
+
+ if (Err)
+ return createStringError(errc::invalid_argument,
+ "failed to parse entry content descriptors: %s",
+ toString(std::move(Err)).c_str());
+
+ if (!HasPath)
+ return createStringError(errc::invalid_argument,
+ "failed to parse entry content descriptions"
+ " because no path was found");
+ return Descriptors;
+}
+
+static Error
+parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
+ uint64_t *OffsetPtr, const dwarf::FormParams &FormParams,
+ const DWARFContext &Ctx, const DWARFUnit *U,
+ DWARFDebugLine::ContentTypeTracker &ContentTypes,
+ std::vector<DWARFFormValue> &IncludeDirectories,
+ std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
+ // Get the directory entry description.
+ llvm::Expected<ContentDescriptors> DirDescriptors =
+ parseV5EntryFormat(DebugLineData, OffsetPtr, nullptr);
+ if (!DirDescriptors)
+ return DirDescriptors.takeError();
+
+ // Get the directory entries, according to the format described above.
+ uint64_t DirEntryCount = DebugLineData.getULEB128(OffsetPtr);
+ for (uint64_t I = 0; I != DirEntryCount; ++I) {
+ for (auto Descriptor : *DirDescriptors) {
+ DWARFFormValue Value(Descriptor.Form);
+ switch (Descriptor.Type) {
+ case DW_LNCT_path:
+ if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
+ return createStringError(errc::invalid_argument,
+ "failed to parse directory entry because "
+ "extracting the form value failed");
+ IncludeDirectories.push_back(Value);
+ break;
+ default:
+ if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
+ return createStringError(errc::invalid_argument,
+ "failed to parse directory entry because "
+ "skipping the form value failed");
+ }
+ }
+ }
+
+ // Get the file entry description.
+ llvm::Expected<ContentDescriptors> FileDescriptors =
+ parseV5EntryFormat(DebugLineData, OffsetPtr, &ContentTypes);
+ if (!FileDescriptors)
+ return FileDescriptors.takeError();
+
+ // Get the file entries, according to the format described above.
+ uint64_t FileEntryCount = DebugLineData.getULEB128(OffsetPtr);
+ for (uint64_t I = 0; I != FileEntryCount; ++I) {
+ DWARFDebugLine::FileNameEntry FileEntry;
+ for (auto Descriptor : *FileDescriptors) {
+ DWARFFormValue Value(Descriptor.Form);
+ if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
+ return createStringError(errc::invalid_argument,
+ "failed to parse file entry because "
+ "extracting the form value failed");
+ switch (Descriptor.Type) {
+ case DW_LNCT_path:
+ FileEntry.Name = Value;
+ break;
+ case DW_LNCT_LLVM_source:
+ FileEntry.Source = Value;
+ break;
+ case DW_LNCT_directory_index:
+ FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue();
+ break;
+ case DW_LNCT_timestamp:
+ FileEntry.ModTime = Value.getAsUnsignedConstant().getValue();
+ break;
+ case DW_LNCT_size:
+ FileEntry.Length = Value.getAsUnsignedConstant().getValue();
+ break;
+ case DW_LNCT_MD5:
+ if (!Value.getAsBlock() || Value.getAsBlock().getValue().size() != 16)
+ return createStringError(
+ errc::invalid_argument,
+ "failed to parse file entry because the MD5 hash is invalid");
+ std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
+ FileEntry.Checksum.Bytes.begin());
+ break;
+ default:
+ break;
+ }
+ }
+ FileNames.push_back(FileEntry);
+ }
+ return Error::success();
+}
+
+uint64_t DWARFDebugLine::Prologue::getLength() const {
+ uint64_t Length = PrologueLength + sizeofTotalLength() +
+ sizeof(getVersion()) + sizeofPrologueLength();
+ if (getVersion() >= 5)
+ Length += 2; // Address + Segment selector sizes.
+ return Length;
+}
+
+Error DWARFDebugLine::Prologue::parse(
+ DWARFDataExtractor DebugLineData, uint64_t *OffsetPtr,
+ function_ref<void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx,
+ const DWARFUnit *U) {
+ const uint64_t PrologueOffset = *OffsetPtr;
+
+ clear();
+ DataExtractor::Cursor Cursor(*OffsetPtr);
+ std::tie(TotalLength, FormParams.Format) =
+ DebugLineData.getInitialLength(Cursor);
+
+ DebugLineData =
+ DWARFDataExtractor(DebugLineData, Cursor.tell() + TotalLength);
+ FormParams.Version = DebugLineData.getU16(Cursor);
+ if (Cursor && !versionIsSupported(getVersion())) {
+ // Treat this error as unrecoverable - we cannot be sure what any of
+ // the data represents including the length field, so cannot skip it or make
+ // any reasonable assumptions.
+ *OffsetPtr = Cursor.tell();
+ return createStringError(
+ errc::not_supported,
+ "parsing line table prologue at offset 0x%8.8" PRIx64
+ ": unsupported version %" PRIu16,
+ PrologueOffset, getVersion());
+ }
+
+ if (getVersion() >= 5) {
+ FormParams.AddrSize = DebugLineData.getU8(Cursor);
+ assert((!Cursor || DebugLineData.getAddressSize() == 0 ||
+ DebugLineData.getAddressSize() == getAddressSize()) &&
+ "Line table header and data extractor disagree");
+ SegSelectorSize = DebugLineData.getU8(Cursor);
+ }
+
+ PrologueLength =
+ DebugLineData.getRelocatedValue(Cursor, sizeofPrologueLength());
+ const uint64_t EndPrologueOffset = PrologueLength + Cursor.tell();
+ DebugLineData = DWARFDataExtractor(DebugLineData, EndPrologueOffset);
+ MinInstLength = DebugLineData.getU8(Cursor);
+ if (getVersion() >= 4)
+ MaxOpsPerInst = DebugLineData.getU8(Cursor);
+ DefaultIsStmt = DebugLineData.getU8(Cursor);
+ LineBase = DebugLineData.getU8(Cursor);
+ LineRange = DebugLineData.getU8(Cursor);
+ OpcodeBase = DebugLineData.getU8(Cursor);
+
+ if (Cursor && OpcodeBase == 0) {
+ // If the opcode base is 0, we cannot read the standard opcode lengths (of
+ // which there are supposed to be one fewer than the opcode base). Assume
+ // there are no standard opcodes and continue parsing.
+ RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "parsing line table prologue at offset 0x%8.8" PRIx64
+ " found opcode base of 0. Assuming no standard opcodes",
+ PrologueOffset));
+ } else if (Cursor) {
+ StandardOpcodeLengths.reserve(OpcodeBase - 1);
+ for (uint32_t I = 1; I < OpcodeBase; ++I) {
+ uint8_t OpLen = DebugLineData.getU8(Cursor);
+ StandardOpcodeLengths.push_back(OpLen);
+ }
+ }
+
+ *OffsetPtr = Cursor.tell();
+ // A corrupt file name or directory table does not prevent interpretation of
+ // the main line program, so check the cursor state now so that its errors can
+ // be handled separately.
+ if (!Cursor)
+ return createStringError(
+ errc::invalid_argument,
+ "parsing line table prologue at offset 0x%8.8" PRIx64 ": %s",
+ PrologueOffset, toString(Cursor.takeError()).c_str());
+
+ Error E =
+ getVersion() >= 5
+ ? parseV5DirFileTables(DebugLineData, OffsetPtr, FormParams, Ctx, U,
+ ContentTypes, IncludeDirectories, FileNames)
+ : parseV2DirFileTables(DebugLineData, OffsetPtr, ContentTypes,
+ IncludeDirectories, FileNames);
+ if (E) {
+ RecoverableErrorHandler(joinErrors(
+ createStringError(
+ errc::invalid_argument,
+ "parsing line table prologue at 0x%8.8" PRIx64
+ " found an invalid directory or file table description at"
+ " 0x%8.8" PRIx64,
+ PrologueOffset, *OffsetPtr),
+ std::move(E)));
+ return Error::success();
+ }
+
+ assert(*OffsetPtr <= EndPrologueOffset);
+ if (*OffsetPtr != EndPrologueOffset) {
+ RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "unknown data in line table prologue at offset 0x%8.8" PRIx64
+ ": parsing ended (at offset 0x%8.8" PRIx64
+ ") before reaching the prologue end at offset 0x%8.8" PRIx64,
+ PrologueOffset, *OffsetPtr, EndPrologueOffset));
+ }
+ return Error::success();
+}
+
+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.Address = 0;
+ Address.SectionIndex = object::SectionedAddress::UndefSection;
+ Line = 1;
+ Column = 0;
+ File = 1;
+ Isa = 0;
+ Discriminator = 0;
+ IsStmt = DefaultIsStmt;
+ BasicBlock = false;
+ EndSequence = false;
+ PrologueEnd = false;
+ EpilogueBegin = false;
+}
+
+void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS, unsigned Indent) {
+ OS.indent(Indent)
+ << "Address Line Column File ISA Discriminator Flags\n";
+ OS.indent(Indent)
+ << "------------------ ------ ------ ------ --- ------------- "
+ "-------------\n";
+}
+
+void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
+ 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" : "")
+ << (EpilogueBegin ? " epilogue_begin" : "")
+ << (EndSequence ? " end_sequence" : "") << '\n';
+}
+
+DWARFDebugLine::Sequence::Sequence() { reset(); }
+
+void DWARFDebugLine::Sequence::reset() {
+ LowPC = 0;
+ HighPC = 0;
+ SectionIndex = object::SectionedAddress::UndefSection;
+ FirstRowIndex = 0;
+ LastRowIndex = 0;
+ Empty = true;
+}
+
+DWARFDebugLine::LineTable::LineTable() { clear(); }
+
+void DWARFDebugLine::LineTable::dump(raw_ostream &OS,
+ DIDumpOptions DumpOptions) const {
+ Prologue.dump(OS, DumpOptions);
+
+ if (!Rows.empty()) {
+ OS << '\n';
+ Row::dumpTableHeader(OS, 0);
+ for (const Row &R : Rows) {
+ R.dump(OS);
+ }
+ }
+
+ // Terminate the table with a final blank line to clearly delineate it from
+ // later dumps.
+ OS << '\n';
+}
+
+void DWARFDebugLine::LineTable::clear() {
+ Prologue.clear();
+ Rows.clear();
+ Sequences.clear();
+}
+
+DWARFDebugLine::ParsingState::ParsingState(
+ struct LineTable *LT, uint64_t TableOffset,
+ function_ref<void(Error)> ErrorHandler)
+ : LineTable(LT), LineTableOffset(TableOffset), ErrorHandler(ErrorHandler) {
+ resetRowAndSequence();
+}
+
+void DWARFDebugLine::ParsingState::resetRowAndSequence() {
+ Row.reset(LineTable->Prologue.DefaultIsStmt);
+ Sequence.reset();
+}
+
+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.Address;
+ Sequence.FirstRowIndex = RowNumber;
+ }
+ LineTable->appendRow(Row);
+ if (Row.EndSequence) {
+ // Record the end of instruction sequence.
+ Sequence.HighPC = Row.Address.Address;
+ Sequence.LastRowIndex = RowNumber + 1;
+ Sequence.SectionIndex = Row.Address.SectionIndex;
+ if (Sequence.isValid())
+ LineTable->appendSequence(Sequence);
+ Sequence.reset();
+ }
+ Row.postAppend();
+}
+
+const DWARFDebugLine::LineTable *
+DWARFDebugLine::getLineTable(uint64_t Offset) const {
+ LineTableConstIter Pos = LineTableMap.find(Offset);
+ if (Pos != LineTableMap.end())
+ return &Pos->second;
+ return nullptr;
+}
+
+Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
+ DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx,
+ const DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
+ if (!DebugLineData.isValidOffset(Offset))
+ return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx64
+ " is not a valid debug line section offset",
+ Offset);
+
+ std::pair<LineTableIter, bool> Pos =
+ LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
+ LineTable *LT = &Pos.first->second;
+ if (Pos.second) {
+ if (Error Err =
+ LT->parse(DebugLineData, &Offset, Ctx, U, RecoverableErrorHandler))
+ return std::move(Err);
+ return LT;
+ }
+ return LT;
+}
+
+static StringRef getOpcodeName(uint8_t Opcode, uint8_t OpcodeBase) {
+ assert(Opcode != 0);
+ if (Opcode < OpcodeBase)
+ return LNStandardString(Opcode);
+ return "special";
+}
+
+uint64_t DWARFDebugLine::ParsingState::advanceAddr(uint64_t OperationAdvance,
+ uint8_t Opcode,
+ uint64_t OpcodeOffset) {
+ StringRef OpcodeName = getOpcodeName(Opcode, LineTable->Prologue.OpcodeBase);
+ // For versions less than 4, the MaxOpsPerInst member is set to 0, as the
+ // maximum_operations_per_instruction field wasn't introduced until DWARFv4.
+ // Don't warn about bad values in this situation.
+ if (ReportAdvanceAddrProblem && LineTable->Prologue.getVersion() >= 4 &&
+ LineTable->Prologue.MaxOpsPerInst != 1)
+ ErrorHandler(createStringError(
+ errc::not_supported,
+ "line table program at offset 0x%8.8" PRIx64
+ " contains a %s opcode at offset 0x%8.8" PRIx64
+ ", but the prologue maximum_operations_per_instruction value is %" PRId8
+ ", which is unsupported. Assuming a value of 1 instead",
+ LineTableOffset, OpcodeName.data(), OpcodeOffset,
+ LineTable->Prologue.MaxOpsPerInst));
+ if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0)
+ ErrorHandler(
+ createStringError(errc::invalid_argument,
+ "line table program at offset 0x%8.8" PRIx64
+ " contains a %s opcode at offset 0x%8.8" PRIx64
+ ", but the prologue minimum_instruction_length value "
+ "is 0, which prevents any address advancing",
+ LineTableOffset, OpcodeName.data(), OpcodeOffset));
+ ReportAdvanceAddrProblem = false;
+ uint64_t AddrOffset = OperationAdvance * LineTable->Prologue.MinInstLength;
+ Row.Address.Address += AddrOffset;
+ return AddrOffset;
+}
+
+DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode
+DWARFDebugLine::ParsingState::advanceAddrForOpcode(uint8_t Opcode,
+ uint64_t OpcodeOffset) {
+ assert(Opcode == DW_LNS_const_add_pc ||
+ Opcode >= LineTable->Prologue.OpcodeBase);
+ if (ReportBadLineRange && LineTable->Prologue.LineRange == 0) {
+ StringRef OpcodeName =
+ getOpcodeName(Opcode, LineTable->Prologue.OpcodeBase);
+ ErrorHandler(
+ createStringError(errc::not_supported,
+ "line table program at offset 0x%8.8" PRIx64
+ " contains a %s opcode at offset 0x%8.8" PRIx64
+ ", but the prologue line_range value is 0. The "
+ "address and line will not be adjusted",
+ LineTableOffset, OpcodeName.data(), OpcodeOffset));
+ ReportBadLineRange = false;
+ }
+
+ uint8_t OpcodeValue = Opcode;
+ if (Opcode == DW_LNS_const_add_pc)
+ OpcodeValue = 255;
+ uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
+ uint64_t OperationAdvance =
+ LineTable->Prologue.LineRange != 0
+ ? AdjustedOpcode / LineTable->Prologue.LineRange
+ : 0;
+ uint64_t AddrOffset = advanceAddr(OperationAdvance, Opcode, OpcodeOffset);
+ return {AddrOffset, AdjustedOpcode};
+}
+
+DWARFDebugLine::ParsingState::AddrAndLineDelta
+DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
+ uint64_t OpcodeOffset) {
+ // A special opcode value is chosen based on the amount that needs
+ // to be added to the line and address registers. The maximum line
+ // increment for a special opcode is the value of the line_base
+ // field in the header, plus the value of the line_range field,
+ // minus 1 (line base + line range - 1). If the desired line
+ // increment is greater than the maximum line increment, a standard
+ // opcode must be used instead of a special opcode. The "address
+ // advance" is calculated by dividing the desired address increment
+ // by the minimum_instruction_length field from the header. The
+ // special opcode is then calculated using the following formula:
+ //
+ // opcode = (desired line increment - line_base) +
+ // (line_range * address advance) + opcode_base
+ //
+ // If the resulting opcode is greater than 255, a standard opcode
+ // must be used instead.
+ //
+ // To decode a special opcode, subtract the opcode_base from the
+ // opcode itself to give the adjusted opcode. The amount to
+ // increment the address register is the result of the adjusted
+ // opcode divided by the line_range multiplied by the
+ // minimum_instruction_length field from the header. That is:
+ //
+ // address increment = (adjusted opcode / line_range) *
+ // minimum_instruction_length
+ //
+ // The amount to increment the line register is the line_base plus
+ // the result of the adjusted opcode modulo the line_range. That is:
+ //
+ // line increment = line_base + (adjusted opcode % line_range)
+
+ DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode AddrAdvanceResult =
+ advanceAddrForOpcode(Opcode, OpcodeOffset);
+ int32_t LineOffset = 0;
+ if (LineTable->Prologue.LineRange != 0)
+ LineOffset =
+ LineTable->Prologue.LineBase +
+ (AddrAdvanceResult.AdjustedOpcode % LineTable->Prologue.LineRange);
+ Row.Line += LineOffset;
+ return {AddrAdvanceResult.AddrDelta, LineOffset};
+}
+
+/// Parse a ULEB128 using the specified \p Cursor. \returns the parsed value on
+/// success, or None if \p Cursor is in a failing state.
+template <typename T>
+static Optional<T> parseULEB128(DWARFDataExtractor &Data,
+ DataExtractor::Cursor &Cursor) {
+ T Value = Data.getULEB128(Cursor);
+ if (Cursor)
+ return Value;
+ return None;
+}
+
+Error DWARFDebugLine::LineTable::parse(
+ DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
+ const DWARFContext &Ctx, const DWARFUnit *U,
+ function_ref<void(Error)> RecoverableErrorHandler, raw_ostream *OS,
+ bool Verbose) {
+ assert((OS || !Verbose) && "cannot have verbose output without stream");
+ const uint64_t DebugLineOffset = *OffsetPtr;
+
+ clear();
+
+ Error PrologueErr =
+ Prologue.parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
+
+ if (OS) {
+ DIDumpOptions DumpOptions;
+ DumpOptions.Verbose = Verbose;
+ Prologue.dump(*OS, DumpOptions);
+ }
+
+ if (PrologueErr) {
+ // Ensure there is a blank line after the prologue to clearly delineate it
+ // from later dumps.
+ if (OS)
+ *OS << "\n";
+ return PrologueErr;
+ }
+
+ uint64_t ProgramLength = Prologue.TotalLength + Prologue.sizeofTotalLength();
+ if (!DebugLineData.isValidOffsetForDataOfSize(DebugLineOffset,
+ ProgramLength)) {
+ assert(DebugLineData.size() > DebugLineOffset &&
+ "prologue parsing should handle invalid offset");
+ uint64_t BytesRemaining = DebugLineData.size() - DebugLineOffset;
+ RecoverableErrorHandler(
+ createStringError(errc::invalid_argument,
+ "line table program with offset 0x%8.8" PRIx64
+ " has length 0x%8.8" PRIx64 " but only 0x%8.8" PRIx64
+ " bytes are available",
+ DebugLineOffset, ProgramLength, BytesRemaining));
+ // Continue by capping the length at the number of remaining bytes.
+ ProgramLength = BytesRemaining;
+ }
+
+ // Create a DataExtractor which can only see the data up to the end of the
+ // table, to prevent reading past the end.
+ const uint64_t EndOffset = DebugLineOffset + ProgramLength;
+ DWARFDataExtractor TableData(DebugLineData, EndOffset);
+
+ // See if we should tell the data extractor the address size.
+ if (TableData.getAddressSize() == 0)
+ TableData.setAddressSize(Prologue.getAddressSize());
+ else
+ assert(Prologue.getAddressSize() == 0 ||
+ Prologue.getAddressSize() == TableData.getAddressSize());
+
+ ParsingState State(this, DebugLineOffset, RecoverableErrorHandler);
+
+ *OffsetPtr = DebugLineOffset + Prologue.getLength();
+ if (OS && *OffsetPtr < EndOffset) {
+ *OS << '\n';
+ Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
+ }
bool TombstonedAddress = false;
auto EmitRow = [&] {
if (!TombstonedAddress) {
@@ -795,703 +795,703 @@ Error DWARFDebugLine::LineTable::parse(
State.appendRowToMatrix();
}
};
- while (*OffsetPtr < EndOffset) {
- DataExtractor::Cursor Cursor(*OffsetPtr);
-
- if (Verbose)
- *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr);
-
- uint64_t OpcodeOffset = *OffsetPtr;
- uint8_t Opcode = TableData.getU8(Cursor);
- size_t RowCount = Rows.size();
-
- if (Cursor && Verbose)
- *OS << format("%02.02" PRIx8 " ", Opcode);
-
- if (Opcode == 0) {
- // Extended Opcodes always start with a zero opcode followed by
- // a uleb128 length so you can skip ones you don't know about
- uint64_t Len = TableData.getULEB128(Cursor);
- uint64_t ExtOffset = Cursor.tell();
-
- // Tolerate zero-length; assume length is correct and soldier on.
- if (Len == 0) {
- if (Cursor && Verbose)
- *OS << "Badly formed extended line op (length 0)\n";
- if (!Cursor) {
- if (Verbose)
- *OS << "\n";
- RecoverableErrorHandler(Cursor.takeError());
- }
- *OffsetPtr = Cursor.tell();
- continue;
- }
-
- uint8_t SubOpcode = TableData.getU8(Cursor);
- // OperandOffset will be the same as ExtOffset, if it was not possible to
- // read the SubOpcode.
- uint64_t OperandOffset = Cursor.tell();
- if (Verbose)
- *OS << LNExtendedString(SubOpcode);
- switch (SubOpcode) {
- case DW_LNE_end_sequence:
- // Set the end_sequence register of the state machine to true and
- // append a row to the matrix using the current values of the
- // state-machine registers. Then reset the registers to the initial
- // values specified above. Every statement program sequence must end
- // with a DW_LNE_end_sequence instruction which creates a row whose
- // address is that of the byte after the last target machine instruction
- // of the sequence.
- State.Row.EndSequence = true;
- // No need to test the Cursor is valid here, since it must be to get
- // into this code path - if it were invalid, the default case would be
- // followed.
+ while (*OffsetPtr < EndOffset) {
+ DataExtractor::Cursor Cursor(*OffsetPtr);
+
+ if (Verbose)
+ *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr);
+
+ uint64_t OpcodeOffset = *OffsetPtr;
+ uint8_t Opcode = TableData.getU8(Cursor);
+ size_t RowCount = Rows.size();
+
+ if (Cursor && Verbose)
+ *OS << format("%02.02" PRIx8 " ", Opcode);
+
+ if (Opcode == 0) {
+ // Extended Opcodes always start with a zero opcode followed by
+ // a uleb128 length so you can skip ones you don't know about
+ uint64_t Len = TableData.getULEB128(Cursor);
+ uint64_t ExtOffset = Cursor.tell();
+
+ // Tolerate zero-length; assume length is correct and soldier on.
+ if (Len == 0) {
+ if (Cursor && Verbose)
+ *OS << "Badly formed extended line op (length 0)\n";
+ if (!Cursor) {
+ if (Verbose)
+ *OS << "\n";
+ RecoverableErrorHandler(Cursor.takeError());
+ }
+ *OffsetPtr = Cursor.tell();
+ continue;
+ }
+
+ uint8_t SubOpcode = TableData.getU8(Cursor);
+ // OperandOffset will be the same as ExtOffset, if it was not possible to
+ // read the SubOpcode.
+ uint64_t OperandOffset = Cursor.tell();
+ if (Verbose)
+ *OS << LNExtendedString(SubOpcode);
+ switch (SubOpcode) {
+ case DW_LNE_end_sequence:
+ // Set the end_sequence register of the state machine to true and
+ // append a row to the matrix using the current values of the
+ // state-machine registers. Then reset the registers to the initial
+ // values specified above. Every statement program sequence must end
+ // with a DW_LNE_end_sequence instruction which creates a row whose
+ // address is that of the byte after the last target machine instruction
+ // of the sequence.
+ State.Row.EndSequence = true;
+ // No need to test the Cursor is valid here, since it must be to get
+ // into this code path - if it were invalid, the default case would be
+ // followed.
EmitRow();
- State.resetRowAndSequence();
- break;
-
- case DW_LNE_set_address:
- // Takes a single relocatable address as an operand. The size of the
- // operand is the size appropriate to hold an address on the target
- // machine. Set the address register to the value given by the
- // relocatable address. All of the other statement program opcodes
- // that affect the address register add a delta to it. This instruction
- // stores a relocatable value into it instead.
- //
- // Make sure the extractor knows the address size. If not, infer it
- // from the size of the operand.
- {
- uint8_t ExtractorAddressSize = TableData.getAddressSize();
- uint64_t OpcodeAddressSize = Len - 1;
- if (ExtractorAddressSize != OpcodeAddressSize &&
- ExtractorAddressSize != 0)
- RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "mismatching address size at offset 0x%8.8" PRIx64
- " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
- ExtOffset, ExtractorAddressSize, Len - 1));
-
- // Assume that the line table is correct and temporarily override the
- // address size. If the size is unsupported, give up trying to read
- // the address and continue to the next opcode.
- if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
- OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
- RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "address size 0x%2.2" PRIx64
- " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
- " is unsupported",
- OpcodeAddressSize, ExtOffset));
- TableData.skip(Cursor, OpcodeAddressSize);
- } else {
- TableData.setAddressSize(OpcodeAddressSize);
- State.Row.Address.Address = TableData.getRelocatedAddress(
- Cursor, &State.Row.Address.SectionIndex);
-
+ State.resetRowAndSequence();
+ break;
+
+ case DW_LNE_set_address:
+ // Takes a single relocatable address as an operand. The size of the
+ // operand is the size appropriate to hold an address on the target
+ // machine. Set the address register to the value given by the
+ // relocatable address. All of the other statement program opcodes
+ // that affect the address register add a delta to it. This instruction
+ // stores a relocatable value into it instead.
+ //
+ // Make sure the extractor knows the address size. If not, infer it
+ // from the size of the operand.
+ {
+ uint8_t ExtractorAddressSize = TableData.getAddressSize();
+ uint64_t OpcodeAddressSize = Len - 1;
+ if (ExtractorAddressSize != OpcodeAddressSize &&
+ ExtractorAddressSize != 0)
+ RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "mismatching address size at offset 0x%8.8" PRIx64
+ " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
+ ExtOffset, ExtractorAddressSize, Len - 1));
+
+ // Assume that the line table is correct and temporarily override the
+ // address size. If the size is unsupported, give up trying to read
+ // the address and continue to the next opcode.
+ if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
+ OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
+ RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "address size 0x%2.2" PRIx64
+ " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
+ " is unsupported",
+ OpcodeAddressSize, ExtOffset));
+ TableData.skip(Cursor, OpcodeAddressSize);
+ } else {
+ TableData.setAddressSize(OpcodeAddressSize);
+ State.Row.Address.Address = TableData.getRelocatedAddress(
+ Cursor, &State.Row.Address.SectionIndex);
+
uint64_t Tombstone =
dwarf::computeTombstoneAddress(OpcodeAddressSize);
TombstonedAddress = State.Row.Address.Address == Tombstone;
- // Restore the address size if the extractor already had it.
- if (ExtractorAddressSize != 0)
- TableData.setAddressSize(ExtractorAddressSize);
- }
-
+ // Restore the address size if the extractor already had it.
+ if (ExtractorAddressSize != 0)
+ TableData.setAddressSize(ExtractorAddressSize);
+ }
+
if (Cursor && Verbose) {
*OS << " (";
DWARFFormValue::dumpAddress(*OS, OpcodeAddressSize, State.Row.Address.Address);
*OS << ')';
}
- }
- break;
-
- case DW_LNE_define_file:
- // Takes 4 arguments. The first is a null terminated string containing
- // a source file name. The second is an unsigned LEB128 number
- // representing the directory index of the directory in which the file
- // was found. The third is an unsigned LEB128 number representing the
- // time of last modification of the file. The fourth is an unsigned
- // LEB128 number representing the length in bytes of the file. The time
- // and length fields may contain LEB128(0) if the information is not
- // available.
- //
- // The directory index represents an entry in the include_directories
- // section of the statement program prologue. The index is LEB128(0)
- // if the file was found in the current directory of the compilation,
- // LEB128(1) if it was found in the first directory in the
- // include_directories section, and so on. The directory index is
- // ignored for file names that represent full path names.
- //
- // The files are numbered, starting at 1, in the order in which they
- // appear; the names in the prologue come before names defined by
- // the DW_LNE_define_file instruction. These numbers are used in the
- // the file register of the state machine.
- {
- FileNameEntry FileEntry;
- const char *Name = TableData.getCStr(Cursor);
- FileEntry.Name =
- DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name);
- FileEntry.DirIdx = TableData.getULEB128(Cursor);
- FileEntry.ModTime = TableData.getULEB128(Cursor);
- FileEntry.Length = TableData.getULEB128(Cursor);
- Prologue.FileNames.push_back(FileEntry);
- if (Cursor && Verbose)
- *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
- << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
- << ", length=" << FileEntry.Length << ")";
- }
- break;
-
- case DW_LNE_set_discriminator:
- State.Row.Discriminator = TableData.getULEB128(Cursor);
- if (Cursor && Verbose)
- *OS << " (" << State.Row.Discriminator << ")";
- break;
-
- default:
- if (Cursor && Verbose)
- *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
- << format(" length %" PRIx64, Len);
- // Len doesn't include the zero opcode byte or the length itself, but
- // it does include the sub_opcode, so we have to adjust for that.
- TableData.skip(Cursor, Len - 1);
- break;
- }
- // Make sure the length as recorded in the table and the standard length
- // for the opcode match. If they don't, continue from the end as claimed
- // by the table. Similarly, continue from the claimed end in the event of
- // a parsing error.
- uint64_t End = ExtOffset + Len;
- if (Cursor && Cursor.tell() != End)
- RecoverableErrorHandler(createStringError(
- errc::illegal_byte_sequence,
- "unexpected line op length at offset 0x%8.8" PRIx64
- " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
- ExtOffset, Len, Cursor.tell() - ExtOffset));
- if (!Cursor && Verbose) {
- DWARFDataExtractor::Cursor ByteCursor(OperandOffset);
- uint8_t Byte = TableData.getU8(ByteCursor);
- if (ByteCursor) {
- *OS << " (<parsing error>";
- do {
- *OS << format(" %2.2" PRIx8, Byte);
- Byte = TableData.getU8(ByteCursor);
- } while (ByteCursor);
- *OS << ")";
- }
-
- // The only parse failure in this case should be if the end was reached.
- // In that case, throw away the error, as the main Cursor's error will
- // be sufficient.
- consumeError(ByteCursor.takeError());
- }
- *OffsetPtr = End;
- } else if (Opcode < Prologue.OpcodeBase) {
- if (Verbose)
- *OS << LNStandardString(Opcode);
- switch (Opcode) {
- // Standard Opcodes
- case DW_LNS_copy:
- // Takes no arguments. Append a row to the matrix using the
- // current values of the state-machine registers.
+ }
+ break;
+
+ case DW_LNE_define_file:
+ // Takes 4 arguments. The first is a null terminated string containing
+ // a source file name. The second is an unsigned LEB128 number
+ // representing the directory index of the directory in which the file
+ // was found. The third is an unsigned LEB128 number representing the
+ // time of last modification of the file. The fourth is an unsigned
+ // LEB128 number representing the length in bytes of the file. The time
+ // and length fields may contain LEB128(0) if the information is not
+ // available.
+ //
+ // The directory index represents an entry in the include_directories
+ // section of the statement program prologue. The index is LEB128(0)
+ // if the file was found in the current directory of the compilation,
+ // LEB128(1) if it was found in the first directory in the
+ // include_directories section, and so on. The directory index is
+ // ignored for file names that represent full path names.
+ //
+ // The files are numbered, starting at 1, in the order in which they
+ // appear; the names in the prologue come before names defined by
+ // the DW_LNE_define_file instruction. These numbers are used in the
+ // the file register of the state machine.
+ {
+ FileNameEntry FileEntry;
+ const char *Name = TableData.getCStr(Cursor);
+ FileEntry.Name =
+ DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name);
+ FileEntry.DirIdx = TableData.getULEB128(Cursor);
+ FileEntry.ModTime = TableData.getULEB128(Cursor);
+ FileEntry.Length = TableData.getULEB128(Cursor);
+ Prologue.FileNames.push_back(FileEntry);
+ if (Cursor && Verbose)
+ *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
+ << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
+ << ", length=" << FileEntry.Length << ")";
+ }
+ break;
+
+ case DW_LNE_set_discriminator:
+ State.Row.Discriminator = TableData.getULEB128(Cursor);
+ if (Cursor && Verbose)
+ *OS << " (" << State.Row.Discriminator << ")";
+ break;
+
+ default:
+ if (Cursor && Verbose)
+ *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
+ << format(" length %" PRIx64, Len);
+ // Len doesn't include the zero opcode byte or the length itself, but
+ // it does include the sub_opcode, so we have to adjust for that.
+ TableData.skip(Cursor, Len - 1);
+ break;
+ }
+ // Make sure the length as recorded in the table and the standard length
+ // for the opcode match. If they don't, continue from the end as claimed
+ // by the table. Similarly, continue from the claimed end in the event of
+ // a parsing error.
+ uint64_t End = ExtOffset + Len;
+ if (Cursor && Cursor.tell() != End)
+ RecoverableErrorHandler(createStringError(
+ errc::illegal_byte_sequence,
+ "unexpected line op length at offset 0x%8.8" PRIx64
+ " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
+ ExtOffset, Len, Cursor.tell() - ExtOffset));
+ if (!Cursor && Verbose) {
+ DWARFDataExtractor::Cursor ByteCursor(OperandOffset);
+ uint8_t Byte = TableData.getU8(ByteCursor);
+ if (ByteCursor) {
+ *OS << " (<parsing error>";
+ do {
+ *OS << format(" %2.2" PRIx8, Byte);
+ Byte = TableData.getU8(ByteCursor);
+ } while (ByteCursor);
+ *OS << ")";
+ }
+
+ // The only parse failure in this case should be if the end was reached.
+ // In that case, throw away the error, as the main Cursor's error will
+ // be sufficient.
+ consumeError(ByteCursor.takeError());
+ }
+ *OffsetPtr = End;
+ } else if (Opcode < Prologue.OpcodeBase) {
+ if (Verbose)
+ *OS << LNStandardString(Opcode);
+ switch (Opcode) {
+ // Standard Opcodes
+ case DW_LNS_copy:
+ // Takes no arguments. Append a row to the matrix using the
+ // current values of the state-machine registers.
EmitRow();
- break;
-
- case DW_LNS_advance_pc:
- // Takes a single unsigned LEB128 operand, multiplies it by the
- // min_inst_length field of the prologue, and adds the
- // result to the address register of the state machine.
- if (Optional<uint64_t> Operand =
- parseULEB128<uint64_t>(TableData, Cursor)) {
- uint64_t AddrOffset =
- State.advanceAddr(*Operand, Opcode, OpcodeOffset);
- if (Verbose)
- *OS << " (" << AddrOffset << ")";
- }
- break;
-
- case DW_LNS_advance_line:
- // Takes a single signed LEB128 operand and adds that value to
- // the line register of the state machine.
- {
- int64_t LineDelta = TableData.getSLEB128(Cursor);
- if (Cursor) {
- State.Row.Line += LineDelta;
- if (Verbose)
- *OS << " (" << State.Row.Line << ")";
- }
- }
- break;
-
- case DW_LNS_set_file:
- // Takes a single unsigned LEB128 operand and stores it in the file
- // register of the state machine.
- if (Optional<uint16_t> File =
- parseULEB128<uint16_t>(TableData, Cursor)) {
- State.Row.File = *File;
- if (Verbose)
- *OS << " (" << State.Row.File << ")";
- }
- break;
-
- case DW_LNS_set_column:
- // Takes a single unsigned LEB128 operand and stores it in the
- // column register of the state machine.
- if (Optional<uint16_t> Column =
- parseULEB128<uint16_t>(TableData, Cursor)) {
- State.Row.Column = *Column;
- if (Verbose)
- *OS << " (" << State.Row.Column << ")";
- }
- break;
-
- case DW_LNS_negate_stmt:
- // Takes no arguments. Set the is_stmt register of the state
- // machine to the logical negation of its current value.
- State.Row.IsStmt = !State.Row.IsStmt;
- break;
-
- case DW_LNS_set_basic_block:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
- State.Row.BasicBlock = true;
- break;
-
- case DW_LNS_const_add_pc:
- // Takes no arguments. Add to the address register of the state
- // machine the address increment value corresponding to special
- // opcode 255. The motivation for DW_LNS_const_add_pc is this:
- // when the statement program needs to advance the address by a
- // small amount, it can use a single special opcode, which occupies
- // a single byte. When it needs to advance the address by up to
- // twice the range of the last special opcode, it can use
- // DW_LNS_const_add_pc followed by a special opcode, for a total
- // of two bytes. Only if it needs to advance the address by more
- // than twice that range will it need to use both DW_LNS_advance_pc
- // and a special opcode, requiring three or more bytes.
- {
- uint64_t AddrOffset =
- State.advanceAddrForOpcode(Opcode, OpcodeOffset).AddrDelta;
- if (Verbose)
- *OS << format(" (0x%16.16" PRIx64 ")", AddrOffset);
- }
- break;
-
- case DW_LNS_fixed_advance_pc:
- // Takes a single uhalf operand. Add to the address register of
- // the state machine the value of the (unencoded) operand. This
- // is the only extended opcode that takes an argument that is not
- // a variable length number. The motivation for DW_LNS_fixed_advance_pc
- // is this: existing assemblers cannot emit DW_LNS_advance_pc or
- // special opcodes because they cannot encode LEB128 numbers or
- // judge when the computation of a special opcode overflows and
- // requires the use of DW_LNS_advance_pc. Such assemblers, however,
- // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
- {
- uint16_t PCOffset =
- TableData.getRelocatedValue(Cursor, 2);
- if (Cursor) {
- State.Row.Address.Address += PCOffset;
- if (Verbose)
- *OS << format(" (0x%4.4" PRIx16 ")", PCOffset);
- }
- }
- break;
-
- case DW_LNS_set_prologue_end:
- // Takes no arguments. Set the prologue_end register of the
- // state machine to true
- State.Row.PrologueEnd = true;
- break;
-
- case DW_LNS_set_epilogue_begin:
- // Takes no arguments. Set the basic_block register of the
- // state machine to true
- State.Row.EpilogueBegin = true;
- break;
-
- case DW_LNS_set_isa:
- // Takes a single unsigned LEB128 operand and stores it in the
- // ISA register of the state machine.
- if (Optional<uint8_t> Isa = parseULEB128<uint8_t>(TableData, Cursor)) {
- State.Row.Isa = *Isa;
- if (Verbose)
- *OS << " (" << (uint64_t)State.Row.Isa << ")";
- }
- break;
-
- default:
- // Handle any unknown standard opcodes here. We know the lengths
- // of such opcodes because they are specified in the prologue
- // as a multiple of LEB128 operands for each opcode.
- {
- assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
- if (Verbose)
- *OS << "Unrecognized standard opcode";
- uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
- std::vector<uint64_t> Operands;
- for (uint8_t I = 0; I < OpcodeLength; ++I) {
- if (Optional<uint64_t> Value =
- parseULEB128<uint64_t>(TableData, Cursor))
- Operands.push_back(*Value);
- else
- break;
- }
- if (Verbose && !Operands.empty()) {
- *OS << " (operands: ";
- bool First = true;
- for (uint64_t Value : Operands) {
- if (!First)
- *OS << ", ";
- First = false;
- *OS << format("0x%16.16" PRIx64, Value);
- }
- if (Verbose)
- *OS << ')';
- }
- }
- break;
- }
-
- *OffsetPtr = Cursor.tell();
- } else {
- // Special Opcodes.
- ParsingState::AddrAndLineDelta Delta =
- State.handleSpecialOpcode(Opcode, OpcodeOffset);
-
+ break;
+
+ case DW_LNS_advance_pc:
+ // Takes a single unsigned LEB128 operand, multiplies it by the
+ // min_inst_length field of the prologue, and adds the
+ // result to the address register of the state machine.
+ if (Optional<uint64_t> Operand =
+ parseULEB128<uint64_t>(TableData, Cursor)) {
+ uint64_t AddrOffset =
+ State.advanceAddr(*Operand, Opcode, OpcodeOffset);
+ if (Verbose)
+ *OS << " (" << AddrOffset << ")";
+ }
+ break;
+
+ case DW_LNS_advance_line:
+ // Takes a single signed LEB128 operand and adds that value to
+ // the line register of the state machine.
+ {
+ int64_t LineDelta = TableData.getSLEB128(Cursor);
+ if (Cursor) {
+ State.Row.Line += LineDelta;
+ if (Verbose)
+ *OS << " (" << State.Row.Line << ")";
+ }
+ }
+ break;
+
+ case DW_LNS_set_file:
+ // Takes a single unsigned LEB128 operand and stores it in the file
+ // register of the state machine.
+ if (Optional<uint16_t> File =
+ parseULEB128<uint16_t>(TableData, Cursor)) {
+ State.Row.File = *File;
+ if (Verbose)
+ *OS << " (" << State.Row.File << ")";
+ }
+ break;
+
+ case DW_LNS_set_column:
+ // Takes a single unsigned LEB128 operand and stores it in the
+ // column register of the state machine.
+ if (Optional<uint16_t> Column =
+ parseULEB128<uint16_t>(TableData, Cursor)) {
+ State.Row.Column = *Column;
+ if (Verbose)
+ *OS << " (" << State.Row.Column << ")";
+ }
+ break;
+
+ case DW_LNS_negate_stmt:
+ // Takes no arguments. Set the is_stmt register of the state
+ // machine to the logical negation of its current value.
+ State.Row.IsStmt = !State.Row.IsStmt;
+ break;
+
+ case DW_LNS_set_basic_block:
+ // Takes no arguments. Set the basic_block register of the
+ // state machine to true
+ State.Row.BasicBlock = true;
+ break;
+
+ case DW_LNS_const_add_pc:
+ // Takes no arguments. Add to the address register of the state
+ // machine the address increment value corresponding to special
+ // opcode 255. The motivation for DW_LNS_const_add_pc is this:
+ // when the statement program needs to advance the address by a
+ // small amount, it can use a single special opcode, which occupies
+ // a single byte. When it needs to advance the address by up to
+ // twice the range of the last special opcode, it can use
+ // DW_LNS_const_add_pc followed by a special opcode, for a total
+ // of two bytes. Only if it needs to advance the address by more
+ // than twice that range will it need to use both DW_LNS_advance_pc
+ // and a special opcode, requiring three or more bytes.
+ {
+ uint64_t AddrOffset =
+ State.advanceAddrForOpcode(Opcode, OpcodeOffset).AddrDelta;
+ if (Verbose)
+ *OS << format(" (0x%16.16" PRIx64 ")", AddrOffset);
+ }
+ break;
+
+ case DW_LNS_fixed_advance_pc:
+ // Takes a single uhalf operand. Add to the address register of
+ // the state machine the value of the (unencoded) operand. This
+ // is the only extended opcode that takes an argument that is not
+ // a variable length number. The motivation for DW_LNS_fixed_advance_pc
+ // is this: existing assemblers cannot emit DW_LNS_advance_pc or
+ // special opcodes because they cannot encode LEB128 numbers or
+ // judge when the computation of a special opcode overflows and
+ // requires the use of DW_LNS_advance_pc. Such assemblers, however,
+ // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
+ {
+ uint16_t PCOffset =
+ TableData.getRelocatedValue(Cursor, 2);
+ if (Cursor) {
+ State.Row.Address.Address += PCOffset;
+ if (Verbose)
+ *OS << format(" (0x%4.4" PRIx16 ")", PCOffset);
+ }
+ }
+ break;
+
+ case DW_LNS_set_prologue_end:
+ // Takes no arguments. Set the prologue_end register of the
+ // state machine to true
+ State.Row.PrologueEnd = true;
+ break;
+
+ case DW_LNS_set_epilogue_begin:
+ // Takes no arguments. Set the basic_block register of the
+ // state machine to true
+ State.Row.EpilogueBegin = true;
+ break;
+
+ case DW_LNS_set_isa:
+ // Takes a single unsigned LEB128 operand and stores it in the
+ // ISA register of the state machine.
+ if (Optional<uint8_t> Isa = parseULEB128<uint8_t>(TableData, Cursor)) {
+ State.Row.Isa = *Isa;
+ if (Verbose)
+ *OS << " (" << (uint64_t)State.Row.Isa << ")";
+ }
+ break;
+
+ default:
+ // Handle any unknown standard opcodes here. We know the lengths
+ // of such opcodes because they are specified in the prologue
+ // as a multiple of LEB128 operands for each opcode.
+ {
+ assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
+ if (Verbose)
+ *OS << "Unrecognized standard opcode";
+ uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
+ std::vector<uint64_t> Operands;
+ for (uint8_t I = 0; I < OpcodeLength; ++I) {
+ if (Optional<uint64_t> Value =
+ parseULEB128<uint64_t>(TableData, Cursor))
+ Operands.push_back(*Value);
+ else
+ break;
+ }
+ if (Verbose && !Operands.empty()) {
+ *OS << " (operands: ";
+ bool First = true;
+ for (uint64_t Value : Operands) {
+ if (!First)
+ *OS << ", ";
+ First = false;
+ *OS << format("0x%16.16" PRIx64, Value);
+ }
+ if (Verbose)
+ *OS << ')';
+ }
+ }
+ break;
+ }
+
+ *OffsetPtr = Cursor.tell();
+ } else {
+ // Special Opcodes.
+ ParsingState::AddrAndLineDelta Delta =
+ State.handleSpecialOpcode(Opcode, OpcodeOffset);
+
if (Verbose)
*OS << "address += " << Delta.Address << ", line += " << Delta.Line;
EmitRow();
- *OffsetPtr = Cursor.tell();
- }
-
- // When a row is added to the matrix, it is also dumped, which includes a
- // new line already, so don't add an extra one.
- if (Verbose && Rows.size() == RowCount)
- *OS << "\n";
-
- // Most parse failures other than when parsing extended opcodes are due to
- // failures to read ULEBs. Bail out of parsing, since we don't know where to
- // continue reading from as there is no stated length for such byte
- // sequences. Print the final trailing new line if needed before doing so.
- if (!Cursor && Opcode != 0) {
- if (Verbose)
- *OS << "\n";
- return Cursor.takeError();
- }
-
- if (!Cursor)
- RecoverableErrorHandler(Cursor.takeError());
- }
-
- if (!State.Sequence.Empty)
- RecoverableErrorHandler(createStringError(
- errc::illegal_byte_sequence,
- "last sequence in debug line table at offset 0x%8.8" PRIx64
- " is not terminated",
- DebugLineOffset));
-
- // Sort all sequences so that address lookup will work faster.
- if (!Sequences.empty()) {
- 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.
- // We don't report warning in this case. For example,
- // sometimes .so compiled from multiple object files contains a few
- // rudimentary sequences for address ranges [0x0, 0xsomething).
- }
-
- // Terminate the table with a final blank line to clearly delineate it from
- // later dumps.
- if (OS)
- *OS << "\n";
-
- return Error::success();
-}
-
-uint32_t DWARFDebugLine::LineTable::findRowInSeq(
- const DWARFDebugLine::Sequence &Seq,
- object::SectionedAddress Address) const {
- if (!Seq.containsPC(Address))
- return UnknownRowIndex;
- 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;
- 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(
- 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.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(
- 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.Address + Size;
- // First, find an instruction sequence containing the given address.
- DWARFDebugLine::Sequence Sequence;
- Sequence.SectionIndex = Address.SectionIndex;
- Sequence.HighPC = Address.Address;
- SequenceIter LastSeq = Sequences.end();
- SequenceIter SeqPos = llvm::upper_bound(
- Sequences, Sequence, DWARFDebugLine::Sequence::orderByHighPC);
- if (SeqPos == LastSeq || !SeqPos->containsPC(Address))
- return false;
-
- SequenceIter StartPos = SeqPos;
-
- // Add the rows from the first sequence to the vector, starting with the
- // index we just calculated
-
- while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
- const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
- // For the first sequence, we need to find which row in the sequence is the
- // first in our range.
- uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
- if (SeqPos == StartPos)
- FirstRowIndex = findRowInSeq(CurSeq, Address);
-
- // Figure out the last row in the range.
- uint32_t LastRowIndex =
- findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
- if (LastRowIndex == UnknownRowIndex)
- LastRowIndex = CurSeq.LastRowIndex - 1;
-
- assert(FirstRowIndex != UnknownRowIndex);
- assert(LastRowIndex != UnknownRowIndex);
-
- for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
- Result.push_back(I);
- }
-
- ++SeqPos;
- }
-
- return true;
-}
-
-Optional<StringRef> DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
- FileLineInfoKind Kind) const {
- if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex))
- return None;
- const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex);
- if (Optional<const char *> source = Entry.Source.getAsCString())
- return StringRef(*source);
- return None;
-}
-
-static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
- // Debug info can contain paths from any OS, not necessarily
- // an OS we're currently running on. Moreover different compilation units can
- // be compiled on different operating systems and linked together later.
- return sys::path::is_absolute(Path, sys::path::Style::posix) ||
- sys::path::is_absolute(Path, sys::path::Style::windows);
-}
-
-bool DWARFDebugLine::Prologue::getFileNameByIndex(
- uint64_t FileIndex, StringRef CompDir, FileLineInfoKind Kind,
- std::string &Result, sys::path::Style Style) const {
- if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
- return false;
- const FileNameEntry &Entry = getFileNameEntry(FileIndex);
- Optional<const char *> Name = Entry.Name.getAsCString();
- if (!Name)
- return false;
- StringRef FileName = *Name;
- if (Kind == FileLineInfoKind::RawValue ||
- isPathAbsoluteOnWindowsOrPosix(FileName)) {
- Result = std::string(FileName);
- return true;
- }
- if (Kind == FileLineInfoKind::BaseNameOnly) {
- Result = std::string(llvm::sys::path::filename(FileName));
- return true;
- }
-
- SmallString<16> FilePath;
- StringRef IncludeDir;
- // Be defensive about the contents of Entry.
- if (getVersion() >= 5) {
- // DirIdx 0 is the compilation directory, so don't include it for
- // relative names.
- if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
- 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();
- }
-
- // For absolute paths only, include the 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 (Kind == FileLineInfoKind::AbsoluteFilePath && !CompDir.empty() &&
- !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
- sys::path::append(FilePath, Style, CompDir);
-
- assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
- Kind == FileLineInfoKind::RelativeFilePath) &&
- "invalid FileLineInfo Kind");
-
- // sys::path::append skips empty strings.
- sys::path::append(FilePath, Style, IncludeDir, FileName);
- Result = std::string(FilePath.str());
- return true;
-}
-
-bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
- 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)
- return false;
- // Take file number and line/column from the row.
- const auto &Row = Rows[RowIndex];
- if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
- return false;
- Result.Line = Row.Line;
- Result.Column = Row.Column;
- Result.Discriminator = Row.Discriminator;
- Result.Source = getSourceByIndex(Row.File, Kind);
- return true;
-}
-
-// We want to supply the Unit associated with a .debug_line[.dwo] table when
-// we dump it, if possible, but still dump the table even if there isn't a Unit.
-// Therefore, collect up handles on all the Units that point into the
-// line-table section.
-static DWARFDebugLine::SectionParser::LineToUnitMap
+ *OffsetPtr = Cursor.tell();
+ }
+
+ // When a row is added to the matrix, it is also dumped, which includes a
+ // new line already, so don't add an extra one.
+ if (Verbose && Rows.size() == RowCount)
+ *OS << "\n";
+
+ // Most parse failures other than when parsing extended opcodes are due to
+ // failures to read ULEBs. Bail out of parsing, since we don't know where to
+ // continue reading from as there is no stated length for such byte
+ // sequences. Print the final trailing new line if needed before doing so.
+ if (!Cursor && Opcode != 0) {
+ if (Verbose)
+ *OS << "\n";
+ return Cursor.takeError();
+ }
+
+ if (!Cursor)
+ RecoverableErrorHandler(Cursor.takeError());
+ }
+
+ if (!State.Sequence.Empty)
+ RecoverableErrorHandler(createStringError(
+ errc::illegal_byte_sequence,
+ "last sequence in debug line table at offset 0x%8.8" PRIx64
+ " is not terminated",
+ DebugLineOffset));
+
+ // Sort all sequences so that address lookup will work faster.
+ if (!Sequences.empty()) {
+ 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.
+ // We don't report warning in this case. For example,
+ // sometimes .so compiled from multiple object files contains a few
+ // rudimentary sequences for address ranges [0x0, 0xsomething).
+ }
+
+ // Terminate the table with a final blank line to clearly delineate it from
+ // later dumps.
+ if (OS)
+ *OS << "\n";
+
+ return Error::success();
+}
+
+uint32_t DWARFDebugLine::LineTable::findRowInSeq(
+ const DWARFDebugLine::Sequence &Seq,
+ object::SectionedAddress Address) const {
+ if (!Seq.containsPC(Address))
+ return UnknownRowIndex;
+ 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;
+ 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(
+ 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.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(
+ 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.Address + Size;
+ // First, find an instruction sequence containing the given address.
+ DWARFDebugLine::Sequence Sequence;
+ Sequence.SectionIndex = Address.SectionIndex;
+ Sequence.HighPC = Address.Address;
+ SequenceIter LastSeq = Sequences.end();
+ SequenceIter SeqPos = llvm::upper_bound(
+ Sequences, Sequence, DWARFDebugLine::Sequence::orderByHighPC);
+ if (SeqPos == LastSeq || !SeqPos->containsPC(Address))
+ return false;
+
+ SequenceIter StartPos = SeqPos;
+
+ // Add the rows from the first sequence to the vector, starting with the
+ // index we just calculated
+
+ while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
+ const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
+ // For the first sequence, we need to find which row in the sequence is the
+ // first in our range.
+ uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
+ if (SeqPos == StartPos)
+ FirstRowIndex = findRowInSeq(CurSeq, Address);
+
+ // Figure out the last row in the range.
+ uint32_t LastRowIndex =
+ findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
+ if (LastRowIndex == UnknownRowIndex)
+ LastRowIndex = CurSeq.LastRowIndex - 1;
+
+ assert(FirstRowIndex != UnknownRowIndex);
+ assert(LastRowIndex != UnknownRowIndex);
+
+ for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
+ Result.push_back(I);
+ }
+
+ ++SeqPos;
+ }
+
+ return true;
+}
+
+Optional<StringRef> DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
+ FileLineInfoKind Kind) const {
+ if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex))
+ return None;
+ const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex);
+ if (Optional<const char *> source = Entry.Source.getAsCString())
+ return StringRef(*source);
+ return None;
+}
+
+static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
+ // Debug info can contain paths from any OS, not necessarily
+ // an OS we're currently running on. Moreover different compilation units can
+ // be compiled on different operating systems and linked together later.
+ return sys::path::is_absolute(Path, sys::path::Style::posix) ||
+ sys::path::is_absolute(Path, sys::path::Style::windows);
+}
+
+bool DWARFDebugLine::Prologue::getFileNameByIndex(
+ uint64_t FileIndex, StringRef CompDir, FileLineInfoKind Kind,
+ std::string &Result, sys::path::Style Style) const {
+ if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
+ return false;
+ const FileNameEntry &Entry = getFileNameEntry(FileIndex);
+ Optional<const char *> Name = Entry.Name.getAsCString();
+ if (!Name)
+ return false;
+ StringRef FileName = *Name;
+ if (Kind == FileLineInfoKind::RawValue ||
+ isPathAbsoluteOnWindowsOrPosix(FileName)) {
+ Result = std::string(FileName);
+ return true;
+ }
+ if (Kind == FileLineInfoKind::BaseNameOnly) {
+ Result = std::string(llvm::sys::path::filename(FileName));
+ return true;
+ }
+
+ SmallString<16> FilePath;
+ StringRef IncludeDir;
+ // Be defensive about the contents of Entry.
+ if (getVersion() >= 5) {
+ // DirIdx 0 is the compilation directory, so don't include it for
+ // relative names.
+ if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
+ 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();
+ }
+
+ // For absolute paths only, include the 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 (Kind == FileLineInfoKind::AbsoluteFilePath && !CompDir.empty() &&
+ !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
+ sys::path::append(FilePath, Style, CompDir);
+
+ assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
+ Kind == FileLineInfoKind::RelativeFilePath) &&
+ "invalid FileLineInfo Kind");
+
+ // sys::path::append skips empty strings.
+ sys::path::append(FilePath, Style, IncludeDir, FileName);
+ Result = std::string(FilePath.str());
+ return true;
+}
+
+bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
+ 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)
+ return false;
+ // Take file number and line/column from the row.
+ const auto &Row = Rows[RowIndex];
+ if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
+ return false;
+ Result.Line = Row.Line;
+ Result.Column = Row.Column;
+ Result.Discriminator = Row.Discriminator;
+ Result.Source = getSourceByIndex(Row.File, Kind);
+ return true;
+}
+
+// We want to supply the Unit associated with a .debug_line[.dwo] table when
+// we dump it, if possible, but still dump the table even if there isn't a Unit.
+// Therefore, collect up handles on all the Units that point into the
+// line-table section.
+static DWARFDebugLine::SectionParser::LineToUnitMap
buildLineToUnitMap(DWARFUnitVector::iterator_range Units) {
- DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
+ DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
for (const auto &U : Units)
if (auto CUDIE = U->getUnitDIE())
- if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
+ if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
- return LineToUnit;
-}
-
+ return LineToUnit;
+}
+
DWARFDebugLine::SectionParser::SectionParser(
DWARFDataExtractor &Data, const DWARFContext &C,
DWARFUnitVector::iterator_range Units)
- : DebugLineData(Data), Context(C) {
+ : DebugLineData(Data), Context(C) {
LineToUnit = buildLineToUnitMap(Units);
- if (!DebugLineData.isValidOffset(Offset))
- Done = true;
-}
-
-bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
- return TotalLength != 0u;
-}
-
-DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
- function_ref<void(Error)> RecoverableErrorHandler,
- function_ref<void(Error)> UnrecoverableErrorHandler, raw_ostream *OS,
- bool Verbose) {
- assert(DebugLineData.isValidOffset(Offset) &&
- "parsing should have terminated");
- DWARFUnit *U = prepareToParse(Offset);
- uint64_t OldOffset = Offset;
- LineTable LT;
- if (Error Err = LT.parse(DebugLineData, &Offset, Context, U,
- RecoverableErrorHandler, OS, Verbose))
- UnrecoverableErrorHandler(std::move(Err));
- moveToNextTable(OldOffset, LT.Prologue);
- return LT;
-}
-
-void DWARFDebugLine::SectionParser::skip(
- function_ref<void(Error)> RecoverableErrorHandler,
- function_ref<void(Error)> UnrecoverableErrorHandler) {
- assert(DebugLineData.isValidOffset(Offset) &&
- "parsing should have terminated");
- DWARFUnit *U = prepareToParse(Offset);
- uint64_t OldOffset = Offset;
- LineTable LT;
- if (Error Err = LT.Prologue.parse(DebugLineData, &Offset,
- RecoverableErrorHandler, Context, U))
- UnrecoverableErrorHandler(std::move(Err));
- moveToNextTable(OldOffset, LT.Prologue);
-}
-
-DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset) {
- DWARFUnit *U = nullptr;
- auto It = LineToUnit.find(Offset);
- if (It != LineToUnit.end())
- U = It->second;
- DebugLineData.setAddressSize(U ? U->getAddressByteSize() : 0);
- return U;
-}
-
-void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
- const Prologue &P) {
- // If the length field is not valid, we don't know where the next table is, so
- // cannot continue to parse. Mark the parser as done, and leave the Offset
- // value as it currently is. This will be the end of the bad length field.
- if (!P.totalLengthIsValid()) {
- Done = true;
- return;
- }
-
- Offset = OldOffset + P.TotalLength + P.sizeofTotalLength();
- if (!DebugLineData.isValidOffset(Offset)) {
- Done = true;
- }
-}
+ if (!DebugLineData.isValidOffset(Offset))
+ Done = true;
+}
+
+bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
+ return TotalLength != 0u;
+}
+
+DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
+ function_ref<void(Error)> RecoverableErrorHandler,
+ function_ref<void(Error)> UnrecoverableErrorHandler, raw_ostream *OS,
+ bool Verbose) {
+ assert(DebugLineData.isValidOffset(Offset) &&
+ "parsing should have terminated");
+ DWARFUnit *U = prepareToParse(Offset);
+ uint64_t OldOffset = Offset;
+ LineTable LT;
+ if (Error Err = LT.parse(DebugLineData, &Offset, Context, U,
+ RecoverableErrorHandler, OS, Verbose))
+ UnrecoverableErrorHandler(std::move(Err));
+ moveToNextTable(OldOffset, LT.Prologue);
+ return LT;
+}
+
+void DWARFDebugLine::SectionParser::skip(
+ function_ref<void(Error)> RecoverableErrorHandler,
+ function_ref<void(Error)> UnrecoverableErrorHandler) {
+ assert(DebugLineData.isValidOffset(Offset) &&
+ "parsing should have terminated");
+ DWARFUnit *U = prepareToParse(Offset);
+ uint64_t OldOffset = Offset;
+ LineTable LT;
+ if (Error Err = LT.Prologue.parse(DebugLineData, &Offset,
+ RecoverableErrorHandler, Context, U))
+ UnrecoverableErrorHandler(std::move(Err));
+ moveToNextTable(OldOffset, LT.Prologue);
+}
+
+DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset) {
+ DWARFUnit *U = nullptr;
+ auto It = LineToUnit.find(Offset);
+ if (It != LineToUnit.end())
+ U = It->second;
+ DebugLineData.setAddressSize(U ? U->getAddressByteSize() : 0);
+ return U;
+}
+
+void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
+ const Prologue &P) {
+ // If the length field is not valid, we don't know where the next table is, so
+ // cannot continue to parse. Mark the parser as done, and leave the Offset
+ // value as it currently is. This will be the end of the bad length field.
+ if (!P.totalLengthIsValid()) {
+ Done = true;
+ return;
+ }
+
+ Offset = OldOffset + P.TotalLength + P.sizeofTotalLength();
+ if (!DebugLineData.isValidOffset(Offset)) {
+ Done = true;
+ }
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index cdffb36741..f39b3a044a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -1,406 +1,406 @@
-//===- DWARFDebugLoc.cpp --------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/WithColor.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cinttypes>
-#include <cstdint>
-
-using namespace llvm;
-using object::SectionedAddress;
-
-namespace {
-class DWARFLocationInterpreter {
- Optional<object::SectionedAddress> Base;
- std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr;
-
-public:
- DWARFLocationInterpreter(
- Optional<object::SectionedAddress> Base,
- std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr)
- : Base(Base), LookupAddr(std::move(LookupAddr)) {}
-
- Expected<Optional<DWARFLocationExpression>>
- Interpret(const DWARFLocationEntry &E);
-};
-} // namespace
-
-static Error createResolverError(uint32_t Index, unsigned Kind) {
- return createStringError(errc::invalid_argument,
- "Unable to resolve indirect address %u for: %s",
- Index, dwarf::LocListEncodingString(Kind).data());
-}
-
-Expected<Optional<DWARFLocationExpression>>
-DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
- switch (E.Kind) {
- case dwarf::DW_LLE_end_of_list:
- return None;
- case dwarf::DW_LLE_base_addressx: {
- Base = LookupAddr(E.Value0);
- if (!Base)
- return createResolverError(E.Value0, E.Kind);
- return None;
- }
- case dwarf::DW_LLE_startx_endx: {
- Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
- if (!LowPC)
- return createResolverError(E.Value0, E.Kind);
- Optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
- if (!HighPC)
- return createResolverError(E.Value1, E.Kind);
- return DWARFLocationExpression{
- DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
- E.Loc};
- }
- case dwarf::DW_LLE_startx_length: {
- Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
- if (!LowPC)
- return createResolverError(E.Value0, E.Kind);
- return DWARFLocationExpression{DWARFAddressRange{LowPC->Address,
- LowPC->Address + E.Value1,
- LowPC->SectionIndex},
- E.Loc};
- }
- case dwarf::DW_LLE_offset_pair: {
- if (!Base) {
- return createStringError(inconvertibleErrorCode(),
- "Unable to resolve location list offset pair: "
- "Base address not defined");
- }
- DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
- Base->SectionIndex};
- if (Range.SectionIndex == SectionedAddress::UndefSection)
- Range.SectionIndex = E.SectionIndex;
- return DWARFLocationExpression{Range, E.Loc};
- }
- case dwarf::DW_LLE_default_location:
- return DWARFLocationExpression{None, E.Loc};
- case dwarf::DW_LLE_base_address:
- Base = SectionedAddress{E.Value0, E.SectionIndex};
- return None;
- case dwarf::DW_LLE_start_end:
- return DWARFLocationExpression{
- DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
- case dwarf::DW_LLE_start_length:
- return DWARFLocationExpression{
- DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
- E.Loc};
- default:
- llvm_unreachable("unreachable locations list kind");
- }
-}
-
+//===- DWARFDebugLoc.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cinttypes>
+#include <cstdint>
+
+using namespace llvm;
+using object::SectionedAddress;
+
+namespace {
+class DWARFLocationInterpreter {
+ Optional<object::SectionedAddress> Base;
+ std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr;
+
+public:
+ DWARFLocationInterpreter(
+ Optional<object::SectionedAddress> Base,
+ std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr)
+ : Base(Base), LookupAddr(std::move(LookupAddr)) {}
+
+ Expected<Optional<DWARFLocationExpression>>
+ Interpret(const DWARFLocationEntry &E);
+};
+} // namespace
+
+static Error createResolverError(uint32_t Index, unsigned Kind) {
+ return createStringError(errc::invalid_argument,
+ "Unable to resolve indirect address %u for: %s",
+ Index, dwarf::LocListEncodingString(Kind).data());
+}
+
+Expected<Optional<DWARFLocationExpression>>
+DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
+ switch (E.Kind) {
+ case dwarf::DW_LLE_end_of_list:
+ return None;
+ case dwarf::DW_LLE_base_addressx: {
+ Base = LookupAddr(E.Value0);
+ if (!Base)
+ return createResolverError(E.Value0, E.Kind);
+ return None;
+ }
+ case dwarf::DW_LLE_startx_endx: {
+ Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
+ if (!LowPC)
+ return createResolverError(E.Value0, E.Kind);
+ Optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
+ if (!HighPC)
+ return createResolverError(E.Value1, E.Kind);
+ return DWARFLocationExpression{
+ DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
+ E.Loc};
+ }
+ case dwarf::DW_LLE_startx_length: {
+ Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
+ if (!LowPC)
+ return createResolverError(E.Value0, E.Kind);
+ return DWARFLocationExpression{DWARFAddressRange{LowPC->Address,
+ LowPC->Address + E.Value1,
+ LowPC->SectionIndex},
+ E.Loc};
+ }
+ case dwarf::DW_LLE_offset_pair: {
+ if (!Base) {
+ return createStringError(inconvertibleErrorCode(),
+ "Unable to resolve location list offset pair: "
+ "Base address not defined");
+ }
+ DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
+ Base->SectionIndex};
+ if (Range.SectionIndex == SectionedAddress::UndefSection)
+ Range.SectionIndex = E.SectionIndex;
+ return DWARFLocationExpression{Range, E.Loc};
+ }
+ case dwarf::DW_LLE_default_location:
+ return DWARFLocationExpression{None, E.Loc};
+ case dwarf::DW_LLE_base_address:
+ Base = SectionedAddress{E.Value0, E.SectionIndex};
+ return None;
+ case dwarf::DW_LLE_start_end:
+ return DWARFLocationExpression{
+ DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
+ case dwarf::DW_LLE_start_length:
+ return DWARFLocationExpression{
+ DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
+ E.Loc};
+ default:
+ llvm_unreachable("unreachable locations list kind");
+ }
+}
+
static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
ArrayRef<uint8_t> Data, bool IsLittleEndian,
unsigned AddressSize, const MCRegisterInfo *MRI,
DWARFUnit *U) {
- DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
- // Note. We do not pass any format to DWARFExpression, even if the
- // corresponding unit is known. For now, there is only one operation,
- // DW_OP_call_ref, which depends on the format; it is rarely used, and
- // is unexpected in location tables.
+ DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
+ // Note. We do not pass any format to DWARFExpression, even if the
+ // corresponding unit is known. For now, there is only one operation,
+ // DW_OP_call_ref, which depends on the format; it is rarely used, and
+ // is unexpected in location tables.
DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
-}
-
-bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
- Optional<SectionedAddress> BaseAddr,
- const MCRegisterInfo *MRI,
- const DWARFObject &Obj, DWARFUnit *U,
- DIDumpOptions DumpOpts,
- unsigned Indent) const {
- DWARFLocationInterpreter Interp(
- BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
- if (U)
- return U->getAddrOffsetSectionItem(Index);
- return None;
- });
- OS << format("0x%8.8" PRIx64 ": ", *Offset);
- Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
- Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
- if (!Loc || DumpOpts.DisplayRawContents)
- dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
- if (Loc && *Loc) {
- OS << "\n";
- OS.indent(Indent);
- if (DumpOpts.DisplayRawContents)
- OS << " => ";
-
- DIDumpOptions RangeDumpOpts(DumpOpts);
- RangeDumpOpts.DisplayRawContents = false;
- if (Loc.get()->Range)
- Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
- else
- OS << "<default>";
- }
- if (!Loc)
- consumeError(Loc.takeError());
-
- if (E.Kind != dwarf::DW_LLE_base_address &&
- E.Kind != dwarf::DW_LLE_base_addressx &&
- E.Kind != dwarf::DW_LLE_end_of_list) {
- OS << ": ";
+}
+
+bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
+ Optional<SectionedAddress> BaseAddr,
+ const MCRegisterInfo *MRI,
+ const DWARFObject &Obj, DWARFUnit *U,
+ DIDumpOptions DumpOpts,
+ unsigned Indent) const {
+ DWARFLocationInterpreter Interp(
+ BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
+ if (U)
+ return U->getAddrOffsetSectionItem(Index);
+ return None;
+ });
+ OS << format("0x%8.8" PRIx64 ": ", *Offset);
+ Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
+ Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
+ if (!Loc || DumpOpts.DisplayRawContents)
+ dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
+ if (Loc && *Loc) {
+ OS << "\n";
+ OS.indent(Indent);
+ if (DumpOpts.DisplayRawContents)
+ OS << " => ";
+
+ DIDumpOptions RangeDumpOpts(DumpOpts);
+ RangeDumpOpts.DisplayRawContents = false;
+ if (Loc.get()->Range)
+ Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
+ else
+ OS << "<default>";
+ }
+ if (!Loc)
+ consumeError(Loc.takeError());
+
+ if (E.Kind != dwarf::DW_LLE_base_address &&
+ E.Kind != dwarf::DW_LLE_base_addressx &&
+ E.Kind != dwarf::DW_LLE_end_of_list) {
+ OS << ": ";
dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
Data.getAddressSize(), MRI, U);
- }
- return true;
- });
- if (E) {
- DumpOpts.RecoverableErrorHandler(std::move(E));
- return false;
- }
- return true;
-}
-
-Error DWARFLocationTable::visitAbsoluteLocationList(
- uint64_t Offset, Optional<SectionedAddress> BaseAddr,
- std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
- function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
- DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
- return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
- Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
- if (!Loc)
- return Callback(Loc.takeError());
- if (*Loc)
- return Callback(**Loc);
- return true;
- });
-}
-
-void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
- const DWARFObject &Obj, DIDumpOptions DumpOpts,
- Optional<uint64_t> DumpOffset) const {
- auto BaseAddr = None;
- unsigned Indent = 12;
- if (DumpOffset) {
- dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
- Indent);
- } else {
- uint64_t Offset = 0;
- StringRef Separator;
- bool CanContinue = true;
- while (CanContinue && Data.isValidOffset(Offset)) {
- OS << Separator;
- Separator = "\n";
-
- CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
- DumpOpts, Indent);
- OS << '\n';
- }
- }
-}
-
-Error DWARFDebugLoc::visitLocationList(
- uint64_t *Offset,
- function_ref<bool(const DWARFLocationEntry &)> Callback) const {
- DataExtractor::Cursor C(*Offset);
- while (true) {
- uint64_t SectionIndex;
- uint64_t Value0 = Data.getRelocatedAddress(C);
- uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
-
- DWARFLocationEntry E;
-
- // The end of any given location list is marked by an end of list entry,
- // which consists of a 0 for the beginning address offset and a 0 for the
- // ending address offset. A beginning offset of 0xff...f marks the base
- // address selection entry.
- if (Value0 == 0 && Value1 == 0) {
- E.Kind = dwarf::DW_LLE_end_of_list;
- } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
- E.Kind = dwarf::DW_LLE_base_address;
- E.Value0 = Value1;
- E.SectionIndex = SectionIndex;
- } else {
- E.Kind = dwarf::DW_LLE_offset_pair;
- E.Value0 = Value0;
- E.Value1 = Value1;
- E.SectionIndex = SectionIndex;
- unsigned Bytes = Data.getU16(C);
- // A single location description describing the location of the object...
- Data.getU8(C, E.Loc, Bytes);
- }
-
- if (!C)
- return C.takeError();
- if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
- break;
- }
- *Offset = C.tell();
- return Error::success();
-}
-
-void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
- raw_ostream &OS, unsigned Indent,
- DIDumpOptions DumpOpts,
- const DWARFObject &Obj) const {
- uint64_t Value0, Value1;
- switch (Entry.Kind) {
- case dwarf::DW_LLE_base_address:
- Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
- Value1 = Entry.Value0;
- break;
- case dwarf::DW_LLE_offset_pair:
- Value0 = Entry.Value0;
- Value1 = Entry.Value1;
- break;
- case dwarf::DW_LLE_end_of_list:
- return;
- default:
- llvm_unreachable("Not possible in DWARF4!");
- }
- OS << '\n';
- OS.indent(Indent);
- OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
- << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
- DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
-}
-
-Error DWARFDebugLoclists::visitLocationList(
- uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
-
- DataExtractor::Cursor C(*Offset);
- bool Continue = true;
- while (Continue) {
- DWARFLocationEntry E;
- E.Kind = Data.getU8(C);
- switch (E.Kind) {
- case dwarf::DW_LLE_end_of_list:
- break;
- case dwarf::DW_LLE_base_addressx:
- E.Value0 = Data.getULEB128(C);
- break;
- case dwarf::DW_LLE_startx_endx:
- E.Value0 = Data.getULEB128(C);
- E.Value1 = Data.getULEB128(C);
- break;
- case dwarf::DW_LLE_startx_length:
- E.Value0 = Data.getULEB128(C);
- // Pre-DWARF 5 has different interpretation of the length field. We have
- // to support both pre- and standartized styles for the compatibility.
- if (Version < 5)
- E.Value1 = Data.getU32(C);
- else
- E.Value1 = Data.getULEB128(C);
- break;
- case dwarf::DW_LLE_offset_pair:
- E.Value0 = Data.getULEB128(C);
- E.Value1 = Data.getULEB128(C);
- E.SectionIndex = SectionedAddress::UndefSection;
- break;
- case dwarf::DW_LLE_default_location:
- break;
- case dwarf::DW_LLE_base_address:
- E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
- break;
- case dwarf::DW_LLE_start_end:
- E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
- E.Value1 = Data.getRelocatedAddress(C);
- break;
- case dwarf::DW_LLE_start_length:
- E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
- E.Value1 = Data.getULEB128(C);
- break;
- default:
- cantFail(C.takeError());
- return createStringError(errc::illegal_byte_sequence,
- "LLE of kind %x not supported", (int)E.Kind);
- }
-
- if (E.Kind != dwarf::DW_LLE_base_address &&
- E.Kind != dwarf::DW_LLE_base_addressx &&
- E.Kind != dwarf::DW_LLE_end_of_list) {
- unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
- // A single location description describing the location of the object...
- Data.getU8(C, E.Loc, Bytes);
- }
-
- if (!C)
- return C.takeError();
- Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
- }
- *Offset = C.tell();
- return Error::success();
-}
-
-void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
- raw_ostream &OS, unsigned Indent,
- DIDumpOptions DumpOpts,
- const DWARFObject &Obj) const {
- size_t MaxEncodingStringLength = 0;
-#define HANDLE_DW_LLE(ID, NAME) \
- MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
- dwarf::LocListEncodingString(ID).size());
-#include "llvm/BinaryFormat/Dwarf.def"
-
- OS << "\n";
- OS.indent(Indent);
- StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
- // Unsupported encodings should have been reported during parsing.
- assert(!EncodingString.empty() && "Unknown loclist entry encoding");
- OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
- unsigned FieldSize = 2 + 2 * Data.getAddressSize();
- switch (Entry.Kind) {
- case dwarf::DW_LLE_end_of_list:
- case dwarf::DW_LLE_default_location:
- break;
- case dwarf::DW_LLE_startx_endx:
- case dwarf::DW_LLE_startx_length:
- case dwarf::DW_LLE_offset_pair:
- case dwarf::DW_LLE_start_end:
- case dwarf::DW_LLE_start_length:
- OS << format_hex(Entry.Value0, FieldSize) << ", "
- << format_hex(Entry.Value1, FieldSize);
- break;
- case dwarf::DW_LLE_base_addressx:
- case dwarf::DW_LLE_base_address:
- OS << format_hex(Entry.Value0, FieldSize);
- break;
- }
- OS << ')';
- switch (Entry.Kind) {
- case dwarf::DW_LLE_base_address:
- case dwarf::DW_LLE_start_end:
- case dwarf::DW_LLE_start_length:
- DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
- break;
- default:
- break;
- }
-}
-
-void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
- raw_ostream &OS, const MCRegisterInfo *MRI,
- const DWARFObject &Obj,
- DIDumpOptions DumpOpts) {
- if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
- OS << "Invalid dump range\n";
- return;
- }
- uint64_t Offset = StartOffset;
- StringRef Separator;
- bool CanContinue = true;
- while (CanContinue && Offset < StartOffset + Size) {
- OS << Separator;
- Separator = "\n";
-
- CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
- nullptr, DumpOpts, /*Indent=*/12);
- OS << '\n';
- }
-}
+ }
+ return true;
+ });
+ if (E) {
+ DumpOpts.RecoverableErrorHandler(std::move(E));
+ return false;
+ }
+ return true;
+}
+
+Error DWARFLocationTable::visitAbsoluteLocationList(
+ uint64_t Offset, Optional<SectionedAddress> BaseAddr,
+ std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
+ function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
+ DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
+ return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
+ Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
+ if (!Loc)
+ return Callback(Loc.takeError());
+ if (*Loc)
+ return Callback(**Loc);
+ return true;
+ });
+}
+
+void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
+ const DWARFObject &Obj, DIDumpOptions DumpOpts,
+ Optional<uint64_t> DumpOffset) const {
+ auto BaseAddr = None;
+ unsigned Indent = 12;
+ if (DumpOffset) {
+ dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
+ Indent);
+ } else {
+ uint64_t Offset = 0;
+ StringRef Separator;
+ bool CanContinue = true;
+ while (CanContinue && Data.isValidOffset(Offset)) {
+ OS << Separator;
+ Separator = "\n";
+
+ CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
+ DumpOpts, Indent);
+ OS << '\n';
+ }
+ }
+}
+
+Error DWARFDebugLoc::visitLocationList(
+ uint64_t *Offset,
+ function_ref<bool(const DWARFLocationEntry &)> Callback) const {
+ DataExtractor::Cursor C(*Offset);
+ while (true) {
+ uint64_t SectionIndex;
+ uint64_t Value0 = Data.getRelocatedAddress(C);
+ uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
+
+ DWARFLocationEntry E;
+
+ // The end of any given location list is marked by an end of list entry,
+ // which consists of a 0 for the beginning address offset and a 0 for the
+ // ending address offset. A beginning offset of 0xff...f marks the base
+ // address selection entry.
+ if (Value0 == 0 && Value1 == 0) {
+ E.Kind = dwarf::DW_LLE_end_of_list;
+ } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
+ E.Kind = dwarf::DW_LLE_base_address;
+ E.Value0 = Value1;
+ E.SectionIndex = SectionIndex;
+ } else {
+ E.Kind = dwarf::DW_LLE_offset_pair;
+ E.Value0 = Value0;
+ E.Value1 = Value1;
+ E.SectionIndex = SectionIndex;
+ unsigned Bytes = Data.getU16(C);
+ // A single location description describing the location of the object...
+ Data.getU8(C, E.Loc, Bytes);
+ }
+
+ if (!C)
+ return C.takeError();
+ if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
+ break;
+ }
+ *Offset = C.tell();
+ return Error::success();
+}
+
+void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
+ raw_ostream &OS, unsigned Indent,
+ DIDumpOptions DumpOpts,
+ const DWARFObject &Obj) const {
+ uint64_t Value0, Value1;
+ switch (Entry.Kind) {
+ case dwarf::DW_LLE_base_address:
+ Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
+ Value1 = Entry.Value0;
+ break;
+ case dwarf::DW_LLE_offset_pair:
+ Value0 = Entry.Value0;
+ Value1 = Entry.Value1;
+ break;
+ case dwarf::DW_LLE_end_of_list:
+ return;
+ default:
+ llvm_unreachable("Not possible in DWARF4!");
+ }
+ OS << '\n';
+ OS.indent(Indent);
+ OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
+ << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
+ DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
+}
+
+Error DWARFDebugLoclists::visitLocationList(
+ uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
+
+ DataExtractor::Cursor C(*Offset);
+ bool Continue = true;
+ while (Continue) {
+ DWARFLocationEntry E;
+ E.Kind = Data.getU8(C);
+ switch (E.Kind) {
+ case dwarf::DW_LLE_end_of_list:
+ break;
+ case dwarf::DW_LLE_base_addressx:
+ E.Value0 = Data.getULEB128(C);
+ break;
+ case dwarf::DW_LLE_startx_endx:
+ E.Value0 = Data.getULEB128(C);
+ E.Value1 = Data.getULEB128(C);
+ break;
+ case dwarf::DW_LLE_startx_length:
+ E.Value0 = Data.getULEB128(C);
+ // Pre-DWARF 5 has different interpretation of the length field. We have
+ // to support both pre- and standartized styles for the compatibility.
+ if (Version < 5)
+ E.Value1 = Data.getU32(C);
+ else
+ E.Value1 = Data.getULEB128(C);
+ break;
+ case dwarf::DW_LLE_offset_pair:
+ E.Value0 = Data.getULEB128(C);
+ E.Value1 = Data.getULEB128(C);
+ E.SectionIndex = SectionedAddress::UndefSection;
+ break;
+ case dwarf::DW_LLE_default_location:
+ break;
+ case dwarf::DW_LLE_base_address:
+ E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
+ break;
+ case dwarf::DW_LLE_start_end:
+ E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
+ E.Value1 = Data.getRelocatedAddress(C);
+ break;
+ case dwarf::DW_LLE_start_length:
+ E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
+ E.Value1 = Data.getULEB128(C);
+ break;
+ default:
+ cantFail(C.takeError());
+ return createStringError(errc::illegal_byte_sequence,
+ "LLE of kind %x not supported", (int)E.Kind);
+ }
+
+ if (E.Kind != dwarf::DW_LLE_base_address &&
+ E.Kind != dwarf::DW_LLE_base_addressx &&
+ E.Kind != dwarf::DW_LLE_end_of_list) {
+ unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
+ // A single location description describing the location of the object...
+ Data.getU8(C, E.Loc, Bytes);
+ }
+
+ if (!C)
+ return C.takeError();
+ Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
+ }
+ *Offset = C.tell();
+ return Error::success();
+}
+
+void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
+ raw_ostream &OS, unsigned Indent,
+ DIDumpOptions DumpOpts,
+ const DWARFObject &Obj) const {
+ size_t MaxEncodingStringLength = 0;
+#define HANDLE_DW_LLE(ID, NAME) \
+ MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
+ dwarf::LocListEncodingString(ID).size());
+#include "llvm/BinaryFormat/Dwarf.def"
+
+ OS << "\n";
+ OS.indent(Indent);
+ StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
+ // Unsupported encodings should have been reported during parsing.
+ assert(!EncodingString.empty() && "Unknown loclist entry encoding");
+ OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
+ unsigned FieldSize = 2 + 2 * Data.getAddressSize();
+ switch (Entry.Kind) {
+ case dwarf::DW_LLE_end_of_list:
+ case dwarf::DW_LLE_default_location:
+ break;
+ case dwarf::DW_LLE_startx_endx:
+ case dwarf::DW_LLE_startx_length:
+ case dwarf::DW_LLE_offset_pair:
+ case dwarf::DW_LLE_start_end:
+ case dwarf::DW_LLE_start_length:
+ OS << format_hex(Entry.Value0, FieldSize) << ", "
+ << format_hex(Entry.Value1, FieldSize);
+ break;
+ case dwarf::DW_LLE_base_addressx:
+ case dwarf::DW_LLE_base_address:
+ OS << format_hex(Entry.Value0, FieldSize);
+ break;
+ }
+ OS << ')';
+ switch (Entry.Kind) {
+ case dwarf::DW_LLE_base_address:
+ case dwarf::DW_LLE_start_end:
+ case dwarf::DW_LLE_start_length:
+ DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
+ break;
+ default:
+ break;
+ }
+}
+
+void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
+ raw_ostream &OS, const MCRegisterInfo *MRI,
+ const DWARFObject &Obj,
+ DIDumpOptions DumpOpts) {
+ if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
+ OS << "Invalid dump range\n";
+ return;
+ }
+ uint64_t Offset = StartOffset;
+ StringRef Separator;
+ bool CanContinue = true;
+ while (CanContinue && Offset < StartOffset + Size) {
+ OS << Separator;
+ Separator = "\n";
+
+ CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
+ nullptr, DumpOpts, /*Indent=*/12);
+ OS << '\n';
+ }
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
index 80ffd81b34..addc2a3ff2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugMacro.cpp
@@ -1,245 +1,245 @@
-//===- DWARFDebugMacro.cpp ------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/Support/WithColor.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdint>
-
-using namespace llvm;
-using namespace dwarf;
-
-DwarfFormat DWARFDebugMacro::MacroHeader::getDwarfFormat() const {
- return Flags & MACRO_OFFSET_SIZE ? DWARF64 : DWARF32;
-}
-
-uint8_t DWARFDebugMacro::MacroHeader::getOffsetByteSize() const {
- return getDwarfOffsetByteSize(getDwarfFormat());
-}
-
-void DWARFDebugMacro::MacroHeader::dumpMacroHeader(raw_ostream &OS) const {
- // FIXME: Add support for dumping opcode_operands_table
- OS << format("macro header: version = 0x%04" PRIx16, Version)
- << format(", flags = 0x%02" PRIx8, Flags)
- << ", format = " << FormatString(getDwarfFormat());
- if (Flags & MACRO_DEBUG_LINE_OFFSET)
- OS << format(", debug_line_offset = 0x%0*" PRIx64, 2 * getOffsetByteSize(),
- DebugLineOffset);
- OS << "\n";
-}
-
-void DWARFDebugMacro::dump(raw_ostream &OS) const {
- unsigned IndLevel = 0;
- for (const auto &Macros : MacroLists) {
- OS << format("0x%08" PRIx64 ":\n", Macros.Offset);
+//===- DWARFDebugMacro.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace dwarf;
+
+DwarfFormat DWARFDebugMacro::MacroHeader::getDwarfFormat() const {
+ return Flags & MACRO_OFFSET_SIZE ? DWARF64 : DWARF32;
+}
+
+uint8_t DWARFDebugMacro::MacroHeader::getOffsetByteSize() const {
+ return getDwarfOffsetByteSize(getDwarfFormat());
+}
+
+void DWARFDebugMacro::MacroHeader::dumpMacroHeader(raw_ostream &OS) const {
+ // FIXME: Add support for dumping opcode_operands_table
+ OS << format("macro header: version = 0x%04" PRIx16, Version)
+ << format(", flags = 0x%02" PRIx8, Flags)
+ << ", format = " << FormatString(getDwarfFormat());
+ if (Flags & MACRO_DEBUG_LINE_OFFSET)
+ OS << format(", debug_line_offset = 0x%0*" PRIx64, 2 * getOffsetByteSize(),
+ DebugLineOffset);
+ OS << "\n";
+}
+
+void DWARFDebugMacro::dump(raw_ostream &OS) const {
+ unsigned IndLevel = 0;
+ for (const auto &Macros : MacroLists) {
+ OS << format("0x%08" PRIx64 ":\n", Macros.Offset);
if (Macros.IsDebugMacro)
- Macros.Header.dumpMacroHeader(OS);
- for (const Entry &E : Macros.Macros) {
- // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
- // this check handles the case of corrupted ".debug_macinfo" section.
- if (IndLevel > 0)
- IndLevel -= (E.Type == DW_MACINFO_end_file);
- // Print indentation.
- for (unsigned I = 0; I < IndLevel; I++)
- OS << " ";
- IndLevel += (E.Type == DW_MACINFO_start_file);
- // Based on which version we are handling choose appropriate macro forms.
+ Macros.Header.dumpMacroHeader(OS);
+ for (const Entry &E : Macros.Macros) {
+ // There should not be DW_MACINFO_end_file when IndLevel is Zero. However,
+ // this check handles the case of corrupted ".debug_macinfo" section.
+ if (IndLevel > 0)
+ IndLevel -= (E.Type == DW_MACINFO_end_file);
+ // Print indentation.
+ for (unsigned I = 0; I < IndLevel; I++)
+ OS << " ";
+ IndLevel += (E.Type == DW_MACINFO_start_file);
+ // Based on which version we are handling choose appropriate macro forms.
if (Macros.IsDebugMacro)
WithColor(OS, HighlightColor::Macro).get()
<< (Macros.Header.Version < 5 ? GnuMacroString(E.Type)
: MacroString(E.Type));
- else
- WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
- switch (E.Type) {
- default:
- // Got a corrupted ".debug_macinfo/.debug_macro" section (invalid
- // macinfo type).
- break;
- // debug_macro and debug_macinfo share some common encodings.
- // DW_MACRO_define == DW_MACINFO_define
- // DW_MACRO_undef == DW_MACINFO_undef
- // DW_MACRO_start_file == DW_MACINFO_start_file
- // DW_MACRO_end_file == DW_MACINFO_end_file
- // For readability/uniformity we are using DW_MACRO_*.
+ else
+ WithColor(OS, HighlightColor::Macro).get() << MacinfoString(E.Type);
+ switch (E.Type) {
+ default:
+ // Got a corrupted ".debug_macinfo/.debug_macro" section (invalid
+ // macinfo type).
+ break;
+ // debug_macro and debug_macinfo share some common encodings.
+ // DW_MACRO_define == DW_MACINFO_define
+ // DW_MACRO_undef == DW_MACINFO_undef
+ // DW_MACRO_start_file == DW_MACINFO_start_file
+ // DW_MACRO_end_file == DW_MACINFO_end_file
+ // For readability/uniformity we are using DW_MACRO_*.
//
// The GNU .debug_macro extension's entries have the same encoding
// as DWARF 5's DW_MACRO_* entries, so we only use the latter here.
- case DW_MACRO_define:
- case DW_MACRO_undef:
- case DW_MACRO_define_strp:
- case DW_MACRO_undef_strp:
- case DW_MACRO_define_strx:
- case DW_MACRO_undef_strx:
- OS << " - lineno: " << E.Line;
- OS << " macro: " << E.MacroStr;
- break;
- case DW_MACRO_start_file:
- OS << " - lineno: " << E.Line;
- OS << " filenum: " << E.File;
- break;
- case DW_MACRO_import:
- OS << format(" - import offset: 0x%0*" PRIx64,
- 2 * Macros.Header.getOffsetByteSize(), E.ImportOffset);
- break;
- case DW_MACRO_end_file:
- break;
- case DW_MACINFO_vendor_ext:
- OS << " - constant: " << E.ExtConstant;
- OS << " string: " << E.ExtStr;
- break;
- }
- OS << "\n";
- }
- }
-}
-
-Error DWARFDebugMacro::parseImpl(
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
+ case DW_MACRO_define_strp:
+ case DW_MACRO_undef_strp:
+ case DW_MACRO_define_strx:
+ case DW_MACRO_undef_strx:
+ OS << " - lineno: " << E.Line;
+ OS << " macro: " << E.MacroStr;
+ break;
+ case DW_MACRO_start_file:
+ OS << " - lineno: " << E.Line;
+ OS << " filenum: " << E.File;
+ break;
+ case DW_MACRO_import:
+ OS << format(" - import offset: 0x%0*" PRIx64,
+ 2 * Macros.Header.getOffsetByteSize(), E.ImportOffset);
+ break;
+ case DW_MACRO_end_file:
+ break;
+ case DW_MACINFO_vendor_ext:
+ OS << " - constant: " << E.ExtConstant;
+ OS << " string: " << E.ExtStr;
+ break;
+ }
+ OS << "\n";
+ }
+ }
+}
+
+Error DWARFDebugMacro::parseImpl(
Optional<DWARFUnitVector::compile_unit_range> Units,
- Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data,
- bool IsMacro) {
- uint64_t Offset = 0;
- MacroList *M = nullptr;
- using MacroToUnitsMap = DenseMap<uint64_t, DWARFUnit *>;
- MacroToUnitsMap MacroToUnits;
- if (IsMacro && Data.isValidOffset(Offset)) {
- // Keep a mapping from Macro contribution to CUs, this will
- // be needed while retrieving macro from DW_MACRO_define_strx form.
- for (const auto &U : Units.getValue())
- if (auto CUDIE = U->getUnitDIE())
- // Skip units which does not contibutes to macro section.
- if (auto MacroOffset = toSectionOffset(CUDIE.find(DW_AT_macros)))
- MacroToUnits.try_emplace(*MacroOffset, U.get());
- }
- while (Data.isValidOffset(Offset)) {
- if (!M) {
- MacroLists.emplace_back();
- M = &MacroLists.back();
- M->Offset = Offset;
+ Optional<DataExtractor> StringExtractor, DWARFDataExtractor Data,
+ bool IsMacro) {
+ uint64_t Offset = 0;
+ MacroList *M = nullptr;
+ using MacroToUnitsMap = DenseMap<uint64_t, DWARFUnit *>;
+ MacroToUnitsMap MacroToUnits;
+ if (IsMacro && Data.isValidOffset(Offset)) {
+ // Keep a mapping from Macro contribution to CUs, this will
+ // be needed while retrieving macro from DW_MACRO_define_strx form.
+ for (const auto &U : Units.getValue())
+ if (auto CUDIE = U->getUnitDIE())
+ // Skip units which does not contibutes to macro section.
+ if (auto MacroOffset = toSectionOffset(CUDIE.find(DW_AT_macros)))
+ MacroToUnits.try_emplace(*MacroOffset, U.get());
+ }
+ while (Data.isValidOffset(Offset)) {
+ if (!M) {
+ MacroLists.emplace_back();
+ M = &MacroLists.back();
+ M->Offset = Offset;
M->IsDebugMacro = IsMacro;
- if (IsMacro) {
- auto Err = M->Header.parseMacroHeader(Data, &Offset);
- if (Err)
- return Err;
- }
- }
- // A macro list entry consists of:
- M->Macros.emplace_back();
- Entry &E = M->Macros.back();
- // 1. Macinfo type
- E.Type = Data.getULEB128(&Offset);
-
- if (E.Type == 0) {
- // Reached end of a ".debug_macinfo/debug_macro" section contribution.
- M = nullptr;
- continue;
- }
-
- switch (E.Type) {
- default:
- // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
- // Push the corrupted entry to the list and halt parsing.
- E.Type = DW_MACINFO_invalid;
- return Error::success();
- // debug_macro and debug_macinfo share some common encodings.
- // DW_MACRO_define == DW_MACINFO_define
- // DW_MACRO_undef == DW_MACINFO_undef
- // DW_MACRO_start_file == DW_MACINFO_start_file
- // DW_MACRO_end_file == DW_MACINFO_end_file
- // For readibility/uniformity we are using DW_MACRO_*.
- case DW_MACRO_define:
- case DW_MACRO_undef:
- // 2. Source line
- E.Line = Data.getULEB128(&Offset);
- // 3. Macro string
- E.MacroStr = Data.getCStr(&Offset);
- break;
- case DW_MACRO_define_strp:
- case DW_MACRO_undef_strp: {
- if (!IsMacro) {
- // DW_MACRO_define_strp is a new form introduced in DWARFv5, it is
- // not supported in debug_macinfo[.dwo] sections. Assume it as an
- // invalid entry, push it and halt parsing.
- E.Type = DW_MACINFO_invalid;
- return Error::success();
- }
- uint64_t StrOffset = 0;
- // 2. Source line
- E.Line = Data.getULEB128(&Offset);
- // 3. Macro string
- StrOffset =
- Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
- assert(StringExtractor && "String Extractor not found");
- E.MacroStr = StringExtractor->getCStr(&StrOffset);
- break;
- }
- case DW_MACRO_define_strx:
- case DW_MACRO_undef_strx: {
- if (!IsMacro) {
- // DW_MACRO_define_strx is a new form introduced in DWARFv5, it is
- // not supported in debug_macinfo[.dwo] sections. Assume it as an
- // invalid entry, push it and halt parsing.
- E.Type = DW_MACINFO_invalid;
- return Error::success();
- }
- E.Line = Data.getULEB128(&Offset);
- auto MacroContributionOffset = MacroToUnits.find(M->Offset);
- if (MacroContributionOffset == MacroToUnits.end())
- return createStringError(errc::invalid_argument,
- "Macro contribution of the unit not found");
- Optional<uint64_t> StrOffset =
- MacroContributionOffset->second->getStringOffsetSectionItem(
- Data.getULEB128(&Offset));
- if (!StrOffset)
- return createStringError(
- errc::invalid_argument,
- "String offsets contribution of the unit not found");
- E.MacroStr =
- MacroContributionOffset->second->getStringExtractor().getCStr(
- &*StrOffset);
- break;
- }
- case DW_MACRO_start_file:
- // 2. Source line
- E.Line = Data.getULEB128(&Offset);
- // 3. Source file id
- E.File = Data.getULEB128(&Offset);
- break;
- case DW_MACRO_end_file:
- break;
- case DW_MACRO_import:
- E.ImportOffset =
- Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
- break;
- case DW_MACINFO_vendor_ext:
- // 2. Vendor extension constant
- E.ExtConstant = Data.getULEB128(&Offset);
- // 3. Vendor extension string
- E.ExtStr = Data.getCStr(&Offset);
- break;
- }
- }
- return Error::success();
-}
-
-Error DWARFDebugMacro::MacroHeader::parseMacroHeader(DWARFDataExtractor Data,
- uint64_t *Offset) {
- Version = Data.getU16(Offset);
- uint8_t FlagData = Data.getU8(Offset);
-
- // FIXME: Add support for parsing opcode_operands_table
- if (FlagData & MACRO_OPCODE_OPERANDS_TABLE)
- return createStringError(errc::not_supported,
- "opcode_operands_table is not supported");
- Flags = FlagData;
- if (Flags & MACRO_DEBUG_LINE_OFFSET)
- DebugLineOffset = Data.getUnsigned(Offset, getOffsetByteSize());
- return Error::success();
-}
+ if (IsMacro) {
+ auto Err = M->Header.parseMacroHeader(Data, &Offset);
+ if (Err)
+ return Err;
+ }
+ }
+ // A macro list entry consists of:
+ M->Macros.emplace_back();
+ Entry &E = M->Macros.back();
+ // 1. Macinfo type
+ E.Type = Data.getULEB128(&Offset);
+
+ if (E.Type == 0) {
+ // Reached end of a ".debug_macinfo/debug_macro" section contribution.
+ M = nullptr;
+ continue;
+ }
+
+ switch (E.Type) {
+ default:
+ // Got a corrupted ".debug_macinfo" section (invalid macinfo type).
+ // Push the corrupted entry to the list and halt parsing.
+ E.Type = DW_MACINFO_invalid;
+ return Error::success();
+ // debug_macro and debug_macinfo share some common encodings.
+ // DW_MACRO_define == DW_MACINFO_define
+ // DW_MACRO_undef == DW_MACINFO_undef
+ // DW_MACRO_start_file == DW_MACINFO_start_file
+ // DW_MACRO_end_file == DW_MACINFO_end_file
+ // For readibility/uniformity we are using DW_MACRO_*.
+ case DW_MACRO_define:
+ case DW_MACRO_undef:
+ // 2. Source line
+ E.Line = Data.getULEB128(&Offset);
+ // 3. Macro string
+ E.MacroStr = Data.getCStr(&Offset);
+ break;
+ case DW_MACRO_define_strp:
+ case DW_MACRO_undef_strp: {
+ if (!IsMacro) {
+ // DW_MACRO_define_strp is a new form introduced in DWARFv5, it is
+ // not supported in debug_macinfo[.dwo] sections. Assume it as an
+ // invalid entry, push it and halt parsing.
+ E.Type = DW_MACINFO_invalid;
+ return Error::success();
+ }
+ uint64_t StrOffset = 0;
+ // 2. Source line
+ E.Line = Data.getULEB128(&Offset);
+ // 3. Macro string
+ StrOffset =
+ Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
+ assert(StringExtractor && "String Extractor not found");
+ E.MacroStr = StringExtractor->getCStr(&StrOffset);
+ break;
+ }
+ case DW_MACRO_define_strx:
+ case DW_MACRO_undef_strx: {
+ if (!IsMacro) {
+ // DW_MACRO_define_strx is a new form introduced in DWARFv5, it is
+ // not supported in debug_macinfo[.dwo] sections. Assume it as an
+ // invalid entry, push it and halt parsing.
+ E.Type = DW_MACINFO_invalid;
+ return Error::success();
+ }
+ E.Line = Data.getULEB128(&Offset);
+ auto MacroContributionOffset = MacroToUnits.find(M->Offset);
+ if (MacroContributionOffset == MacroToUnits.end())
+ return createStringError(errc::invalid_argument,
+ "Macro contribution of the unit not found");
+ Optional<uint64_t> StrOffset =
+ MacroContributionOffset->second->getStringOffsetSectionItem(
+ Data.getULEB128(&Offset));
+ if (!StrOffset)
+ return createStringError(
+ errc::invalid_argument,
+ "String offsets contribution of the unit not found");
+ E.MacroStr =
+ MacroContributionOffset->second->getStringExtractor().getCStr(
+ &*StrOffset);
+ break;
+ }
+ case DW_MACRO_start_file:
+ // 2. Source line
+ E.Line = Data.getULEB128(&Offset);
+ // 3. Source file id
+ E.File = Data.getULEB128(&Offset);
+ break;
+ case DW_MACRO_end_file:
+ break;
+ case DW_MACRO_import:
+ E.ImportOffset =
+ Data.getRelocatedValue(M->Header.getOffsetByteSize(), &Offset);
+ break;
+ case DW_MACINFO_vendor_ext:
+ // 2. Vendor extension constant
+ E.ExtConstant = Data.getULEB128(&Offset);
+ // 3. Vendor extension string
+ E.ExtStr = Data.getCStr(&Offset);
+ break;
+ }
+ }
+ return Error::success();
+}
+
+Error DWARFDebugMacro::MacroHeader::parseMacroHeader(DWARFDataExtractor Data,
+ uint64_t *Offset) {
+ Version = Data.getU16(Offset);
+ uint8_t FlagData = Data.getU8(Offset);
+
+ // FIXME: Add support for parsing opcode_operands_table
+ if (FlagData & MACRO_OPCODE_OPERANDS_TABLE)
+ return createStringError(errc::not_supported,
+ "opcode_operands_table is not supported");
+ Flags = FlagData;
+ if (Flags & MACRO_DEBUG_LINE_OFFSET)
+ DebugLineOffset = Data.getUnsigned(Offset, getOffsetByteSize());
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
index 5031acdb54..f8e4e9ffcf 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugPubTable.cpp
@@ -1,118 +1,118 @@
-//===- DWARFDebugPubTable.cpp ---------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
-#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdint>
-
-using namespace llvm;
-using namespace dwarf;
-
-void DWARFDebugPubTable::extract(
- DWARFDataExtractor Data, bool GnuStyle,
- function_ref<void(Error)> RecoverableErrorHandler) {
- this->GnuStyle = GnuStyle;
- Sets.clear();
- uint64_t Offset = 0;
- while (Data.isValidOffset(Offset)) {
- uint64_t SetOffset = Offset;
- Sets.push_back({});
- Set &NewSet = Sets.back();
-
- DataExtractor::Cursor C(Offset);
- std::tie(NewSet.Length, NewSet.Format) = Data.getInitialLength(C);
- if (!C) {
- // Drop the newly added set because it does not contain anything useful
- // to dump.
- Sets.pop_back();
- RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "name lookup table at offset 0x%" PRIx64 " parsing failed: %s",
- SetOffset, toString(C.takeError()).c_str()));
- return;
- }
-
- Offset = C.tell() + NewSet.Length;
- DWARFDataExtractor SetData(Data, Offset);
- const unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(NewSet.Format);
-
- NewSet.Version = SetData.getU16(C);
- NewSet.Offset = SetData.getRelocatedValue(C, OffsetSize);
- NewSet.Size = SetData.getUnsigned(C, OffsetSize);
-
- if (!C) {
- // Preserve the newly added set because at least some fields of the header
- // are read and can be dumped.
- RecoverableErrorHandler(
- createStringError(errc::invalid_argument,
- "name lookup table at offset 0x%" PRIx64
- " does not have a complete header: %s",
- SetOffset, toString(C.takeError()).c_str()));
- continue;
- }
-
- while (C) {
- uint64_t DieRef = SetData.getUnsigned(C, OffsetSize);
- if (DieRef == 0)
- break;
- uint8_t IndexEntryValue = GnuStyle ? SetData.getU8(C) : 0;
- StringRef Name = SetData.getCStrRef(C);
- if (C)
- NewSet.Entries.push_back(
- {DieRef, PubIndexEntryDescriptor(IndexEntryValue), Name});
- }
-
- if (!C) {
- RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "name lookup table at offset 0x%" PRIx64 " parsing failed: %s",
- SetOffset, toString(C.takeError()).c_str()));
- continue;
- }
- if (C.tell() != Offset)
- RecoverableErrorHandler(createStringError(
- errc::invalid_argument,
- "name lookup table at offset 0x%" PRIx64
- " has a terminator at offset 0x%" PRIx64
- " before the expected end at 0x%" PRIx64,
- SetOffset, C.tell() - OffsetSize, Offset - OffsetSize));
- }
-}
-
-void DWARFDebugPubTable::dump(raw_ostream &OS) const {
- for (const Set &S : Sets) {
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(S.Format);
- OS << "length = " << format("0x%0*" PRIx64, OffsetDumpWidth, S.Length);
- OS << ", format = " << dwarf::FormatString(S.Format);
- OS << ", version = " << format("0x%04x", S.Version);
- OS << ", unit_offset = "
- << format("0x%0*" PRIx64, OffsetDumpWidth, S.Offset);
- OS << ", unit_size = " << format("0x%0*" PRIx64, OffsetDumpWidth, S.Size)
- << '\n';
- OS << (GnuStyle ? "Offset Linkage Kind Name\n"
- : "Offset Name\n");
-
- for (const Entry &E : S.Entries) {
- OS << format("0x%0*" PRIx64 " ", OffsetDumpWidth, E.SecOffset);
- if (GnuStyle) {
- StringRef EntryLinkage =
- GDBIndexEntryLinkageString(E.Descriptor.Linkage);
- StringRef EntryKind = dwarf::GDBIndexEntryKindString(E.Descriptor.Kind);
- OS << format("%-8s", EntryLinkage.data()) << ' '
- << format("%-8s", EntryKind.data()) << ' ';
- }
- OS << '\"' << E.Name << "\"\n";
- }
- }
-}
+//===- DWARFDebugPubTable.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
+#include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace dwarf;
+
+void DWARFDebugPubTable::extract(
+ DWARFDataExtractor Data, bool GnuStyle,
+ function_ref<void(Error)> RecoverableErrorHandler) {
+ this->GnuStyle = GnuStyle;
+ Sets.clear();
+ uint64_t Offset = 0;
+ while (Data.isValidOffset(Offset)) {
+ uint64_t SetOffset = Offset;
+ Sets.push_back({});
+ Set &NewSet = Sets.back();
+
+ DataExtractor::Cursor C(Offset);
+ std::tie(NewSet.Length, NewSet.Format) = Data.getInitialLength(C);
+ if (!C) {
+ // Drop the newly added set because it does not contain anything useful
+ // to dump.
+ Sets.pop_back();
+ RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "name lookup table at offset 0x%" PRIx64 " parsing failed: %s",
+ SetOffset, toString(C.takeError()).c_str()));
+ return;
+ }
+
+ Offset = C.tell() + NewSet.Length;
+ DWARFDataExtractor SetData(Data, Offset);
+ const unsigned OffsetSize = dwarf::getDwarfOffsetByteSize(NewSet.Format);
+
+ NewSet.Version = SetData.getU16(C);
+ NewSet.Offset = SetData.getRelocatedValue(C, OffsetSize);
+ NewSet.Size = SetData.getUnsigned(C, OffsetSize);
+
+ if (!C) {
+ // Preserve the newly added set because at least some fields of the header
+ // are read and can be dumped.
+ RecoverableErrorHandler(
+ createStringError(errc::invalid_argument,
+ "name lookup table at offset 0x%" PRIx64
+ " does not have a complete header: %s",
+ SetOffset, toString(C.takeError()).c_str()));
+ continue;
+ }
+
+ while (C) {
+ uint64_t DieRef = SetData.getUnsigned(C, OffsetSize);
+ if (DieRef == 0)
+ break;
+ uint8_t IndexEntryValue = GnuStyle ? SetData.getU8(C) : 0;
+ StringRef Name = SetData.getCStrRef(C);
+ if (C)
+ NewSet.Entries.push_back(
+ {DieRef, PubIndexEntryDescriptor(IndexEntryValue), Name});
+ }
+
+ if (!C) {
+ RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "name lookup table at offset 0x%" PRIx64 " parsing failed: %s",
+ SetOffset, toString(C.takeError()).c_str()));
+ continue;
+ }
+ if (C.tell() != Offset)
+ RecoverableErrorHandler(createStringError(
+ errc::invalid_argument,
+ "name lookup table at offset 0x%" PRIx64
+ " has a terminator at offset 0x%" PRIx64
+ " before the expected end at 0x%" PRIx64,
+ SetOffset, C.tell() - OffsetSize, Offset - OffsetSize));
+ }
+}
+
+void DWARFDebugPubTable::dump(raw_ostream &OS) const {
+ for (const Set &S : Sets) {
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(S.Format);
+ OS << "length = " << format("0x%0*" PRIx64, OffsetDumpWidth, S.Length);
+ OS << ", format = " << dwarf::FormatString(S.Format);
+ OS << ", version = " << format("0x%04x", S.Version);
+ OS << ", unit_offset = "
+ << format("0x%0*" PRIx64, OffsetDumpWidth, S.Offset);
+ OS << ", unit_size = " << format("0x%0*" PRIx64, OffsetDumpWidth, S.Size)
+ << '\n';
+ OS << (GnuStyle ? "Offset Linkage Kind Name\n"
+ : "Offset Name\n");
+
+ for (const Entry &E : S.Entries) {
+ OS << format("0x%0*" PRIx64 " ", OffsetDumpWidth, E.SecOffset);
+ if (GnuStyle) {
+ StringRef EntryLinkage =
+ GDBIndexEntryLinkageString(E.Descriptor.Linkage);
+ StringRef EntryKind = dwarf::GDBIndexEntryKindString(E.Descriptor.Kind);
+ OS << format("%-8s", EntryLinkage.data()) << ' '
+ << format("%-8s", EntryKind.data()) << ' ';
+ }
+ OS << '\"' << E.Name << "\"\n";
+ }
+ }
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index dc7da5d934..f9464af237 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -1,102 +1,102 @@
-//===- DWARFDebugRangesList.cpp -------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cinttypes>
-#include <cstdint>
-
-using namespace llvm;
-
-void DWARFDebugRangeList::clear() {
- Offset = -1ULL;
- AddressSize = 0;
- Entries.clear();
-}
-
-Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
- uint64_t *offset_ptr) {
- clear();
- if (!data.isValidOffset(*offset_ptr))
- return createStringError(errc::invalid_argument,
- "invalid range list offset 0x%" PRIx64, *offset_ptr);
-
- AddressSize = data.getAddressSize();
- if (AddressSize != 4 && AddressSize != 8)
- return createStringError(errc::invalid_argument,
- "invalid address size: %" PRIu8, AddressSize);
- Offset = *offset_ptr;
- while (true) {
- RangeListEntry Entry;
- Entry.SectionIndex = -1ULL;
-
- uint64_t prev_offset = *offset_ptr;
- Entry.StartAddress = data.getRelocatedAddress(offset_ptr);
- Entry.EndAddress =
- data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex);
-
- // Check that both values were extracted correctly.
- if (*offset_ptr != prev_offset + 2 * AddressSize) {
- clear();
- return createStringError(errc::invalid_argument,
- "invalid range list entry at offset 0x%" PRIx64,
- prev_offset);
- }
- if (Entry.isEndOfListEntry())
- break;
- Entries.push_back(Entry);
- }
- return Error::success();
-}
-
-void DWARFDebugRangeList::dump(raw_ostream &OS) const {
- for (const RangeListEntry &RLE : Entries) {
- const char *format_str =
- (AddressSize == 4 ? "%08" PRIx64 " %08" PRIx64 " %08" PRIx64 "\n"
- : "%08" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n");
- OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
- }
- OS << format("%08" PRIx64 " <End of list>\n", Offset);
-}
-
-DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
- llvm::Optional<object::SectionedAddress> BaseAddr) const {
- DWARFAddressRangesVector Res;
+//===- DWARFDebugRangesList.cpp -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cinttypes>
+#include <cstdint>
+
+using namespace llvm;
+
+void DWARFDebugRangeList::clear() {
+ Offset = -1ULL;
+ AddressSize = 0;
+ Entries.clear();
+}
+
+Error DWARFDebugRangeList::extract(const DWARFDataExtractor &data,
+ uint64_t *offset_ptr) {
+ clear();
+ if (!data.isValidOffset(*offset_ptr))
+ return createStringError(errc::invalid_argument,
+ "invalid range list offset 0x%" PRIx64, *offset_ptr);
+
+ AddressSize = data.getAddressSize();
+ if (AddressSize != 4 && AddressSize != 8)
+ return createStringError(errc::invalid_argument,
+ "invalid address size: %" PRIu8, AddressSize);
+ Offset = *offset_ptr;
+ while (true) {
+ RangeListEntry Entry;
+ Entry.SectionIndex = -1ULL;
+
+ uint64_t prev_offset = *offset_ptr;
+ Entry.StartAddress = data.getRelocatedAddress(offset_ptr);
+ Entry.EndAddress =
+ data.getRelocatedAddress(offset_ptr, &Entry.SectionIndex);
+
+ // Check that both values were extracted correctly.
+ if (*offset_ptr != prev_offset + 2 * AddressSize) {
+ clear();
+ return createStringError(errc::invalid_argument,
+ "invalid range list entry at offset 0x%" PRIx64,
+ prev_offset);
+ }
+ if (Entry.isEndOfListEntry())
+ break;
+ Entries.push_back(Entry);
+ }
+ return Error::success();
+}
+
+void DWARFDebugRangeList::dump(raw_ostream &OS) const {
+ for (const RangeListEntry &RLE : Entries) {
+ const char *format_str =
+ (AddressSize == 4 ? "%08" PRIx64 " %08" PRIx64 " %08" PRIx64 "\n"
+ : "%08" PRIx64 " %016" PRIx64 " %016" PRIx64 "\n");
+ OS << format(format_str, Offset, RLE.StartAddress, RLE.EndAddress);
+ }
+ OS << format("%08" PRIx64 " <End of list>\n", Offset);
+}
+
+DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
+ llvm::Optional<object::SectionedAddress> BaseAddr) const {
+ DWARFAddressRangesVector Res;
// debug_addr can't use the max integer tombstone because that's used for the
// base address specifier entry - so use max-1.
uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressSize) - 1;
- for (const RangeListEntry &RLE : Entries) {
- if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
- BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
- continue;
- }
-
- DWARFAddressRange E;
- E.LowPC = RLE.StartAddress;
+ for (const RangeListEntry &RLE : Entries) {
+ if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
+ BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
+ continue;
+ }
+
+ DWARFAddressRange E;
+ E.LowPC = RLE.StartAddress;
if (E.LowPC == Tombstone)
continue;
- E.HighPC = RLE.EndAddress;
- E.SectionIndex = RLE.SectionIndex;
- // Base address of a range list entry is determined by the closest preceding
- // base address selection entry in the same range list. It defaults to the
- // base address of the compilation unit if there is no such entry.
- if (BaseAddr) {
+ E.HighPC = RLE.EndAddress;
+ E.SectionIndex = RLE.SectionIndex;
+ // Base address of a range list entry is determined by the closest preceding
+ // base address selection entry in the same range list. It defaults to the
+ // base address of the compilation unit if there is no such entry.
+ if (BaseAddr) {
if (BaseAddr->Address == Tombstone)
continue;
- E.LowPC += BaseAddr->Address;
- E.HighPC += BaseAddr->Address;
- if (E.SectionIndex == -1ULL)
- E.SectionIndex = BaseAddr->SectionIndex;
- }
- Res.push_back(E);
- }
- return Res;
-}
+ E.LowPC += BaseAddr->Address;
+ E.HighPC += BaseAddr->Address;
+ if (E.SectionIndex == -1ULL)
+ E.SectionIndex = BaseAddr->SectionIndex;
+ }
+ Res.push_back(E);
+ }
+ return Res;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
index d12acca196..fece448bb8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDebugRnglists.cpp
@@ -1,77 +1,77 @@
-//===- DWARFDebugRnglists.cpp ---------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
-#include "llvm/BinaryFormat/Dwarf.h"
+//===- DWARFDebugRnglists.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
- Offset = *OffsetPtr;
- SectionIndex = -1ULL;
- // The caller should guarantee that we have at least 1 byte available, so
- // we just assert instead of revalidate.
+ Offset = *OffsetPtr;
+ SectionIndex = -1ULL;
+ // The caller should guarantee that we have at least 1 byte available, so
+ // we just assert instead of revalidate.
assert(*OffsetPtr < Data.size() &&
- "not enough space to extract a rangelist encoding");
- uint8_t Encoding = Data.getU8(OffsetPtr);
-
+ "not enough space to extract a rangelist encoding");
+ uint8_t Encoding = Data.getU8(OffsetPtr);
+
DataExtractor::Cursor C(*OffsetPtr);
- switch (Encoding) {
- case dwarf::DW_RLE_end_of_list:
- Value0 = Value1 = 0;
- break;
- // TODO: Support other encodings.
- case dwarf::DW_RLE_base_addressx: {
+ switch (Encoding) {
+ case dwarf::DW_RLE_end_of_list:
+ Value0 = Value1 = 0;
+ break;
+ // TODO: Support other encodings.
+ case dwarf::DW_RLE_base_addressx: {
Value0 = Data.getULEB128(C);
- break;
- }
- case dwarf::DW_RLE_startx_endx:
+ break;
+ }
+ case dwarf::DW_RLE_startx_endx:
Value0 = Data.getULEB128(C);
Value1 = Data.getULEB128(C);
break;
- case dwarf::DW_RLE_startx_length: {
+ case dwarf::DW_RLE_startx_length: {
Value0 = Data.getULEB128(C);
Value1 = Data.getULEB128(C);
- break;
- }
- case dwarf::DW_RLE_offset_pair: {
+ break;
+ }
+ case dwarf::DW_RLE_offset_pair: {
Value0 = Data.getULEB128(C);
Value1 = Data.getULEB128(C);
- break;
- }
- case dwarf::DW_RLE_base_address: {
+ break;
+ }
+ case dwarf::DW_RLE_base_address: {
Value0 = Data.getRelocatedAddress(C, &SectionIndex);
- break;
- }
- case dwarf::DW_RLE_start_end: {
+ break;
+ }
+ case dwarf::DW_RLE_start_end: {
Value0 = Data.getRelocatedAddress(C, &SectionIndex);
Value1 = Data.getRelocatedAddress(C);
- break;
- }
- case dwarf::DW_RLE_start_length: {
+ break;
+ }
+ case dwarf::DW_RLE_start_length: {
Value0 = Data.getRelocatedAddress(C, &SectionIndex);
Value1 = Data.getULEB128(C);
- break;
- }
- default:
+ break;
+ }
+ default:
consumeError(C.takeError());
- return createStringError(errc::not_supported,
+ return createStringError(errc::not_supported,
"unknown rnglists encoding 0x%" PRIx32
" at offset 0x%" PRIx64,
uint32_t(Encoding), Offset);
- }
-
+ }
+
if (!C) {
consumeError(C.takeError());
return createStringError(
@@ -81,72 +81,72 @@ Error RangeListEntry::extract(DWARFDataExtractor Data, uint64_t *OffsetPtr) {
}
*OffsetPtr = C.tell();
- EntryKind = Encoding;
- return Error::success();
-}
-
-DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
- llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
+ EntryKind = Encoding;
+ return Error::success();
+}
+
+DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
+ llvm::Optional<object::SectionedAddress> BaseAddr, DWARFUnit &U) const {
return getAbsoluteRanges(
BaseAddr, U.getAddressByteSize(),
[&](uint32_t Index) { return U.getAddrOffsetSectionItem(Index); });
-}
-
-DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
+}
+
+DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
Optional<object::SectionedAddress> BaseAddr, uint8_t AddressByteSize,
- function_ref<Optional<object::SectionedAddress>(uint32_t)>
- LookupPooledAddress) const {
- DWARFAddressRangesVector Res;
+ function_ref<Optional<object::SectionedAddress>(uint32_t)>
+ LookupPooledAddress) const {
+ DWARFAddressRangesVector Res;
uint64_t Tombstone = dwarf::computeTombstoneAddress(AddressByteSize);
- for (const RangeListEntry &RLE : Entries) {
- if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
- break;
- if (RLE.EntryKind == dwarf::DW_RLE_base_addressx) {
- BaseAddr = LookupPooledAddress(RLE.Value0);
- if (!BaseAddr)
- BaseAddr = {RLE.Value0, -1ULL};
- continue;
- }
- if (RLE.EntryKind == dwarf::DW_RLE_base_address) {
- BaseAddr = {RLE.Value0, RLE.SectionIndex};
- continue;
- }
-
- DWARFAddressRange E;
- E.SectionIndex = RLE.SectionIndex;
- if (BaseAddr && E.SectionIndex == -1ULL)
- E.SectionIndex = BaseAddr->SectionIndex;
-
- switch (RLE.EntryKind) {
- case dwarf::DW_RLE_offset_pair:
- E.LowPC = RLE.Value0;
+ for (const RangeListEntry &RLE : Entries) {
+ if (RLE.EntryKind == dwarf::DW_RLE_end_of_list)
+ break;
+ if (RLE.EntryKind == dwarf::DW_RLE_base_addressx) {
+ BaseAddr = LookupPooledAddress(RLE.Value0);
+ if (!BaseAddr)
+ BaseAddr = {RLE.Value0, -1ULL};
+ continue;
+ }
+ if (RLE.EntryKind == dwarf::DW_RLE_base_address) {
+ BaseAddr = {RLE.Value0, RLE.SectionIndex};
+ continue;
+ }
+
+ DWARFAddressRange E;
+ E.SectionIndex = RLE.SectionIndex;
+ if (BaseAddr && E.SectionIndex == -1ULL)
+ E.SectionIndex = BaseAddr->SectionIndex;
+
+ switch (RLE.EntryKind) {
+ case dwarf::DW_RLE_offset_pair:
+ E.LowPC = RLE.Value0;
if (E.LowPC == Tombstone)
continue;
- E.HighPC = RLE.Value1;
- if (BaseAddr) {
+ E.HighPC = RLE.Value1;
+ if (BaseAddr) {
if (BaseAddr->Address == Tombstone)
continue;
- E.LowPC += BaseAddr->Address;
- E.HighPC += BaseAddr->Address;
- }
- break;
- case dwarf::DW_RLE_start_end:
- E.LowPC = RLE.Value0;
- E.HighPC = RLE.Value1;
- break;
- case dwarf::DW_RLE_start_length:
- E.LowPC = RLE.Value0;
- E.HighPC = E.LowPC + RLE.Value1;
- break;
- case dwarf::DW_RLE_startx_length: {
- auto Start = LookupPooledAddress(RLE.Value0);
- if (!Start)
- Start = {0, -1ULL};
- E.SectionIndex = Start->SectionIndex;
- E.LowPC = Start->Address;
- E.HighPC = E.LowPC + RLE.Value1;
- break;
- }
+ E.LowPC += BaseAddr->Address;
+ E.HighPC += BaseAddr->Address;
+ }
+ break;
+ case dwarf::DW_RLE_start_end:
+ E.LowPC = RLE.Value0;
+ E.HighPC = RLE.Value1;
+ break;
+ case dwarf::DW_RLE_start_length:
+ E.LowPC = RLE.Value0;
+ E.HighPC = E.LowPC + RLE.Value1;
+ break;
+ case dwarf::DW_RLE_startx_length: {
+ auto Start = LookupPooledAddress(RLE.Value0);
+ if (!Start)
+ Start = {0, -1ULL};
+ E.SectionIndex = Start->SectionIndex;
+ E.LowPC = Start->Address;
+ E.HighPC = E.LowPC + RLE.Value1;
+ break;
+ }
case dwarf::DW_RLE_startx_endx: {
auto Start = LookupPooledAddress(RLE.Value0);
if (!Start)
@@ -160,91 +160,91 @@ DWARFAddressRangesVector DWARFDebugRnglist::getAbsoluteRanges(
E.HighPC = End->Address;
break;
}
- default:
- // Unsupported encodings should have been reported during extraction,
- // so we should not run into any here.
- llvm_unreachable("Unsupported range list encoding");
- }
+ default:
+ // Unsupported encodings should have been reported during extraction,
+ // so we should not run into any here.
+ llvm_unreachable("Unsupported range list encoding");
+ }
if (E.LowPC == Tombstone)
continue;
- Res.push_back(E);
- }
- return Res;
-}
-
-void RangeListEntry::dump(
- raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
- uint64_t &CurrentBase, DIDumpOptions DumpOpts,
- llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
- LookupPooledAddress) const {
- auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry,
- uint8_t AddrSize, DIDumpOptions DumpOpts) {
- if (DumpOpts.Verbose) {
- DumpOpts.DisplayRawContents = true;
- DWARFAddressRange(Entry.Value0, Entry.Value1)
- .dump(OS, AddrSize, DumpOpts);
- OS << " => ";
- }
- };
-
- if (DumpOpts.Verbose) {
- // Print the section offset in verbose mode.
- OS << format("0x%8.8" PRIx64 ":", Offset);
- auto EncodingString = dwarf::RangeListEncodingString(EntryKind);
- // Unsupported encodings should have been reported during parsing.
- assert(!EncodingString.empty() && "Unknown range entry encoding");
- OS << format(" [%s%*c", EncodingString.data(),
- MaxEncodingStringLength - EncodingString.size() + 1, ']');
- if (EntryKind != dwarf::DW_RLE_end_of_list)
- OS << ": ";
- }
-
+ Res.push_back(E);
+ }
+ return Res;
+}
+
+void RangeListEntry::dump(
+ raw_ostream &OS, uint8_t AddrSize, uint8_t MaxEncodingStringLength,
+ uint64_t &CurrentBase, DIDumpOptions DumpOpts,
+ llvm::function_ref<Optional<object::SectionedAddress>(uint32_t)>
+ LookupPooledAddress) const {
+ auto PrintRawEntry = [](raw_ostream &OS, const RangeListEntry &Entry,
+ uint8_t AddrSize, DIDumpOptions DumpOpts) {
+ if (DumpOpts.Verbose) {
+ DumpOpts.DisplayRawContents = true;
+ DWARFAddressRange(Entry.Value0, Entry.Value1)
+ .dump(OS, AddrSize, DumpOpts);
+ OS << " => ";
+ }
+ };
+
+ if (DumpOpts.Verbose) {
+ // Print the section offset in verbose mode.
+ OS << format("0x%8.8" PRIx64 ":", Offset);
+ auto EncodingString = dwarf::RangeListEncodingString(EntryKind);
+ // Unsupported encodings should have been reported during parsing.
+ assert(!EncodingString.empty() && "Unknown range entry encoding");
+ OS << format(" [%s%*c", EncodingString.data(),
+ MaxEncodingStringLength - EncodingString.size() + 1, ']');
+ if (EntryKind != dwarf::DW_RLE_end_of_list)
+ OS << ": ";
+ }
+
uint64_t Tombstone = dwarf::computeTombstoneAddress(AddrSize);
- switch (EntryKind) {
- case dwarf::DW_RLE_end_of_list:
- OS << (DumpOpts.Verbose ? "" : "<End of list>");
- break;
- case dwarf::DW_RLE_base_addressx: {
- if (auto SA = LookupPooledAddress(Value0))
- CurrentBase = SA->Address;
- else
- CurrentBase = Value0;
- if (!DumpOpts.Verbose)
- return;
+ switch (EntryKind) {
+ case dwarf::DW_RLE_end_of_list:
+ OS << (DumpOpts.Verbose ? "" : "<End of list>");
+ break;
+ case dwarf::DW_RLE_base_addressx: {
+ if (auto SA = LookupPooledAddress(Value0))
+ CurrentBase = SA->Address;
+ else
+ CurrentBase = Value0;
+ if (!DumpOpts.Verbose)
+ return;
DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
- break;
- }
- case dwarf::DW_RLE_base_address:
- // In non-verbose mode we do not print anything for this entry.
- CurrentBase = Value0;
- if (!DumpOpts.Verbose)
- return;
+ break;
+ }
+ case dwarf::DW_RLE_base_address:
+ // In non-verbose mode we do not print anything for this entry.
+ CurrentBase = Value0;
+ if (!DumpOpts.Verbose)
+ return;
DWARFFormValue::dumpAddress(OS << ' ', AddrSize, Value0);
- break;
- case dwarf::DW_RLE_start_length:
- PrintRawEntry(OS, *this, AddrSize, DumpOpts);
- DWARFAddressRange(Value0, Value0 + Value1).dump(OS, AddrSize, DumpOpts);
- break;
- case dwarf::DW_RLE_offset_pair:
- PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ break;
+ case dwarf::DW_RLE_start_length:
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ DWARFAddressRange(Value0, Value0 + Value1).dump(OS, AddrSize, DumpOpts);
+ break;
+ case dwarf::DW_RLE_offset_pair:
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
if (CurrentBase != Tombstone)
DWARFAddressRange(Value0 + CurrentBase, Value1 + CurrentBase)
.dump(OS, AddrSize, DumpOpts);
else
OS << "dead code";
- break;
- case dwarf::DW_RLE_start_end:
- DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);
- break;
- case dwarf::DW_RLE_startx_length: {
- PrintRawEntry(OS, *this, AddrSize, DumpOpts);
- uint64_t Start = 0;
- if (auto SA = LookupPooledAddress(Value0))
- Start = SA->Address;
- DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts);
- break;
- }
+ break;
+ case dwarf::DW_RLE_start_end:
+ DWARFAddressRange(Value0, Value1).dump(OS, AddrSize, DumpOpts);
+ break;
+ case dwarf::DW_RLE_startx_length: {
+ PrintRawEntry(OS, *this, AddrSize, DumpOpts);
+ uint64_t Start = 0;
+ if (auto SA = LookupPooledAddress(Value0))
+ Start = SA->Address;
+ DWARFAddressRange(Start, Start + Value1).dump(OS, AddrSize, DumpOpts);
+ break;
+ }
case dwarf::DW_RLE_startx_endx: {
PrintRawEntry(OS, *this, AddrSize, DumpOpts);
uint64_t Start = 0;
@@ -256,8 +256,8 @@ void RangeListEntry::dump(
DWARFAddressRange(Start, End).dump(OS, AddrSize, DumpOpts);
break;
}
- default:
- llvm_unreachable("Unsupported range list encoding");
- }
- OS << "\n";
-}
+ default:
+ llvm_unreachable("Unsupported range list encoding");
+ }
+ OS << "\n";
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp
index 5a55f3a041..f22e8141bd 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -1,274 +1,274 @@
-//===- DWARFDie.cpp -------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatAdapters.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/MathExtras.h"
-#include "llvm/Support/WithColor.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <cinttypes>
-#include <cstdint>
-#include <string>
-#include <utility>
-
-using namespace llvm;
-using namespace dwarf;
-using namespace object;
-
-static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
- OS << " (";
- do {
- uint64_t Shift = countTrailingZeros(Val);
- assert(Shift < 64 && "undefined behavior");
- uint64_t Bit = 1ULL << Shift;
- auto PropName = ApplePropertyString(Bit);
- if (!PropName.empty())
- OS << PropName;
- else
- OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
- if (!(Val ^= Bit))
- break;
- OS << ", ";
- } while (true);
- OS << ")";
-}
-
-static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
- const DWARFAddressRangesVector &Ranges,
- unsigned AddressSize, unsigned Indent,
- const DIDumpOptions &DumpOpts) {
- if (!DumpOpts.ShowAddresses)
- return;
-
- for (const DWARFAddressRange &R : Ranges) {
- OS << '\n';
- OS.indent(Indent);
- R.dump(OS, AddressSize, DumpOpts, &Obj);
- }
-}
-
+//===- DWARFDie.cpp -------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatAdapters.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cinttypes>
+#include <cstdint>
+#include <string>
+#include <utility>
+
+using namespace llvm;
+using namespace dwarf;
+using namespace object;
+
+static void dumpApplePropertyAttribute(raw_ostream &OS, uint64_t Val) {
+ OS << " (";
+ do {
+ uint64_t Shift = countTrailingZeros(Val);
+ assert(Shift < 64 && "undefined behavior");
+ uint64_t Bit = 1ULL << Shift;
+ auto PropName = ApplePropertyString(Bit);
+ if (!PropName.empty())
+ OS << PropName;
+ else
+ OS << format("DW_APPLE_PROPERTY_0x%" PRIx64, Bit);
+ if (!(Val ^= Bit))
+ break;
+ OS << ", ";
+ } while (true);
+ OS << ")";
+}
+
+static void dumpRanges(const DWARFObject &Obj, raw_ostream &OS,
+ const DWARFAddressRangesVector &Ranges,
+ unsigned AddressSize, unsigned Indent,
+ const DIDumpOptions &DumpOpts) {
+ if (!DumpOpts.ShowAddresses)
+ return;
+
+ for (const DWARFAddressRange &R : Ranges) {
+ OS << '\n';
+ OS.indent(Indent);
+ R.dump(OS, AddressSize, DumpOpts, &Obj);
+ }
+}
+
static void dumpLocation(raw_ostream &OS, const DWARFFormValue &FormValue,
- DWARFUnit *U, unsigned Indent,
- DIDumpOptions DumpOpts) {
- DWARFContext &Ctx = U->getContext();
- const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
- if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
- FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) {
- ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
- DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
- Ctx.isLittleEndian(), 0);
- DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
+ DWARFUnit *U, unsigned Indent,
+ DIDumpOptions DumpOpts) {
+ DWARFContext &Ctx = U->getContext();
+ const MCRegisterInfo *MRI = Ctx.getRegisterInfo();
+ if (FormValue.isFormClass(DWARFFormValue::FC_Block) ||
+ FormValue.isFormClass(DWARFFormValue::FC_Exprloc)) {
+ ArrayRef<uint8_t> Expr = *FormValue.getAsBlock();
+ DataExtractor Data(StringRef((const char *)Expr.data(), Expr.size()),
+ Ctx.isLittleEndian(), 0);
+ DWARFExpression(Data, U->getAddressByteSize(), U->getFormParams().Format)
.print(OS, DumpOpts, MRI, U);
- return;
- }
-
- if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
- uint64_t Offset = *FormValue.getAsSectionOffset();
-
- if (FormValue.getForm() == DW_FORM_loclistx) {
- FormValue.dump(OS, DumpOpts);
-
- if (auto LoclistOffset = U->getLoclistOffset(Offset))
- Offset = *LoclistOffset;
- else
- return;
- }
- U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
- MRI, Ctx.getDWARFObj(), U, DumpOpts,
- Indent);
- return;
- }
-
- FormValue.dump(OS, DumpOpts);
-}
-
-/// Dump the name encoded in the type tag.
-static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) {
- StringRef TagStr = TagString(T);
- if (!TagStr.startswith("DW_TAG_") || !TagStr.endswith("_type"))
- return;
- OS << TagStr.substr(7, TagStr.size() - 12) << " ";
-}
-
-static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) {
- for (const DWARFDie &C : D.children())
- if (C.getTag() == DW_TAG_subrange_type) {
- Optional<uint64_t> LB;
- Optional<uint64_t> Count;
- Optional<uint64_t> UB;
- Optional<unsigned> DefaultLB;
- if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
- LB = L->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
- Count = CountV->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
- UB = UpperV->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> LV =
- D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
- if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
- if ((DefaultLB =
- LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
- if (LB && *LB == *DefaultLB)
- LB = None;
- if (!LB && !Count && !UB)
- OS << "[]";
- else if (!LB && (Count || UB) && DefaultLB)
- OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
- else {
- OS << "[[";
- if (LB)
- OS << *LB;
- else
- OS << '?';
- OS << ", ";
- if (Count)
- if (LB)
- OS << *LB + *Count;
- else
- OS << "? + " << *Count;
- else if (UB)
- OS << *UB + 1;
- else
- OS << '?';
- OS << ")]";
- }
- }
-}
-
-/// Recursively dump the DIE type name when applicable.
-static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) {
- if (!D.isValid())
- return;
-
- if (const char *Name = D.getName(DINameKind::LinkageName)) {
- OS << Name;
- return;
- }
-
- // FIXME: We should have pretty printers per language. Currently we print
- // everything as if it was C++ and fall back to the TAG type name.
- const dwarf::Tag T = D.getTag();
- switch (T) {
- case DW_TAG_array_type:
- case DW_TAG_pointer_type:
- case DW_TAG_ptr_to_member_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_subroutine_type:
- break;
- default:
- dumpTypeTagName(OS, T);
- }
-
- // Follow the DW_AT_type if possible.
- DWARFDie TypeDie = D.getAttributeValueAsReferencedDie(DW_AT_type);
- dumpTypeName(OS, TypeDie);
-
- switch (T) {
- case DW_TAG_subroutine_type: {
- if (!TypeDie)
- OS << "void";
- OS << '(';
- bool First = true;
- for (const DWARFDie &C : D.children()) {
- if (C.getTag() == DW_TAG_formal_parameter) {
- if (!First)
- OS << ", ";
- First = false;
- dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type));
- }
- }
- OS << ')';
- break;
- }
- case DW_TAG_array_type: {
- dumpArrayType(OS, D);
- break;
- }
- case DW_TAG_pointer_type:
- OS << '*';
- break;
- case DW_TAG_ptr_to_member_type:
- if (DWARFDie Cont =
- D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
- dumpTypeName(OS << ' ', Cont);
- OS << "::";
- }
- OS << '*';
- break;
- case DW_TAG_reference_type:
- OS << '&';
- break;
- case DW_TAG_rvalue_reference_type:
- OS << "&&";
- break;
- default:
- break;
- }
-}
-
-static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
+ return;
+ }
+
+ if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
+ uint64_t Offset = *FormValue.getAsSectionOffset();
+
+ if (FormValue.getForm() == DW_FORM_loclistx) {
+ FormValue.dump(OS, DumpOpts);
+
+ if (auto LoclistOffset = U->getLoclistOffset(Offset))
+ Offset = *LoclistOffset;
+ else
+ return;
+ }
+ U->getLocationTable().dumpLocationList(&Offset, OS, U->getBaseAddress(),
+ MRI, Ctx.getDWARFObj(), U, DumpOpts,
+ Indent);
+ return;
+ }
+
+ FormValue.dump(OS, DumpOpts);
+}
+
+/// Dump the name encoded in the type tag.
+static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) {
+ StringRef TagStr = TagString(T);
+ if (!TagStr.startswith("DW_TAG_") || !TagStr.endswith("_type"))
+ return;
+ OS << TagStr.substr(7, TagStr.size() - 12) << " ";
+}
+
+static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) {
+ for (const DWARFDie &C : D.children())
+ if (C.getTag() == DW_TAG_subrange_type) {
+ Optional<uint64_t> LB;
+ Optional<uint64_t> Count;
+ Optional<uint64_t> UB;
+ Optional<unsigned> DefaultLB;
+ if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
+ LB = L->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
+ Count = CountV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
+ UB = UpperV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> LV =
+ D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
+ if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
+ if ((DefaultLB =
+ LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
+ if (LB && *LB == *DefaultLB)
+ LB = None;
+ if (!LB && !Count && !UB)
+ OS << "[]";
+ else if (!LB && (Count || UB) && DefaultLB)
+ OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
+ else {
+ OS << "[[";
+ if (LB)
+ OS << *LB;
+ else
+ OS << '?';
+ OS << ", ";
+ if (Count)
+ if (LB)
+ OS << *LB + *Count;
+ else
+ OS << "? + " << *Count;
+ else if (UB)
+ OS << *UB + 1;
+ else
+ OS << '?';
+ OS << ")]";
+ }
+ }
+}
+
+/// Recursively dump the DIE type name when applicable.
+static void dumpTypeName(raw_ostream &OS, const DWARFDie &D) {
+ if (!D.isValid())
+ return;
+
+ if (const char *Name = D.getName(DINameKind::LinkageName)) {
+ OS << Name;
+ return;
+ }
+
+ // FIXME: We should have pretty printers per language. Currently we print
+ // everything as if it was C++ and fall back to the TAG type name.
+ const dwarf::Tag T = D.getTag();
+ switch (T) {
+ case DW_TAG_array_type:
+ case DW_TAG_pointer_type:
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_subroutine_type:
+ break;
+ default:
+ dumpTypeTagName(OS, T);
+ }
+
+ // Follow the DW_AT_type if possible.
+ DWARFDie TypeDie = D.getAttributeValueAsReferencedDie(DW_AT_type);
+ dumpTypeName(OS, TypeDie);
+
+ switch (T) {
+ case DW_TAG_subroutine_type: {
+ if (!TypeDie)
+ OS << "void";
+ OS << '(';
+ bool First = true;
+ for (const DWARFDie &C : D.children()) {
+ if (C.getTag() == DW_TAG_formal_parameter) {
+ if (!First)
+ OS << ", ";
+ First = false;
+ dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type));
+ }
+ }
+ OS << ')';
+ break;
+ }
+ case DW_TAG_array_type: {
+ dumpArrayType(OS, D);
+ break;
+ }
+ case DW_TAG_pointer_type:
+ OS << '*';
+ break;
+ case DW_TAG_ptr_to_member_type:
+ if (DWARFDie Cont =
+ D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
+ dumpTypeName(OS << ' ', Cont);
+ OS << "::";
+ }
+ OS << '*';
+ break;
+ case DW_TAG_reference_type:
+ OS << '&';
+ break;
+ case DW_TAG_rvalue_reference_type:
+ OS << "&&";
+ break;
+ default:
+ break;
+ }
+}
+
+static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
const DWARFAttribute &AttrValue, unsigned Indent,
- DIDumpOptions DumpOpts) {
- if (!Die.isValid())
- return;
- const char BaseIndent[] = " ";
- OS << BaseIndent;
- OS.indent(Indent + 2);
+ DIDumpOptions DumpOpts) {
+ if (!Die.isValid())
+ return;
+ const char BaseIndent[] = " ";
+ OS << BaseIndent;
+ OS.indent(Indent + 2);
dwarf::Attribute Attr = AttrValue.Attr;
- WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr);
-
+ WithColor(OS, HighlightColor::Attribute) << formatv("{0}", Attr);
+
dwarf::Form Form = AttrValue.Value.getForm();
- if (DumpOpts.Verbose || DumpOpts.ShowForm)
- OS << formatv(" [{0}]", Form);
-
- DWARFUnit *U = Die.getDwarfUnit();
+ if (DumpOpts.Verbose || DumpOpts.ShowForm)
+ OS << formatv(" [{0}]", Form);
+
+ DWARFUnit *U = Die.getDwarfUnit();
const DWARFFormValue &FormValue = AttrValue.Value;
-
- OS << "\t(";
-
- StringRef Name;
- std::string File;
- auto Color = HighlightColor::Enumerator;
- if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
- Color = HighlightColor::String;
- if (const auto *LT = U->getContext().getLineTableForUnit(U))
- if (LT->getFileNameByIndex(
- FormValue.getAsUnsignedConstant().getValue(),
- U->getCompilationDir(),
- DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
- File = '"' + File + '"';
- Name = File;
- }
- } 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 << "\t(";
+
+ StringRef Name;
+ std::string File;
+ auto Color = HighlightColor::Enumerator;
+ if (Attr == DW_AT_decl_file || Attr == DW_AT_call_file) {
+ Color = HighlightColor::String;
+ if (const auto *LT = U->getContext().getLineTableForUnit(U))
+ if (LT->getFileNameByIndex(
+ FormValue.getAsUnsignedConstant().getValue(),
+ U->getCompilationDir(),
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, File)) {
+ File = '"' + File + '"';
+ Name = File;
+ }
+ } 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();
else if (Attr == DW_AT_low_pc &&
(FormValue.getAsAddress() ==
dwarf::computeTombstoneAddress(U->getAddressByteSize()))) {
@@ -281,294 +281,294 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
OS << ')';
} else if (Attr == DW_AT_high_pc && !DumpOpts.ShowForm && !DumpOpts.Verbose &&
FormValue.getAsUnsignedConstant()) {
- if (DumpOpts.ShowAddresses) {
- // Print the actual address rather than the offset.
- uint64_t LowPC, HighPC, Index;
- if (Die.getLowAndHighPC(LowPC, HighPC, Index))
+ if (DumpOpts.ShowAddresses) {
+ // Print the actual address rather than the offset.
+ uint64_t LowPC, HighPC, Index;
+ if (Die.getLowAndHighPC(LowPC, HighPC, Index))
DWARFFormValue::dumpAddress(OS, U->getAddressByteSize(), HighPC);
- else
- FormValue.dump(OS, DumpOpts);
- }
- } else if (Form == dwarf::Form::DW_FORM_exprloc ||
- DWARFAttribute::mayHaveLocationDescription(Attr))
- dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
- else
- FormValue.dump(OS, DumpOpts);
-
- std::string Space = DumpOpts.ShowAddresses ? " " : "";
-
- // We have dumped the attribute raw value. For some attributes
- // having both the raw value and the pretty-printed value is
- // interesting. These attributes are handled below.
- if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
- if (const char *Name =
- Die.getAttributeValueAsReferencedDie(FormValue).getName(
- DINameKind::LinkageName))
- OS << Space << "\"" << Name << '\"';
- } else if (Attr == DW_AT_type) {
- OS << Space << "\"";
- dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(FormValue));
- OS << '"';
- } else if (Attr == DW_AT_APPLE_property_attribute) {
- 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 (auto RangeListOffset =
- U->getRnglistOffset(*FormValue.getAsSectionOffset())) {
- DWARFFormValue FV = DWARFFormValue::createFromUValue(
- dwarf::DW_FORM_sec_offset, *RangeListOffset);
- FV.dump(OS, DumpOpts);
- }
- if (auto RangesOrError = Die.getAddressRanges())
- dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
- sizeof(BaseIndent) + Indent + 4, DumpOpts);
- else
- DumpOpts.RecoverableErrorHandler(createStringError(
- errc::invalid_argument, "decoding address ranges: %s",
- toString(RangesOrError.takeError()).c_str()));
- }
-
- OS << ")\n";
-}
-
-bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; }
-
-bool DWARFDie::isSubroutineDIE() const {
- auto Tag = getTag();
- return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
-}
-
-Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const {
- if (!isValid())
- return None;
- auto AbbrevDecl = getAbbreviationDeclarationPtr();
- if (AbbrevDecl)
- return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U);
- return None;
-}
-
-Optional<DWARFFormValue>
-DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
- if (!isValid())
- return None;
- auto AbbrevDecl = getAbbreviationDeclarationPtr();
- if (AbbrevDecl) {
- for (auto Attr : Attrs) {
- if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
- return Value;
- }
- }
- return None;
-}
-
-Optional<DWARFFormValue>
-DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
- SmallVector<DWARFDie, 3> Worklist;
- Worklist.push_back(*this);
-
- // Keep track if DIEs already seen to prevent infinite recursion.
- // Empirically we rarely see a depth of more than 3 when dealing with valid
- // 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()) {
+ else
+ FormValue.dump(OS, DumpOpts);
+ }
+ } else if (Form == dwarf::Form::DW_FORM_exprloc ||
+ DWARFAttribute::mayHaveLocationDescription(Attr))
+ dumpLocation(OS, FormValue, U, sizeof(BaseIndent) + Indent + 4, DumpOpts);
+ else
+ FormValue.dump(OS, DumpOpts);
+
+ std::string Space = DumpOpts.ShowAddresses ? " " : "";
+
+ // We have dumped the attribute raw value. For some attributes
+ // having both the raw value and the pretty-printed value is
+ // interesting. These attributes are handled below.
+ if (Attr == DW_AT_specification || Attr == DW_AT_abstract_origin) {
+ if (const char *Name =
+ Die.getAttributeValueAsReferencedDie(FormValue).getName(
+ DINameKind::LinkageName))
+ OS << Space << "\"" << Name << '\"';
+ } else if (Attr == DW_AT_type) {
+ OS << Space << "\"";
+ dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(FormValue));
+ OS << '"';
+ } else if (Attr == DW_AT_APPLE_property_attribute) {
+ 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 (auto RangeListOffset =
+ U->getRnglistOffset(*FormValue.getAsSectionOffset())) {
+ DWARFFormValue FV = DWARFFormValue::createFromUValue(
+ dwarf::DW_FORM_sec_offset, *RangeListOffset);
+ FV.dump(OS, DumpOpts);
+ }
+ if (auto RangesOrError = Die.getAddressRanges())
+ dumpRanges(Obj, OS, RangesOrError.get(), U->getAddressByteSize(),
+ sizeof(BaseIndent) + Indent + 4, DumpOpts);
+ else
+ DumpOpts.RecoverableErrorHandler(createStringError(
+ errc::invalid_argument, "decoding address ranges: %s",
+ toString(RangesOrError.takeError()).c_str()));
+ }
+
+ OS << ")\n";
+}
+
+bool DWARFDie::isSubprogramDIE() const { return getTag() == DW_TAG_subprogram; }
+
+bool DWARFDie::isSubroutineDIE() const {
+ auto Tag = getTag();
+ return Tag == DW_TAG_subprogram || Tag == DW_TAG_inlined_subroutine;
+}
+
+Optional<DWARFFormValue> DWARFDie::find(dwarf::Attribute Attr) const {
+ if (!isValid())
+ return None;
+ auto AbbrevDecl = getAbbreviationDeclarationPtr();
+ if (AbbrevDecl)
+ return AbbrevDecl->getAttributeValue(getOffset(), Attr, *U);
+ return None;
+}
+
+Optional<DWARFFormValue>
+DWARFDie::find(ArrayRef<dwarf::Attribute> Attrs) const {
+ if (!isValid())
+ return None;
+ auto AbbrevDecl = getAbbreviationDeclarationPtr();
+ if (AbbrevDecl) {
+ for (auto Attr : Attrs) {
+ if (auto Value = AbbrevDecl->getAttributeValue(getOffset(), Attr, *U))
+ return Value;
+ }
+ }
+ return None;
+}
+
+Optional<DWARFFormValue>
+DWARFDie::findRecursively(ArrayRef<dwarf::Attribute> Attrs) const {
+ SmallVector<DWARFDie, 3> Worklist;
+ Worklist.push_back(*this);
+
+ // Keep track if DIEs already seen to prevent infinite recursion.
+ // Empirically we rarely see a depth of more than 3 when dealing with valid
+ // 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.pop_back_val();
-
- if (!Die.isValid())
- continue;
-
- if (auto Value = Die.find(Attrs))
- return Value;
-
- if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
- if (Seen.insert(D).second)
- Worklist.push_back(D);
-
- if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
- if (Seen.insert(D).second)
- Worklist.push_back(D);
- }
-
- return None;
-}
-
-DWARFDie
-DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
- if (Optional<DWARFFormValue> F = find(Attr))
- return getAttributeValueAsReferencedDie(*F);
- return DWARFDie();
-}
-
-DWARFDie
-DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
- 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();
-}
-
-Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const {
- return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
-}
-
-Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
- return toSectionOffset(find(DW_AT_loclists_base));
-}
-
-Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
+
+ if (!Die.isValid())
+ continue;
+
+ if (auto Value = Die.find(Attrs))
+ return Value;
+
+ if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_abstract_origin))
+ if (Seen.insert(D).second)
+ Worklist.push_back(D);
+
+ if (auto D = Die.getAttributeValueAsReferencedDie(DW_AT_specification))
+ if (Seen.insert(D).second)
+ Worklist.push_back(D);
+ }
+
+ return None;
+}
+
+DWARFDie
+DWARFDie::getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const {
+ if (Optional<DWARFFormValue> F = find(Attr))
+ return getAttributeValueAsReferencedDie(*F);
+ return DWARFDie();
+}
+
+DWARFDie
+DWARFDie::getAttributeValueAsReferencedDie(const DWARFFormValue &V) const {
+ 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();
+}
+
+Optional<uint64_t> DWARFDie::getRangesBaseAttribute() const {
+ return toSectionOffset(find({DW_AT_rnglists_base, DW_AT_GNU_ranges_base}));
+}
+
+Optional<uint64_t> DWARFDie::getLocBaseAttribute() const {
+ return toSectionOffset(find(DW_AT_loclists_base));
+}
+
+Optional<uint64_t> DWARFDie::getHighPC(uint64_t LowPC) const {
uint64_t Tombstone = dwarf::computeTombstoneAddress(U->getAddressByteSize());
if (LowPC == Tombstone)
return None;
- if (auto FormValue = find(DW_AT_high_pc)) {
- if (auto Address = FormValue->getAsAddress()) {
- // High PC is an address.
- return Address;
- }
- if (auto Offset = FormValue->getAsUnsignedConstant()) {
- // High PC is an offset from LowPC.
- return LowPC + *Offset;
- }
- }
- return None;
-}
-
-bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
- uint64_t &SectionIndex) const {
- auto F = find(DW_AT_low_pc);
- auto LowPcAddr = toSectionedAddress(F);
- if (!LowPcAddr)
- return false;
- if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) {
- LowPC = LowPcAddr->Address;
- HighPC = *HighPcAddr;
- SectionIndex = LowPcAddr->SectionIndex;
- return true;
- }
- return false;
-}
-
-Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const {
- if (isNULL())
- return DWARFAddressRangesVector();
- // Single range specified by low/high PC.
- uint64_t LowPC, HighPC, Index;
- if (getLowAndHighPC(LowPC, HighPC, Index))
- return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
-
- Optional<DWARFFormValue> Value = find(DW_AT_ranges);
- if (Value) {
- if (Value->getForm() == DW_FORM_rnglistx)
- return U->findRnglistFromIndex(*Value->getAsSectionOffset());
- return U->findRnglistFromOffset(*Value->getAsSectionOffset());
- }
- return DWARFAddressRangesVector();
-}
-
-void DWARFDie::collectChildrenAddressRanges(
- DWARFAddressRangesVector &Ranges) const {
- if (isNULL())
- return;
- if (isSubprogramDIE()) {
- if (auto DIERangesOrError = getAddressRanges())
+ if (auto FormValue = find(DW_AT_high_pc)) {
+ if (auto Address = FormValue->getAsAddress()) {
+ // High PC is an address.
+ return Address;
+ }
+ if (auto Offset = FormValue->getAsUnsignedConstant()) {
+ // High PC is an offset from LowPC.
+ return LowPC + *Offset;
+ }
+ }
+ return None;
+}
+
+bool DWARFDie::getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
+ uint64_t &SectionIndex) const {
+ auto F = find(DW_AT_low_pc);
+ auto LowPcAddr = toSectionedAddress(F);
+ if (!LowPcAddr)
+ return false;
+ if (auto HighPcAddr = getHighPC(LowPcAddr->Address)) {
+ LowPC = LowPcAddr->Address;
+ HighPC = *HighPcAddr;
+ SectionIndex = LowPcAddr->SectionIndex;
+ return true;
+ }
+ return false;
+}
+
+Expected<DWARFAddressRangesVector> DWARFDie::getAddressRanges() const {
+ if (isNULL())
+ return DWARFAddressRangesVector();
+ // Single range specified by low/high PC.
+ uint64_t LowPC, HighPC, Index;
+ if (getLowAndHighPC(LowPC, HighPC, Index))
+ return DWARFAddressRangesVector{{LowPC, HighPC, Index}};
+
+ Optional<DWARFFormValue> Value = find(DW_AT_ranges);
+ if (Value) {
+ if (Value->getForm() == DW_FORM_rnglistx)
+ return U->findRnglistFromIndex(*Value->getAsSectionOffset());
+ return U->findRnglistFromOffset(*Value->getAsSectionOffset());
+ }
+ return DWARFAddressRangesVector();
+}
+
+void DWARFDie::collectChildrenAddressRanges(
+ DWARFAddressRangesVector &Ranges) const {
+ if (isNULL())
+ return;
+ if (isSubprogramDIE()) {
+ if (auto DIERangesOrError = getAddressRanges())
llvm::append_range(Ranges, DIERangesOrError.get());
- else
- llvm::consumeError(DIERangesOrError.takeError());
- }
-
- for (auto Child : children())
- Child.collectChildrenAddressRanges(Ranges);
-}
-
-bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
- auto RangesOrError = getAddressRanges();
- if (!RangesOrError) {
- llvm::consumeError(RangesOrError.takeError());
- return false;
- }
-
- for (const auto &R : RangesOrError.get())
- if (R.LowPC <= Address && Address < R.HighPC)
- return true;
- return false;
-}
-
-Expected<DWARFLocationExpressionsVector>
-DWARFDie::getLocations(dwarf::Attribute Attr) const {
- Optional<DWARFFormValue> Location = find(Attr);
- if (!Location)
- return createStringError(inconvertibleErrorCode(), "No %s",
- dwarf::AttributeString(Attr).data());
-
- if (Optional<uint64_t> Off = Location->getAsSectionOffset()) {
- uint64_t Offset = *Off;
-
- if (Location->getForm() == DW_FORM_loclistx) {
- if (auto LoclistOffset = U->getLoclistOffset(Offset))
- Offset = *LoclistOffset;
- else
- return createStringError(inconvertibleErrorCode(),
- "Loclist table not found");
- }
- return U->findLoclistFromOffset(Offset);
- }
-
- if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
- return DWARFLocationExpressionsVector{
- DWARFLocationExpression{None, to_vector<4>(*Expr)}};
- }
-
- return createStringError(
- inconvertibleErrorCode(), "Unsupported %s encoding: %s",
- dwarf::AttributeString(Attr).data(),
- dwarf::FormEncodingString(Location->getForm()).data());
-}
-
-const char *DWARFDie::getSubroutineName(DINameKind Kind) const {
- if (!isSubroutineDIE())
- return nullptr;
- return getName(Kind);
-}
-
-const char *DWARFDie::getName(DINameKind Kind) const {
- if (!isValid() || Kind == DINameKind::None)
- return nullptr;
- // Try to get mangled name only if it was asked for.
- if (Kind == DINameKind::LinkageName) {
- if (auto Name = getLinkageName())
- return Name;
- }
- return getShortName();
-}
-
-const char *DWARFDie::getShortName() const {
- if (!isValid())
- return nullptr;
-
- return dwarf::toString(findRecursively(dwarf::DW_AT_name), nullptr);
-}
-
-const char *DWARFDie::getLinkageName() const {
- if (!isValid())
- return nullptr;
-
- return dwarf::toString(findRecursively({dwarf::DW_AT_MIPS_linkage_name,
- dwarf::DW_AT_linkage_name}),
- nullptr);
-}
-
-uint64_t DWARFDie::getDeclLine() const {
- return toUnsigned(findRecursively(DW_AT_decl_line), 0);
-}
-
+ else
+ llvm::consumeError(DIERangesOrError.takeError());
+ }
+
+ for (auto Child : children())
+ Child.collectChildrenAddressRanges(Ranges);
+}
+
+bool DWARFDie::addressRangeContainsAddress(const uint64_t Address) const {
+ auto RangesOrError = getAddressRanges();
+ if (!RangesOrError) {
+ llvm::consumeError(RangesOrError.takeError());
+ return false;
+ }
+
+ for (const auto &R : RangesOrError.get())
+ if (R.LowPC <= Address && Address < R.HighPC)
+ return true;
+ return false;
+}
+
+Expected<DWARFLocationExpressionsVector>
+DWARFDie::getLocations(dwarf::Attribute Attr) const {
+ Optional<DWARFFormValue> Location = find(Attr);
+ if (!Location)
+ return createStringError(inconvertibleErrorCode(), "No %s",
+ dwarf::AttributeString(Attr).data());
+
+ if (Optional<uint64_t> Off = Location->getAsSectionOffset()) {
+ uint64_t Offset = *Off;
+
+ if (Location->getForm() == DW_FORM_loclistx) {
+ if (auto LoclistOffset = U->getLoclistOffset(Offset))
+ Offset = *LoclistOffset;
+ else
+ return createStringError(inconvertibleErrorCode(),
+ "Loclist table not found");
+ }
+ return U->findLoclistFromOffset(Offset);
+ }
+
+ if (Optional<ArrayRef<uint8_t>> Expr = Location->getAsBlock()) {
+ return DWARFLocationExpressionsVector{
+ DWARFLocationExpression{None, to_vector<4>(*Expr)}};
+ }
+
+ return createStringError(
+ inconvertibleErrorCode(), "Unsupported %s encoding: %s",
+ dwarf::AttributeString(Attr).data(),
+ dwarf::FormEncodingString(Location->getForm()).data());
+}
+
+const char *DWARFDie::getSubroutineName(DINameKind Kind) const {
+ if (!isSubroutineDIE())
+ return nullptr;
+ return getName(Kind);
+}
+
+const char *DWARFDie::getName(DINameKind Kind) const {
+ if (!isValid() || Kind == DINameKind::None)
+ return nullptr;
+ // Try to get mangled name only if it was asked for.
+ if (Kind == DINameKind::LinkageName) {
+ if (auto Name = getLinkageName())
+ return Name;
+ }
+ return getShortName();
+}
+
+const char *DWARFDie::getShortName() const {
+ if (!isValid())
+ return nullptr;
+
+ return dwarf::toString(findRecursively(dwarf::DW_AT_name), nullptr);
+}
+
+const char *DWARFDie::getLinkageName() const {
+ if (!isValid())
+ return nullptr;
+
+ return dwarf::toString(findRecursively({dwarf::DW_AT_MIPS_linkage_name,
+ dwarf::DW_AT_linkage_name}),
+ nullptr);
+}
+
+uint64_t DWARFDie::getDeclLine() const {
+ return toUnsigned(findRecursively(DW_AT_decl_line), 0);
+}
+
std::string
DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const {
std::string FileName;
@@ -580,142 +580,142 @@ DWARFDie::getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const {
return FileName;
}
-void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
- uint32_t &CallColumn,
- uint32_t &CallDiscriminator) const {
- CallFile = toUnsigned(find(DW_AT_call_file), 0);
- CallLine = toUnsigned(find(DW_AT_call_line), 0);
- CallColumn = toUnsigned(find(DW_AT_call_column), 0);
- CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
-}
-
-/// 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, unsigned Depth = 0) {
- if (!Die)
- return Indent;
- 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;
-}
-
-void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
- DIDumpOptions DumpOpts) const {
- if (!isValid())
- return;
- DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
- const uint64_t Offset = getOffset();
- uint64_t offset = Offset;
- if (DumpOpts.ShowParents) {
- DIDumpOptions ParentDumpOpts = DumpOpts;
- ParentDumpOpts.ShowParents = false;
- ParentDumpOpts.ShowChildren = false;
- Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts);
- }
-
- if (debug_info_data.isValidOffset(offset)) {
- uint32_t abbrCode = debug_info_data.getULEB128(&offset);
- if (DumpOpts.ShowAddresses)
- WithColor(OS, HighlightColor::Address).get()
- << format("\n0x%8.8" PRIx64 ": ", Offset);
-
- if (abbrCode) {
- auto AbbrevDecl = getAbbreviationDeclarationPtr();
- if (AbbrevDecl) {
- WithColor(OS, HighlightColor::Tag).get().indent(Indent)
- << formatv("{0}", getTag());
- if (DumpOpts.Verbose)
- OS << format(" [%u] %c", abbrCode,
- AbbrevDecl->hasChildren() ? '*' : ' ');
- OS << '\n';
-
- // Dump all data in the DIE for the attributes.
+void DWARFDie::getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
+ uint32_t &CallColumn,
+ uint32_t &CallDiscriminator) const {
+ CallFile = toUnsigned(find(DW_AT_call_file), 0);
+ CallLine = toUnsigned(find(DW_AT_call_line), 0);
+ CallColumn = toUnsigned(find(DW_AT_call_column), 0);
+ CallDiscriminator = toUnsigned(find(DW_AT_GNU_discriminator), 0);
+}
+
+/// 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, unsigned Depth = 0) {
+ if (!Die)
+ return Indent;
+ 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;
+}
+
+void DWARFDie::dump(raw_ostream &OS, unsigned Indent,
+ DIDumpOptions DumpOpts) const {
+ if (!isValid())
+ return;
+ DWARFDataExtractor debug_info_data = U->getDebugInfoExtractor();
+ const uint64_t Offset = getOffset();
+ uint64_t offset = Offset;
+ if (DumpOpts.ShowParents) {
+ DIDumpOptions ParentDumpOpts = DumpOpts;
+ ParentDumpOpts.ShowParents = false;
+ ParentDumpOpts.ShowChildren = false;
+ Indent = dumpParentChain(getParent(), OS, Indent, ParentDumpOpts);
+ }
+
+ if (debug_info_data.isValidOffset(offset)) {
+ uint32_t abbrCode = debug_info_data.getULEB128(&offset);
+ if (DumpOpts.ShowAddresses)
+ WithColor(OS, HighlightColor::Address).get()
+ << format("\n0x%8.8" PRIx64 ": ", Offset);
+
+ if (abbrCode) {
+ auto AbbrevDecl = getAbbreviationDeclarationPtr();
+ if (AbbrevDecl) {
+ WithColor(OS, HighlightColor::Tag).get().indent(Indent)
+ << formatv("{0}", getTag());
+ if (DumpOpts.Verbose)
+ OS << format(" [%u] %c", abbrCode,
+ AbbrevDecl->hasChildren() ? '*' : ' ');
+ OS << '\n';
+
+ // Dump all data in the DIE for the attributes.
for (const DWARFAttribute &AttrValue : attributes())
dumpAttribute(OS, *this, AttrValue, Indent, DumpOpts);
-
- DWARFDie child = getFirstChild();
- if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) {
- DumpOpts.ChildRecurseDepth--;
- DIDumpOptions ChildDumpOpts = DumpOpts;
- ChildDumpOpts.ShowParents = false;
- while (child) {
- child.dump(OS, Indent + 2, ChildDumpOpts);
- child = child.getSibling();
- }
- }
- } else {
- OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
- << abbrCode << '\n';
- }
- } else {
- OS.indent(Indent) << "NULL\n";
- }
- }
-}
-
-LLVM_DUMP_METHOD void DWARFDie::dump() const { dump(llvm::errs(), 0); }
-
-DWARFDie DWARFDie::getParent() const {
- if (isValid())
- return U->getParent(Die);
- return DWARFDie();
-}
-
-DWARFDie DWARFDie::getSibling() const {
- if (isValid())
- return U->getSibling(Die);
- return DWARFDie();
-}
-
-DWARFDie DWARFDie::getPreviousSibling() const {
- if (isValid())
- return U->getPreviousSibling(Die);
- return DWARFDie();
-}
-
-DWARFDie DWARFDie::getFirstChild() const {
- if (isValid())
- return U->getFirstChild(Die);
- return DWARFDie();
-}
-
-DWARFDie DWARFDie::getLastChild() const {
- if (isValid())
- return U->getLastChild(Die);
- return DWARFDie();
-}
-
-iterator_range<DWARFDie::attribute_iterator> DWARFDie::attributes() const {
- return make_range(attribute_iterator(*this, false),
- attribute_iterator(*this, true));
-}
-
-DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End)
- : Die(D), Index(0) {
- auto AbbrDecl = Die.getAbbreviationDeclarationPtr();
- assert(AbbrDecl && "Must have abbreviation declaration");
- if (End) {
- // This is the end iterator so we set the index to the attribute count.
- Index = AbbrDecl->getNumAttributes();
- } else {
- // This is the begin iterator so we extract the value for this->Index.
- AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize();
- updateForIndex(*AbbrDecl, 0);
- }
-}
-
-void DWARFDie::attribute_iterator::updateForIndex(
- const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) {
- Index = I;
- // AbbrDecl must be valid before calling this function.
- auto NumAttrs = AbbrDecl.getNumAttributes();
- if (Index < NumAttrs) {
- AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
- // Add the previous byte size of any previous attribute value.
- AttrValue.Offset += AttrValue.ByteSize;
- uint64_t ParseOffset = AttrValue.Offset;
+
+ DWARFDie child = getFirstChild();
+ if (DumpOpts.ShowChildren && DumpOpts.ChildRecurseDepth > 0 && child) {
+ DumpOpts.ChildRecurseDepth--;
+ DIDumpOptions ChildDumpOpts = DumpOpts;
+ ChildDumpOpts.ShowParents = false;
+ while (child) {
+ child.dump(OS, Indent + 2, ChildDumpOpts);
+ child = child.getSibling();
+ }
+ }
+ } else {
+ OS << "Abbreviation code not found in 'debug_abbrev' class for code: "
+ << abbrCode << '\n';
+ }
+ } else {
+ OS.indent(Indent) << "NULL\n";
+ }
+ }
+}
+
+LLVM_DUMP_METHOD void DWARFDie::dump() const { dump(llvm::errs(), 0); }
+
+DWARFDie DWARFDie::getParent() const {
+ if (isValid())
+ return U->getParent(Die);
+ return DWARFDie();
+}
+
+DWARFDie DWARFDie::getSibling() const {
+ if (isValid())
+ return U->getSibling(Die);
+ return DWARFDie();
+}
+
+DWARFDie DWARFDie::getPreviousSibling() const {
+ if (isValid())
+ return U->getPreviousSibling(Die);
+ return DWARFDie();
+}
+
+DWARFDie DWARFDie::getFirstChild() const {
+ if (isValid())
+ return U->getFirstChild(Die);
+ return DWARFDie();
+}
+
+DWARFDie DWARFDie::getLastChild() const {
+ if (isValid())
+ return U->getLastChild(Die);
+ return DWARFDie();
+}
+
+iterator_range<DWARFDie::attribute_iterator> DWARFDie::attributes() const {
+ return make_range(attribute_iterator(*this, false),
+ attribute_iterator(*this, true));
+}
+
+DWARFDie::attribute_iterator::attribute_iterator(DWARFDie D, bool End)
+ : Die(D), Index(0) {
+ auto AbbrDecl = Die.getAbbreviationDeclarationPtr();
+ assert(AbbrDecl && "Must have abbreviation declaration");
+ if (End) {
+ // This is the end iterator so we set the index to the attribute count.
+ Index = AbbrDecl->getNumAttributes();
+ } else {
+ // This is the begin iterator so we extract the value for this->Index.
+ AttrValue.Offset = D.getOffset() + AbbrDecl->getCodeByteSize();
+ updateForIndex(*AbbrDecl, 0);
+ }
+}
+
+void DWARFDie::attribute_iterator::updateForIndex(
+ const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I) {
+ Index = I;
+ // AbbrDecl must be valid before calling this function.
+ auto NumAttrs = AbbrDecl.getNumAttributes();
+ if (Index < NumAttrs) {
+ AttrValue.Attr = AbbrDecl.getAttrByIndex(Index);
+ // Add the previous byte size of any previous attribute value.
+ AttrValue.Offset += AttrValue.ByteSize;
+ uint64_t ParseOffset = AttrValue.Offset;
if (AbbrDecl.getAttrIsImplicitConstByIndex(Index))
AttrValue.Value = DWARFFormValue::createFromSValue(
AbbrDecl.getFormByIndex(Index),
@@ -726,52 +726,52 @@ void DWARFDie::attribute_iterator::updateForIndex(
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 = {};
- }
-}
-
-DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() {
- if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr())
- 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:
- case DW_AT_GNU_call_site_target:
- return true;
- default:
- return false;
- }
-}
+ AttrValue.ByteSize = ParseOffset - AttrValue.Offset;
+ } else {
+ assert(Index == NumAttrs && "Indexes should be [0, NumAttrs) only");
+ AttrValue = {};
+ }
+}
+
+DWARFDie::attribute_iterator &DWARFDie::attribute_iterator::operator++() {
+ if (auto AbbrDecl = Die.getAbbreviationDeclarationPtr())
+ 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:
+ case DW_AT_GNU_call_site_target:
+ return true;
+ default:
+ return false;
+ }
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp
index 811716111b..7a109bc290 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFExpression.cpp
@@ -1,504 +1,504 @@
-//===-- DWARFExpression.cpp -----------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/Support/Format.h"
-#include <cassert>
-#include <cstdint>
-#include <vector>
-
-using namespace llvm;
-using namespace dwarf;
-
-namespace llvm {
-
-typedef std::vector<DWARFExpression::Operation::Description> DescVector;
-
-static DescVector getDescriptions() {
- DescVector Descriptions;
- typedef DWARFExpression::Operation Op;
- typedef Op::Description Desc;
-
- Descriptions.resize(0xff);
- Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
- Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
- Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
- Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
- Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
- Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
- Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
- Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
- Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
- Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
- Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
- Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
- for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
- Descriptions[LA] = Desc(Op::Dwarf2);
- for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
- Descriptions[LA] = Desc(Op::Dwarf2);
- for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
- Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
- Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
- Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
- Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
- Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
- Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
- Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
- Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
- Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
- Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
- Descriptions[DW_OP_implicit_value] =
- Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
- Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
- Descriptions[DW_OP_WASM_location] =
- Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg);
- Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
- 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);
- Descriptions[DW_OP_regval_type] =
- Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef);
-
- return Descriptions;
-}
-
-static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) {
- // FIXME: Make this constexpr once all compilers are smart enough to do it.
- static DescVector Descriptions = getDescriptions();
- // Handle possible corrupted or unsupported operation.
- if (OpCode >= Descriptions.size())
- return {};
- return Descriptions[OpCode];
-}
-
-bool DWARFExpression::Operation::extract(DataExtractor Data,
- uint8_t AddressSize, uint64_t Offset,
- Optional<DwarfFormat> Format) {
- EndOffset = Offset;
- Opcode = Data.getU8(&Offset);
-
- Desc = getOpDesc(Opcode);
- if (Desc.Version == Operation::DwarfNA)
- return false;
-
- for (unsigned Operand = 0; Operand < 2; ++Operand) {
- unsigned Size = Desc.Op[Operand];
- unsigned Signed = Size & Operation::SignBit;
-
- if (Size == Operation::SizeNA)
- break;
-
- switch (Size & ~Operation::SignBit) {
- case Operation::Size1:
- Operands[Operand] = Data.getU8(&Offset);
- if (Signed)
- Operands[Operand] = (int8_t)Operands[Operand];
- break;
- case Operation::Size2:
- Operands[Operand] = Data.getU16(&Offset);
- if (Signed)
- Operands[Operand] = (int16_t)Operands[Operand];
- break;
- case Operation::Size4:
- Operands[Operand] = Data.getU32(&Offset);
- if (Signed)
- Operands[Operand] = (int32_t)Operands[Operand];
- break;
- case Operation::Size8:
- Operands[Operand] = Data.getU64(&Offset);
- break;
- case Operation::SizeAddr:
- Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
- break;
- case Operation::SizeRefAddr:
- if (!Format)
- return false;
- Operands[Operand] =
- Data.getUnsigned(&Offset, dwarf::getDwarfOffsetByteSize(*Format));
- break;
- case Operation::SizeLEB:
- if (Signed)
- Operands[Operand] = Data.getSLEB128(&Offset);
- else
- Operands[Operand] = Data.getULEB128(&Offset);
- break;
- case Operation::BaseTypeRef:
- Operands[Operand] = Data.getULEB128(&Offset);
- break;
- case Operation::WasmLocationArg:
- assert(Operand == 1);
- switch (Operands[0]) {
- case 0: case 1: case 2:
- Operands[Operand] = Data.getULEB128(&Offset);
- break;
- case 3: // global as uint32
- Operands[Operand] = Data.getU32(&Offset);
- break;
- default:
- return false; // Unknown Wasm location
- }
- break;
- case Operation::SizeBlock:
- // We need a size, so this cannot be the first operand
- if (Operand == 0)
- return false;
- // Store the offset of the block as the value.
- Operands[Operand] = Offset;
- Offset += Operands[Operand - 1];
- break;
- default:
- llvm_unreachable("Unknown DWARFExpression Op size");
- }
-
- OperandEndOffsets[Operand] = Offset;
- }
-
- EndOffset = Offset;
- return true;
-}
-
-static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
+//===-- DWARFExpression.cpp -----------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/Support/Format.h"
+#include <cassert>
+#include <cstdint>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+
+namespace llvm {
+
+typedef std::vector<DWARFExpression::Operation::Description> DescVector;
+
+static DescVector getDescriptions() {
+ DescVector Descriptions;
+ typedef DWARFExpression::Operation Op;
+ typedef Op::Description Desc;
+
+ Descriptions.resize(0xff);
+ Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
+ Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
+ Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
+ Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
+ Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
+ Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
+ Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
+ Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
+ Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
+ Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
+ Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
+ Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
+ for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
+ Descriptions[LA] = Desc(Op::Dwarf2);
+ for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
+ Descriptions[LA] = Desc(Op::Dwarf2);
+ for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
+ Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
+ Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
+ Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
+ Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
+ Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
+ Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
+ Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
+ Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
+ Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
+ Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
+ Descriptions[DW_OP_implicit_value] =
+ Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
+ Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
+ Descriptions[DW_OP_WASM_location] =
+ Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg);
+ Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
+ 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);
+ Descriptions[DW_OP_regval_type] =
+ Desc(Op::Dwarf5, Op::SizeLEB, Op::BaseTypeRef);
+
+ return Descriptions;
+}
+
+static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) {
+ // FIXME: Make this constexpr once all compilers are smart enough to do it.
+ static DescVector Descriptions = getDescriptions();
+ // Handle possible corrupted or unsupported operation.
+ if (OpCode >= Descriptions.size())
+ return {};
+ return Descriptions[OpCode];
+}
+
+bool DWARFExpression::Operation::extract(DataExtractor Data,
+ uint8_t AddressSize, uint64_t Offset,
+ Optional<DwarfFormat> Format) {
+ EndOffset = Offset;
+ Opcode = Data.getU8(&Offset);
+
+ Desc = getOpDesc(Opcode);
+ if (Desc.Version == Operation::DwarfNA)
+ return false;
+
+ for (unsigned Operand = 0; Operand < 2; ++Operand) {
+ unsigned Size = Desc.Op[Operand];
+ unsigned Signed = Size & Operation::SignBit;
+
+ if (Size == Operation::SizeNA)
+ break;
+
+ switch (Size & ~Operation::SignBit) {
+ case Operation::Size1:
+ Operands[Operand] = Data.getU8(&Offset);
+ if (Signed)
+ Operands[Operand] = (int8_t)Operands[Operand];
+ break;
+ case Operation::Size2:
+ Operands[Operand] = Data.getU16(&Offset);
+ if (Signed)
+ Operands[Operand] = (int16_t)Operands[Operand];
+ break;
+ case Operation::Size4:
+ Operands[Operand] = Data.getU32(&Offset);
+ if (Signed)
+ Operands[Operand] = (int32_t)Operands[Operand];
+ break;
+ case Operation::Size8:
+ Operands[Operand] = Data.getU64(&Offset);
+ break;
+ case Operation::SizeAddr:
+ Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
+ break;
+ case Operation::SizeRefAddr:
+ if (!Format)
+ return false;
+ Operands[Operand] =
+ Data.getUnsigned(&Offset, dwarf::getDwarfOffsetByteSize(*Format));
+ break;
+ case Operation::SizeLEB:
+ if (Signed)
+ Operands[Operand] = Data.getSLEB128(&Offset);
+ else
+ Operands[Operand] = Data.getULEB128(&Offset);
+ break;
+ case Operation::BaseTypeRef:
+ Operands[Operand] = Data.getULEB128(&Offset);
+ break;
+ case Operation::WasmLocationArg:
+ assert(Operand == 1);
+ switch (Operands[0]) {
+ case 0: case 1: case 2:
+ Operands[Operand] = Data.getULEB128(&Offset);
+ break;
+ case 3: // global as uint32
+ Operands[Operand] = Data.getU32(&Offset);
+ break;
+ default:
+ return false; // Unknown Wasm location
+ }
+ break;
+ case Operation::SizeBlock:
+ // We need a size, so this cannot be the first operand
+ if (Operand == 0)
+ return false;
+ // Store the offset of the block as the value.
+ Operands[Operand] = Offset;
+ Offset += Operands[Operand - 1];
+ break;
+ default:
+ llvm_unreachable("Unknown DWARFExpression Op size");
+ }
+
+ OperandEndOffsets[Operand] = Offset;
+ }
+
+ EndOffset = Offset;
+ return true;
+}
+
+static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
DIDumpOptions DumpOpts, uint64_t Operands[2],
unsigned Operand) {
- assert(Operand < 2 && "operand out of bounds");
- auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
- if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
+ assert(Operand < 2 && "operand out of bounds");
+ auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
+ if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
OS << " (";
if (DumpOpts.Verbose)
OS << format("0x%08" PRIx64 " -> ", Operands[Operand]);
OS << format("0x%08" PRIx64 ")", 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]);
- }
-}
-
+ if (auto Name = Die.find(dwarf::DW_AT_name))
+ OS << " \"" << Name->getAsCString() << "\"";
+ } else {
+ OS << format(" <invalid base_type ref: 0x%" PRIx64 ">",
+ Operands[Operand]);
+ }
+}
+
static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS,
DIDumpOptions DumpOpts, uint8_t Opcode,
- uint64_t Operands[2],
- const MCRegisterInfo *MRI, bool isEH) {
- if (!MRI)
- return false;
-
- uint64_t DwarfRegNum;
- unsigned OpNum = 0;
-
- if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
- Opcode == DW_OP_regval_type)
- DwarfRegNum = Operands[OpNum++];
- else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
- DwarfRegNum = Opcode - DW_OP_breg0;
- else
- DwarfRegNum = Opcode - DW_OP_reg0;
-
- if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) {
- if (const char *RegName = MRI->getName(*LLVMRegNum)) {
- if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
- Opcode == DW_OP_bregx)
- OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
- else
- OS << ' ' << RegName;
-
- if (Opcode == DW_OP_regval_type)
+ uint64_t Operands[2],
+ const MCRegisterInfo *MRI, bool isEH) {
+ if (!MRI)
+ return false;
+
+ uint64_t DwarfRegNum;
+ unsigned OpNum = 0;
+
+ if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
+ Opcode == DW_OP_regval_type)
+ DwarfRegNum = Operands[OpNum++];
+ else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
+ DwarfRegNum = Opcode - DW_OP_breg0;
+ else
+ DwarfRegNum = Opcode - DW_OP_reg0;
+
+ if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) {
+ if (const char *RegName = MRI->getName(*LLVMRegNum)) {
+ if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
+ Opcode == DW_OP_bregx)
+ OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
+ else
+ OS << ' ' << RegName;
+
+ if (Opcode == DW_OP_regval_type)
prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, 1);
- return true;
- }
- }
-
- return false;
-}
-
+ return true;
+ }
+ }
+
+ return false;
+}
+
bool DWARFExpression::Operation::print(raw_ostream &OS, DIDumpOptions DumpOpts,
- const DWARFExpression *Expr,
- const MCRegisterInfo *RegInfo,
+ const DWARFExpression *Expr,
+ const MCRegisterInfo *RegInfo,
DWARFUnit *U, bool isEH) {
- if (Error) {
- OS << "<decoding error>";
- return false;
- }
-
- StringRef Name = OperationEncodingString(Opcode);
- assert(!Name.empty() && "DW_OP has no name!");
- OS << Name;
-
- if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
- (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
- Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
- Opcode == DW_OP_regval_type)
+ if (Error) {
+ OS << "<decoding error>";
+ return false;
+ }
+
+ StringRef Name = OperationEncodingString(Opcode);
+ assert(!Name.empty() && "DW_OP has no name!");
+ OS << Name;
+
+ if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
+ (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
+ Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
+ Opcode == DW_OP_regval_type)
if (prettyPrintRegisterOp(U, OS, DumpOpts, Opcode, Operands, RegInfo, isEH))
- return true;
-
- for (unsigned Operand = 0; Operand < 2; ++Operand) {
- unsigned Size = Desc.Op[Operand];
- unsigned Signed = Size & Operation::SignBit;
-
- if (Size == Operation::SizeNA)
- break;
-
- if (Size == Operation::BaseTypeRef && U) {
- // For DW_OP_convert the operand may be 0 to indicate that conversion to
- // the generic type should be done. The same holds for DW_OP_reinterpret,
- // which is currently not supported.
- if (Opcode == DW_OP_convert && Operands[Operand] == 0)
- OS << " 0x0";
- else
+ return true;
+
+ for (unsigned Operand = 0; Operand < 2; ++Operand) {
+ unsigned Size = Desc.Op[Operand];
+ unsigned Signed = Size & Operation::SignBit;
+
+ if (Size == Operation::SizeNA)
+ break;
+
+ if (Size == Operation::BaseTypeRef && U) {
+ // For DW_OP_convert the operand may be 0 to indicate that conversion to
+ // the generic type should be done. The same holds for DW_OP_reinterpret,
+ // which is currently not supported.
+ if (Opcode == DW_OP_convert && Operands[Operand] == 0)
+ OS << " 0x0";
+ else
prettyPrintBaseTypeRef(U, OS, DumpOpts, Operands, Operand);
- } else if (Size == Operation::WasmLocationArg) {
- assert(Operand == 1);
- switch (Operands[0]) {
- case 0: case 1: case 2:
- case 3: // global as uint32
- OS << format(" 0x%" PRIx64, Operands[Operand]);
- break;
- default: assert(false);
- }
- } else if (Size == Operation::SizeBlock) {
- uint64_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 if (Opcode != DW_OP_entry_value &&
- Opcode != DW_OP_GNU_entry_value)
- OS << format(" 0x%" PRIx64, Operands[Operand]);
- }
- }
- return true;
-}
-
+ } else if (Size == Operation::WasmLocationArg) {
+ assert(Operand == 1);
+ switch (Operands[0]) {
+ case 0: case 1: case 2:
+ case 3: // global as uint32
+ OS << format(" 0x%" PRIx64, Operands[Operand]);
+ break;
+ default: assert(false);
+ }
+ } else if (Size == Operation::SizeBlock) {
+ uint64_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 if (Opcode != DW_OP_entry_value &&
+ Opcode != DW_OP_GNU_entry_value)
+ OS << format(" 0x%" PRIx64, Operands[Operand]);
+ }
+ }
+ return true;
+}
+
void DWARFExpression::print(raw_ostream &OS, DIDumpOptions DumpOpts,
const MCRegisterInfo *RegInfo, DWARFUnit *U,
bool IsEH) const {
- uint32_t EntryValExprSize = 0;
- for (auto &Op : *this) {
+ uint32_t EntryValExprSize = 0;
+ for (auto &Op : *this) {
if (!Op.print(OS, DumpOpts, this, RegInfo, U, IsEH)) {
- uint64_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) {
- // For DW_OP_convert the operand may be 0 to indicate that conversion to
- // the generic type should be done, so don't look up a base type in that
- // case. The same holds for DW_OP_reinterpret, which is currently not
- // supported.
- if (Opcode == DW_OP_convert && Operands[Operand] == 0)
- continue;
- 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;
-}
-
-/// A user-facing string representation of a DWARF expression. This might be an
-/// Address expression, in which case it will be implicitly dereferenced, or a
-/// Value expression.
-struct PrintedExpr {
- enum ExprKind {
- Address,
- Value,
- };
- ExprKind Kind;
- SmallString<16> String;
-
- PrintedExpr(ExprKind K = Address) : Kind(K) {}
-};
-
-static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I,
- const DWARFExpression::iterator E,
- const MCRegisterInfo &MRI) {
- SmallVector<PrintedExpr, 4> Stack;
-
- while (I != E) {
- DWARFExpression::Operation &Op = *I;
- uint8_t Opcode = Op.getCode();
- switch (Opcode) {
- case dwarf::DW_OP_regx: {
- // DW_OP_regx: A register, with the register num given as an operand.
- // Printed as the plain register name.
- uint64_t DwarfRegNum = Op.getRawOperand(0);
- Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
- if (!LLVMRegNum) {
- OS << "<unknown register " << DwarfRegNum << ">";
- return false;
- }
- raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
- S << MRI.getName(*LLVMRegNum);
- break;
- }
- case dwarf::DW_OP_bregx: {
- int DwarfRegNum = Op.getRawOperand(0);
- int64_t Offset = Op.getRawOperand(1);
- Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
- if (!LLVMRegNum) {
- OS << "<unknown register " << DwarfRegNum << ">";
- return false;
- }
- raw_svector_ostream S(Stack.emplace_back().String);
- S << MRI.getName(*LLVMRegNum);
- if (Offset)
- S << format("%+" PRId64, Offset);
- break;
- }
- case dwarf::DW_OP_entry_value:
- case dwarf::DW_OP_GNU_entry_value: {
- // DW_OP_entry_value contains a sub-expression which must be rendered
- // separately.
- uint64_t SubExprLength = Op.getRawOperand(0);
- DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
- ++I;
- raw_svector_ostream S(Stack.emplace_back().String);
- S << "entry(";
- printCompactDWARFExpr(S, I, SubExprEnd, MRI);
- S << ")";
- I = SubExprEnd;
- continue;
- }
- case dwarf::DW_OP_stack_value: {
- // The top stack entry should be treated as the actual value of tne
- // variable, rather than the address of the variable in memory.
- assert(!Stack.empty());
- Stack.back().Kind = PrintedExpr::Value;
- break;
- }
- default:
- if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
- // DW_OP_reg<N>: A register, with the register num implied by the
- // opcode. Printed as the plain register name.
- uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
- Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
- if (!LLVMRegNum) {
- OS << "<unknown register " << DwarfRegNum << ">";
- return false;
- }
- raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
- S << MRI.getName(*LLVMRegNum);
- } else if (Opcode >= dwarf::DW_OP_breg0 &&
- Opcode <= dwarf::DW_OP_breg31) {
- int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
- int64_t Offset = Op.getRawOperand(0);
- Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
- if (!LLVMRegNum) {
- OS << "<unknown register " << DwarfRegNum << ">";
- return false;
- }
- raw_svector_ostream S(Stack.emplace_back().String);
- S << MRI.getName(*LLVMRegNum);
- if (Offset)
- S << format("%+" PRId64, Offset);
- } else {
- // If we hit an unknown operand, we don't know its effect on the stack,
- // so bail out on the whole expression.
- OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
- << (int)Opcode << ")>";
- return false;
- }
- break;
- }
- ++I;
- }
-
- assert(Stack.size() == 1 && "expected one value on stack");
-
- if (Stack.front().Kind == PrintedExpr::Address)
- OS << "[" << Stack.front().String << "]";
- else
- OS << Stack.front().String;
-
- return true;
-}
-
-bool DWARFExpression::printCompact(raw_ostream &OS, const MCRegisterInfo &MRI) {
- return printCompactDWARFExpr(OS, begin(), end(), MRI);
-}
-
-} // namespace llvm
+ uint64_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) {
+ // For DW_OP_convert the operand may be 0 to indicate that conversion to
+ // the generic type should be done, so don't look up a base type in that
+ // case. The same holds for DW_OP_reinterpret, which is currently not
+ // supported.
+ if (Opcode == DW_OP_convert && Operands[Operand] == 0)
+ continue;
+ 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;
+}
+
+/// A user-facing string representation of a DWARF expression. This might be an
+/// Address expression, in which case it will be implicitly dereferenced, or a
+/// Value expression.
+struct PrintedExpr {
+ enum ExprKind {
+ Address,
+ Value,
+ };
+ ExprKind Kind;
+ SmallString<16> String;
+
+ PrintedExpr(ExprKind K = Address) : Kind(K) {}
+};
+
+static bool printCompactDWARFExpr(raw_ostream &OS, DWARFExpression::iterator I,
+ const DWARFExpression::iterator E,
+ const MCRegisterInfo &MRI) {
+ SmallVector<PrintedExpr, 4> Stack;
+
+ while (I != E) {
+ DWARFExpression::Operation &Op = *I;
+ uint8_t Opcode = Op.getCode();
+ switch (Opcode) {
+ case dwarf::DW_OP_regx: {
+ // DW_OP_regx: A register, with the register num given as an operand.
+ // Printed as the plain register name.
+ uint64_t DwarfRegNum = Op.getRawOperand(0);
+ Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
+ if (!LLVMRegNum) {
+ OS << "<unknown register " << DwarfRegNum << ">";
+ return false;
+ }
+ raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+ S << MRI.getName(*LLVMRegNum);
+ break;
+ }
+ case dwarf::DW_OP_bregx: {
+ int DwarfRegNum = Op.getRawOperand(0);
+ int64_t Offset = Op.getRawOperand(1);
+ Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
+ if (!LLVMRegNum) {
+ OS << "<unknown register " << DwarfRegNum << ">";
+ return false;
+ }
+ raw_svector_ostream S(Stack.emplace_back().String);
+ S << MRI.getName(*LLVMRegNum);
+ if (Offset)
+ S << format("%+" PRId64, Offset);
+ break;
+ }
+ case dwarf::DW_OP_entry_value:
+ case dwarf::DW_OP_GNU_entry_value: {
+ // DW_OP_entry_value contains a sub-expression which must be rendered
+ // separately.
+ uint64_t SubExprLength = Op.getRawOperand(0);
+ DWARFExpression::iterator SubExprEnd = I.skipBytes(SubExprLength);
+ ++I;
+ raw_svector_ostream S(Stack.emplace_back().String);
+ S << "entry(";
+ printCompactDWARFExpr(S, I, SubExprEnd, MRI);
+ S << ")";
+ I = SubExprEnd;
+ continue;
+ }
+ case dwarf::DW_OP_stack_value: {
+ // The top stack entry should be treated as the actual value of tne
+ // variable, rather than the address of the variable in memory.
+ assert(!Stack.empty());
+ Stack.back().Kind = PrintedExpr::Value;
+ break;
+ }
+ default:
+ if (Opcode >= dwarf::DW_OP_reg0 && Opcode <= dwarf::DW_OP_reg31) {
+ // DW_OP_reg<N>: A register, with the register num implied by the
+ // opcode. Printed as the plain register name.
+ uint64_t DwarfRegNum = Opcode - dwarf::DW_OP_reg0;
+ Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
+ if (!LLVMRegNum) {
+ OS << "<unknown register " << DwarfRegNum << ">";
+ return false;
+ }
+ raw_svector_ostream S(Stack.emplace_back(PrintedExpr::Value).String);
+ S << MRI.getName(*LLVMRegNum);
+ } else if (Opcode >= dwarf::DW_OP_breg0 &&
+ Opcode <= dwarf::DW_OP_breg31) {
+ int DwarfRegNum = Opcode - dwarf::DW_OP_breg0;
+ int64_t Offset = Op.getRawOperand(0);
+ Optional<unsigned> LLVMRegNum = MRI.getLLVMRegNum(DwarfRegNum, false);
+ if (!LLVMRegNum) {
+ OS << "<unknown register " << DwarfRegNum << ">";
+ return false;
+ }
+ raw_svector_ostream S(Stack.emplace_back().String);
+ S << MRI.getName(*LLVMRegNum);
+ if (Offset)
+ S << format("%+" PRId64, Offset);
+ } else {
+ // If we hit an unknown operand, we don't know its effect on the stack,
+ // so bail out on the whole expression.
+ OS << "<unknown op " << dwarf::OperationEncodingString(Opcode) << " ("
+ << (int)Opcode << ")>";
+ return false;
+ }
+ break;
+ }
+ ++I;
+ }
+
+ assert(Stack.size() == 1 && "expected one value on stack");
+
+ if (Stack.front().Kind == PrintedExpr::Address)
+ OS << "[" << Stack.front().String << "]";
+ else
+ OS << Stack.front().String;
+
+ return true;
+}
+
+bool DWARFExpression::printCompact(raw_ostream &OS, const MCRegisterInfo &MRI) {
+ return printCompactDWARFExpr(OS, begin(), end(), MRI);
+}
+
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp
index 2559765876..be27899454 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFFormValue.cpp
@@ -1,732 +1,732 @@
-//===- DWARFFormValue.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/None.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/WithColor.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cinttypes>
-#include <cstdint>
-#include <limits>
-
-using namespace llvm;
-using namespace dwarf;
-
-static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
- DWARFFormValue::FC_Unknown, // 0x0
- DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
- DWARFFormValue::FC_Unknown, // 0x02 unused
- DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2
- DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4
- DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
- // --- These can be FC_SectionOffset in DWARF3 and below:
- DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
- DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
- // ---
- DWARFFormValue::FC_String, // 0x08 DW_FORM_string
- DWARFFormValue::FC_Block, // 0x09 DW_FORM_block
- DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1
- DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1
- DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag
- DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata
- DWARFFormValue::FC_String, // 0x0e DW_FORM_strp
- DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata
- DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr
- DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1
- DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2
- DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4
- DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8
- DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata
- DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect
- DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
- DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc
- DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
- DWARFFormValue::FC_String, // 0x1a DW_FORM_strx
- DWARFFormValue::FC_Address, // 0x1b DW_FORM_addrx
- DWARFFormValue::FC_Reference, // 0x1c DW_FORM_ref_sup4
- DWARFFormValue::FC_String, // 0x1d DW_FORM_strp_sup
- DWARFFormValue::FC_Constant, // 0x1e DW_FORM_data16
- DWARFFormValue::FC_String, // 0x1f DW_FORM_line_strp
- DWARFFormValue::FC_Reference, // 0x20 DW_FORM_ref_sig8
- DWARFFormValue::FC_Constant, // 0x21 DW_FORM_implicit_const
- DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx
- DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx
- DWARFFormValue::FC_Reference, // 0x24 DW_FORM_ref_sup8
- DWARFFormValue::FC_String, // 0x25 DW_FORM_strx1
- DWARFFormValue::FC_String, // 0x26 DW_FORM_strx2
- DWARFFormValue::FC_String, // 0x27 DW_FORM_strx3
- DWARFFormValue::FC_String, // 0x28 DW_FORM_strx4
- DWARFFormValue::FC_Address, // 0x29 DW_FORM_addrx1
- DWARFFormValue::FC_Address, // 0x2a DW_FORM_addrx2
- DWARFFormValue::FC_Address, // 0x2b DW_FORM_addrx3
- DWARFFormValue::FC_Address, // 0x2c DW_FORM_addrx4
-
-};
-
-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,
- uint64_t *OffsetPtr) {
- DWARFFormValue FormValue(F);
- FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
- U->getFormParams(), U);
- return FormValue;
-}
-
-bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
- uint64_t *OffsetPtr,
- const dwarf::FormParams Params) {
- bool Indirect = false;
- do {
- switch (Form) {
- // Blocks of inlined data that have a length field and the data bytes
- // inlined in the .debug_info.
- case DW_FORM_exprloc:
- case DW_FORM_block: {
- uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
- *OffsetPtr += size;
- return true;
- }
- case DW_FORM_block1: {
- uint8_t size = DebugInfoData.getU8(OffsetPtr);
- *OffsetPtr += size;
- return true;
- }
- case DW_FORM_block2: {
- uint16_t size = DebugInfoData.getU16(OffsetPtr);
- *OffsetPtr += size;
- return true;
- }
- case DW_FORM_block4: {
- uint32_t size = DebugInfoData.getU32(OffsetPtr);
- *OffsetPtr += size;
- return true;
- }
-
- // Inlined NULL terminated C-strings.
- case DW_FORM_string:
- DebugInfoData.getCStr(OffsetPtr);
- return true;
-
- case DW_FORM_addr:
- case DW_FORM_ref_addr:
- case DW_FORM_flag_present:
- case DW_FORM_data1:
- case DW_FORM_data2:
- case DW_FORM_data4:
- case DW_FORM_data8:
- case DW_FORM_data16:
- case DW_FORM_flag:
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- case DW_FORM_ref_sup4:
- case DW_FORM_ref_sup8:
- case DW_FORM_strx1:
- case DW_FORM_strx2:
- case DW_FORM_strx4:
- case DW_FORM_addrx1:
- case DW_FORM_addrx2:
- case DW_FORM_addrx4:
- case DW_FORM_sec_offset:
- case DW_FORM_strp:
- case DW_FORM_strp_sup:
- case DW_FORM_line_strp:
- case DW_FORM_GNU_ref_alt:
- case DW_FORM_GNU_strp_alt:
+//===- DWARFFormValue.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cinttypes>
+#include <cstdint>
+#include <limits>
+
+using namespace llvm;
+using namespace dwarf;
+
+static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
+ DWARFFormValue::FC_Unknown, // 0x0
+ DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
+ DWARFFormValue::FC_Unknown, // 0x02 unused
+ DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2
+ DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4
+ DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
+ // --- These can be FC_SectionOffset in DWARF3 and below:
+ DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
+ DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
+ // ---
+ DWARFFormValue::FC_String, // 0x08 DW_FORM_string
+ DWARFFormValue::FC_Block, // 0x09 DW_FORM_block
+ DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1
+ DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1
+ DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag
+ DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata
+ DWARFFormValue::FC_String, // 0x0e DW_FORM_strp
+ DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata
+ DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr
+ DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1
+ DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2
+ DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4
+ DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8
+ DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata
+ DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect
+ DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
+ DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc
+ DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
+ DWARFFormValue::FC_String, // 0x1a DW_FORM_strx
+ DWARFFormValue::FC_Address, // 0x1b DW_FORM_addrx
+ DWARFFormValue::FC_Reference, // 0x1c DW_FORM_ref_sup4
+ DWARFFormValue::FC_String, // 0x1d DW_FORM_strp_sup
+ DWARFFormValue::FC_Constant, // 0x1e DW_FORM_data16
+ DWARFFormValue::FC_String, // 0x1f DW_FORM_line_strp
+ DWARFFormValue::FC_Reference, // 0x20 DW_FORM_ref_sig8
+ DWARFFormValue::FC_Constant, // 0x21 DW_FORM_implicit_const
+ DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx
+ DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx
+ DWARFFormValue::FC_Reference, // 0x24 DW_FORM_ref_sup8
+ DWARFFormValue::FC_String, // 0x25 DW_FORM_strx1
+ DWARFFormValue::FC_String, // 0x26 DW_FORM_strx2
+ DWARFFormValue::FC_String, // 0x27 DW_FORM_strx3
+ DWARFFormValue::FC_String, // 0x28 DW_FORM_strx4
+ DWARFFormValue::FC_Address, // 0x29 DW_FORM_addrx1
+ DWARFFormValue::FC_Address, // 0x2a DW_FORM_addrx2
+ DWARFFormValue::FC_Address, // 0x2b DW_FORM_addrx3
+ DWARFFormValue::FC_Address, // 0x2c DW_FORM_addrx4
+
+};
+
+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,
+ uint64_t *OffsetPtr) {
+ DWARFFormValue FormValue(F);
+ FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
+ U->getFormParams(), U);
+ return FormValue;
+}
+
+bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
+ uint64_t *OffsetPtr,
+ const dwarf::FormParams Params) {
+ bool Indirect = false;
+ do {
+ switch (Form) {
+ // Blocks of inlined data that have a length field and the data bytes
+ // inlined in the .debug_info.
+ case DW_FORM_exprloc:
+ case DW_FORM_block: {
+ uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
+ *OffsetPtr += size;
+ return true;
+ }
+ case DW_FORM_block1: {
+ uint8_t size = DebugInfoData.getU8(OffsetPtr);
+ *OffsetPtr += size;
+ return true;
+ }
+ case DW_FORM_block2: {
+ uint16_t size = DebugInfoData.getU16(OffsetPtr);
+ *OffsetPtr += size;
+ return true;
+ }
+ case DW_FORM_block4: {
+ uint32_t size = DebugInfoData.getU32(OffsetPtr);
+ *OffsetPtr += size;
+ return true;
+ }
+
+ // Inlined NULL terminated C-strings.
+ case DW_FORM_string:
+ DebugInfoData.getCStr(OffsetPtr);
+ return true;
+
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr:
+ case DW_FORM_flag_present:
+ case DW_FORM_data1:
+ case DW_FORM_data2:
+ case DW_FORM_data4:
+ case DW_FORM_data8:
+ case DW_FORM_data16:
+ case DW_FORM_flag:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_ref_sup4:
+ case DW_FORM_ref_sup8:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx4:
+ case DW_FORM_addrx1:
+ case DW_FORM_addrx2:
+ case DW_FORM_addrx4:
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ case DW_FORM_strp_sup:
+ case DW_FORM_line_strp:
+ case DW_FORM_GNU_ref_alt:
+ case DW_FORM_GNU_strp_alt:
case DW_FORM_implicit_const:
- if (Optional<uint8_t> FixedSize =
- dwarf::getFixedFormByteSize(Form, Params)) {
- *OffsetPtr += *FixedSize;
- return true;
- }
- return false;
-
- // signed or unsigned LEB 128 values.
- case DW_FORM_sdata:
- DebugInfoData.getSLEB128(OffsetPtr);
- return true;
-
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- case DW_FORM_strx:
- case DW_FORM_addrx:
- case DW_FORM_loclistx:
- case DW_FORM_rnglistx:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- DebugInfoData.getULEB128(OffsetPtr);
- return true;
-
- case DW_FORM_indirect:
- Indirect = true;
- Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
- break;
-
- default:
- return false;
- }
- } while (Indirect);
- return true;
-}
-
-bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
- // First, check DWARF5 form classes.
- if (Form < makeArrayRef(DWARF5FormClasses).size() &&
- DWARF5FormClasses[Form] == FC)
- return true;
- // Check more forms from extensions and proposals.
- switch (Form) {
- case DW_FORM_GNU_ref_alt:
- return (FC == FC_Reference);
- case DW_FORM_GNU_addr_index:
- return (FC == FC_Address);
- case DW_FORM_GNU_str_index:
- case DW_FORM_GNU_strp_alt:
- return (FC == FC_String);
- default:
- break;
- }
-
- 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,
- uint64_t *OffsetPtr, dwarf::FormParams FP,
- const DWARFContext *Ctx,
- const DWARFUnit *CU) {
- if (!Ctx && CU)
- Ctx = &CU->getContext();
- C = Ctx;
- U = CU;
- Format = FP.Format;
- bool Indirect = false;
- bool IsBlock = false;
- Value.data = nullptr;
- // Read the value for the form into value and follow and DW_FORM_indirect
- // instances we run into
- Error Err = Error::success();
- do {
- Indirect = false;
- switch (Form) {
- case DW_FORM_addr:
- case DW_FORM_ref_addr: {
- uint16_t Size =
- (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
- Value.uval =
- Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex, &Err);
- break;
- }
- case DW_FORM_exprloc:
- case DW_FORM_block:
- Value.uval = Data.getULEB128(OffsetPtr, &Err);
- IsBlock = true;
- break;
- case DW_FORM_block1:
- Value.uval = Data.getU8(OffsetPtr, &Err);
- IsBlock = true;
- break;
- case DW_FORM_block2:
- Value.uval = Data.getU16(OffsetPtr, &Err);
- IsBlock = true;
- break;
- case DW_FORM_block4:
- Value.uval = Data.getU32(OffsetPtr, &Err);
- IsBlock = true;
- break;
- case DW_FORM_data1:
- case DW_FORM_ref1:
- case DW_FORM_flag:
- case DW_FORM_strx1:
- case DW_FORM_addrx1:
- Value.uval = Data.getU8(OffsetPtr, &Err);
- break;
- case DW_FORM_data2:
- case DW_FORM_ref2:
- case DW_FORM_strx2:
- case DW_FORM_addrx2:
- Value.uval = Data.getU16(OffsetPtr, &Err);
- break;
- case DW_FORM_strx3:
- Value.uval = Data.getU24(OffsetPtr, &Err);
- break;
- case DW_FORM_data4:
- case DW_FORM_ref4:
- case DW_FORM_ref_sup4:
- case DW_FORM_strx4:
- case DW_FORM_addrx4:
- Value.uval = Data.getRelocatedValue(4, OffsetPtr, nullptr, &Err);
- break;
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sup8:
- Value.uval = Data.getRelocatedValue(8, OffsetPtr, nullptr, &Err);
- break;
- case DW_FORM_data16:
- // Treat this like a 16-byte block.
- Value.uval = 16;
- IsBlock = true;
- break;
- case DW_FORM_sdata:
- Value.sval = Data.getSLEB128(OffsetPtr, &Err);
- break;
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- case DW_FORM_rnglistx:
- case DW_FORM_loclistx:
- case DW_FORM_GNU_addr_index:
- case DW_FORM_GNU_str_index:
- case DW_FORM_addrx:
- case DW_FORM_strx:
- Value.uval = Data.getULEB128(OffsetPtr, &Err);
- break;
- case DW_FORM_string:
- Value.cstr = Data.getCStr(OffsetPtr, &Err);
- break;
- case DW_FORM_indirect:
- Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr, &Err));
- Indirect = true;
- break;
- case DW_FORM_strp:
- case DW_FORM_sec_offset:
- case DW_FORM_GNU_ref_alt:
- case DW_FORM_GNU_strp_alt:
- case DW_FORM_line_strp:
- case DW_FORM_strp_sup: {
- Value.uval = Data.getRelocatedValue(FP.getDwarfOffsetByteSize(),
- OffsetPtr, nullptr, &Err);
- break;
- }
- case DW_FORM_flag_present:
- Value.uval = 1;
- break;
- case DW_FORM_ref_sig8:
- Value.uval = Data.getU64(OffsetPtr, &Err);
- break;
+ if (Optional<uint8_t> FixedSize =
+ dwarf::getFixedFormByteSize(Form, Params)) {
+ *OffsetPtr += *FixedSize;
+ return true;
+ }
+ return false;
+
+ // signed or unsigned LEB 128 values.
+ case DW_FORM_sdata:
+ DebugInfoData.getSLEB128(OffsetPtr);
+ return true;
+
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_strx:
+ case DW_FORM_addrx:
+ case DW_FORM_loclistx:
+ case DW_FORM_rnglistx:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ DebugInfoData.getULEB128(OffsetPtr);
+ return true;
+
+ case DW_FORM_indirect:
+ Indirect = true;
+ Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
+ break;
+
+ default:
+ return false;
+ }
+ } while (Indirect);
+ return true;
+}
+
+bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
+ // First, check DWARF5 form classes.
+ if (Form < makeArrayRef(DWARF5FormClasses).size() &&
+ DWARF5FormClasses[Form] == FC)
+ return true;
+ // Check more forms from extensions and proposals.
+ switch (Form) {
+ case DW_FORM_GNU_ref_alt:
+ return (FC == FC_Reference);
+ case DW_FORM_GNU_addr_index:
+ return (FC == FC_Address);
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_GNU_strp_alt:
+ return (FC == FC_String);
+ default:
+ break;
+ }
+
+ 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,
+ uint64_t *OffsetPtr, dwarf::FormParams FP,
+ const DWARFContext *Ctx,
+ const DWARFUnit *CU) {
+ if (!Ctx && CU)
+ Ctx = &CU->getContext();
+ C = Ctx;
+ U = CU;
+ Format = FP.Format;
+ bool Indirect = false;
+ bool IsBlock = false;
+ Value.data = nullptr;
+ // Read the value for the form into value and follow and DW_FORM_indirect
+ // instances we run into
+ Error Err = Error::success();
+ do {
+ Indirect = false;
+ switch (Form) {
+ case DW_FORM_addr:
+ case DW_FORM_ref_addr: {
+ uint16_t Size =
+ (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
+ Value.uval =
+ Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex, &Err);
+ break;
+ }
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ Value.uval = Data.getULEB128(OffsetPtr, &Err);
+ IsBlock = true;
+ break;
+ case DW_FORM_block1:
+ Value.uval = Data.getU8(OffsetPtr, &Err);
+ IsBlock = true;
+ break;
+ case DW_FORM_block2:
+ Value.uval = Data.getU16(OffsetPtr, &Err);
+ IsBlock = true;
+ break;
+ case DW_FORM_block4:
+ Value.uval = Data.getU32(OffsetPtr, &Err);
+ IsBlock = true;
+ break;
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_flag:
+ case DW_FORM_strx1:
+ case DW_FORM_addrx1:
+ Value.uval = Data.getU8(OffsetPtr, &Err);
+ break;
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ case DW_FORM_strx2:
+ case DW_FORM_addrx2:
+ Value.uval = Data.getU16(OffsetPtr, &Err);
+ break;
+ case DW_FORM_strx3:
+ Value.uval = Data.getU24(OffsetPtr, &Err);
+ break;
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_ref_sup4:
+ case DW_FORM_strx4:
+ case DW_FORM_addrx4:
+ Value.uval = Data.getRelocatedValue(4, OffsetPtr, nullptr, &Err);
+ break;
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sup8:
+ Value.uval = Data.getRelocatedValue(8, OffsetPtr, nullptr, &Err);
+ break;
+ case DW_FORM_data16:
+ // Treat this like a 16-byte block.
+ Value.uval = 16;
+ IsBlock = true;
+ break;
+ case DW_FORM_sdata:
+ Value.sval = Data.getSLEB128(OffsetPtr, &Err);
+ break;
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_rnglistx:
+ case DW_FORM_loclistx:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_addrx:
+ case DW_FORM_strx:
+ Value.uval = Data.getULEB128(OffsetPtr, &Err);
+ break;
+ case DW_FORM_string:
+ Value.cstr = Data.getCStr(OffsetPtr, &Err);
+ break;
+ case DW_FORM_indirect:
+ Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr, &Err));
+ Indirect = true;
+ break;
+ case DW_FORM_strp:
+ case DW_FORM_sec_offset:
+ case DW_FORM_GNU_ref_alt:
+ case DW_FORM_GNU_strp_alt:
+ case DW_FORM_line_strp:
+ case DW_FORM_strp_sup: {
+ Value.uval = Data.getRelocatedValue(FP.getDwarfOffsetByteSize(),
+ OffsetPtr, nullptr, &Err);
+ break;
+ }
+ case DW_FORM_flag_present:
+ Value.uval = 1;
+ break;
+ case DW_FORM_ref_sig8:
+ Value.uval = Data.getU64(OffsetPtr, &Err);
+ break;
case DW_FORM_implicit_const:
// Value has been already set by DWARFFormValue::createFromSValue.
break;
- default:
- // DWARFFormValue::skipValue() will have caught this and caused all
- // DWARF DIEs to fail to be parsed, so this code is not be reachable.
- llvm_unreachable("unsupported form");
- }
- } while (Indirect && !Err);
-
- if (IsBlock)
- Value.data = Data.getBytes(OffsetPtr, Value.uval, &Err).bytes_begin();
-
- return !errorToBool(std::move(Err));
-}
-
+ default:
+ // DWARFFormValue::skipValue() will have caught this and caused all
+ // DWARF DIEs to fail to be parsed, so this code is not be reachable.
+ llvm_unreachable("unsupported form");
+ }
+ } while (Indirect && !Err);
+
+ if (IsBlock)
+ Value.data = Data.getBytes(OffsetPtr, Value.uval, &Err).bytes_begin();
+
+ return !errorToBool(std::move(Err));
+}
+
void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize,
uint64_t Address) {
uint8_t HexDigits = AddressSize * 2;
OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address);
}
-void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
- DIDumpOptions DumpOpts,
- object::SectionedAddress SA) const {
+void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
+ DIDumpOptions DumpOpts,
+ object::SectionedAddress SA) const {
dumpAddress(OS, U->getAddressByteSize(), SA.Address);
- dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
- SA.SectionIndex);
-}
-
-void DWARFFormValue::dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
- DIDumpOptions DumpOpts,
- uint64_t SectionIndex) {
- if (!DumpOpts.Verbose || SectionIndex == -1ULL)
- return;
- ArrayRef<SectionName> SectionNames = Obj.getSectionNames();
- const auto &SecRef = SectionNames[SectionIndex];
-
- OS << " \"" << SecRef.Name << '\"';
-
- // Print section index if name is not unique.
- if (!SecRef.IsNameUnique)
- OS << format(" [%" PRIu64 "]", SectionIndex);
-}
-
-void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
- uint64_t UValue = Value.uval;
- bool CURelativeOffset = false;
- raw_ostream &AddrOS = DumpOpts.ShowAddresses
- ? WithColor(OS, HighlightColor::Address).get()
- : nulls();
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
- switch (Form) {
- case DW_FORM_addr:
- dumpSectionedAddress(AddrOS, DumpOpts, {Value.uval, Value.SectionIndex});
- break;
- case DW_FORM_addrx:
- case DW_FORM_addrx1:
- case DW_FORM_addrx2:
- case DW_FORM_addrx3:
- case DW_FORM_addrx4:
- case DW_FORM_GNU_addr_index: {
- 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 (A)
- dumpSectionedAddress(AddrOS, DumpOpts, *A);
- else
- OS << "<unresolved>";
- break;
- }
- case DW_FORM_flag_present:
- OS << "true";
- break;
- case DW_FORM_flag:
- case DW_FORM_data1:
- OS << format("0x%02x", (uint8_t)UValue);
- break;
- case DW_FORM_data2:
- OS << format("0x%04x", (uint16_t)UValue);
- break;
- case DW_FORM_data4:
- OS << format("0x%08x", (uint32_t)UValue);
- break;
- case DW_FORM_ref_sig8:
- AddrOS << format("0x%016" PRIx64, UValue);
- break;
- case DW_FORM_data8:
- OS << format("0x%016" PRIx64, UValue);
- break;
- case DW_FORM_data16:
- OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16);
- break;
- case DW_FORM_string:
- OS << '"';
- OS.write_escaped(Value.cstr);
- OS << '"';
- break;
- case DW_FORM_exprloc:
- case DW_FORM_block:
- case DW_FORM_block1:
- case DW_FORM_block2:
- case DW_FORM_block4:
- if (UValue > 0) {
- switch (Form) {
- case DW_FORM_exprloc:
- case DW_FORM_block:
- AddrOS << format("<0x%" PRIx64 "> ", UValue);
- break;
- case DW_FORM_block1:
- AddrOS << format("<0x%2.2x> ", (uint8_t)UValue);
- break;
- case DW_FORM_block2:
- AddrOS << format("<0x%4.4x> ", (uint16_t)UValue);
- break;
- case DW_FORM_block4:
- AddrOS << format("<0x%8.8x> ", (uint32_t)UValue);
- break;
- default:
- break;
- }
-
- const uint8_t *DataPtr = Value.data;
- if (DataPtr) {
- // UValue contains size of block
- const uint8_t *EndDataPtr = DataPtr + UValue;
- while (DataPtr < EndDataPtr) {
- AddrOS << format("%2.2x ", *DataPtr);
- ++DataPtr;
- }
- } else
- OS << "NULL";
- }
- break;
-
- case DW_FORM_sdata:
+ dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
+ SA.SectionIndex);
+}
+
+void DWARFFormValue::dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
+ DIDumpOptions DumpOpts,
+ uint64_t SectionIndex) {
+ if (!DumpOpts.Verbose || SectionIndex == -1ULL)
+ return;
+ ArrayRef<SectionName> SectionNames = Obj.getSectionNames();
+ const auto &SecRef = SectionNames[SectionIndex];
+
+ OS << " \"" << SecRef.Name << '\"';
+
+ // Print section index if name is not unique.
+ if (!SecRef.IsNameUnique)
+ OS << format(" [%" PRIu64 "]", SectionIndex);
+}
+
+void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
+ uint64_t UValue = Value.uval;
+ bool CURelativeOffset = false;
+ raw_ostream &AddrOS = DumpOpts.ShowAddresses
+ ? WithColor(OS, HighlightColor::Address).get()
+ : nulls();
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
+ switch (Form) {
+ case DW_FORM_addr:
+ dumpSectionedAddress(AddrOS, DumpOpts, {Value.uval, Value.SectionIndex});
+ break;
+ case DW_FORM_addrx:
+ case DW_FORM_addrx1:
+ case DW_FORM_addrx2:
+ case DW_FORM_addrx3:
+ case DW_FORM_addrx4:
+ case DW_FORM_GNU_addr_index: {
+ 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 (A)
+ dumpSectionedAddress(AddrOS, DumpOpts, *A);
+ else
+ OS << "<unresolved>";
+ break;
+ }
+ case DW_FORM_flag_present:
+ OS << "true";
+ break;
+ case DW_FORM_flag:
+ case DW_FORM_data1:
+ OS << format("0x%02x", (uint8_t)UValue);
+ break;
+ case DW_FORM_data2:
+ OS << format("0x%04x", (uint16_t)UValue);
+ break;
+ case DW_FORM_data4:
+ OS << format("0x%08x", (uint32_t)UValue);
+ break;
+ case DW_FORM_ref_sig8:
+ AddrOS << format("0x%016" PRIx64, UValue);
+ break;
+ case DW_FORM_data8:
+ OS << format("0x%016" PRIx64, UValue);
+ break;
+ case DW_FORM_data16:
+ OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), None, 16, 16);
+ break;
+ case DW_FORM_string:
+ OS << '"';
+ OS.write_escaped(Value.cstr);
+ OS << '"';
+ break;
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ case DW_FORM_block1:
+ case DW_FORM_block2:
+ case DW_FORM_block4:
+ if (UValue > 0) {
+ switch (Form) {
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ AddrOS << format("<0x%" PRIx64 "> ", UValue);
+ break;
+ case DW_FORM_block1:
+ AddrOS << format("<0x%2.2x> ", (uint8_t)UValue);
+ break;
+ case DW_FORM_block2:
+ AddrOS << format("<0x%4.4x> ", (uint16_t)UValue);
+ break;
+ case DW_FORM_block4:
+ AddrOS << format("<0x%8.8x> ", (uint32_t)UValue);
+ break;
+ default:
+ break;
+ }
+
+ const uint8_t *DataPtr = Value.data;
+ if (DataPtr) {
+ // UValue contains size of block
+ const uint8_t *EndDataPtr = DataPtr + UValue;
+ while (DataPtr < EndDataPtr) {
+ AddrOS << format("%2.2x ", *DataPtr);
+ ++DataPtr;
+ }
+ } else
+ OS << "NULL";
+ }
+ break;
+
+ case DW_FORM_sdata:
case DW_FORM_implicit_const:
- OS << Value.sval;
- break;
- case DW_FORM_udata:
- OS << Value.uval;
- break;
- case DW_FORM_strp:
- if (DumpOpts.Verbose)
- OS << format(" .debug_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, UValue);
- dumpString(OS);
- break;
- case DW_FORM_line_strp:
- if (DumpOpts.Verbose)
- OS << format(" .debug_line_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth,
- UValue);
- dumpString(OS);
- break;
- case DW_FORM_strx:
- case DW_FORM_strx1:
- case DW_FORM_strx2:
- case DW_FORM_strx3:
- case DW_FORM_strx4:
- case DW_FORM_GNU_str_index:
- if (DumpOpts.Verbose)
- OS << format("indexed (%8.8x) string = ", (uint32_t)UValue);
- dumpString(OS);
- break;
- case DW_FORM_GNU_strp_alt:
- if (DumpOpts.Verbose)
- OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
- dumpString(OS);
- break;
- case DW_FORM_ref_addr:
- AddrOS << format("0x%016" PRIx64, UValue);
- break;
- case DW_FORM_ref1:
- CURelativeOffset = true;
- if (DumpOpts.Verbose)
- AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
- break;
- case DW_FORM_ref2:
- CURelativeOffset = true;
- if (DumpOpts.Verbose)
- AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
- break;
- case DW_FORM_ref4:
- CURelativeOffset = true;
- if (DumpOpts.Verbose)
- AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
- break;
- case DW_FORM_ref8:
- CURelativeOffset = true;
- if (DumpOpts.Verbose)
- AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
- break;
- case DW_FORM_ref_udata:
- CURelativeOffset = true;
- if (DumpOpts.Verbose)
- AddrOS << format("cu + 0x%" PRIx64, UValue);
- break;
- case DW_FORM_GNU_ref_alt:
- AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
- break;
-
- // All DW_FORM_indirect attributes should be resolved prior to calling
- // this function
- case DW_FORM_indirect:
- OS << "DW_FORM_indirect";
- break;
-
- case DW_FORM_rnglistx:
- OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue);
- break;
-
- case DW_FORM_loclistx:
- OS << format("indexed (0x%x) loclist = ", (uint32_t)UValue);
- break;
-
- case DW_FORM_sec_offset:
- AddrOS << format("0x%0*" PRIx64, OffsetDumpWidth, UValue);
- break;
-
- default:
- OS << format("DW_FORM(0x%4.4x)", Form);
- break;
- }
-
- if (CURelativeOffset) {
- if (DumpOpts.Verbose)
- OS << " => {";
- if (DumpOpts.ShowAddresses)
- WithColor(OS, HighlightColor::Address).get()
- << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
- if (DumpOpts.Verbose)
- OS << "}";
- }
-}
-
-void DWARFFormValue::dumpString(raw_ostream &OS) const {
- Optional<const char *> DbgStr = getAsCString();
- if (DbgStr.hasValue()) {
- auto COS = WithColor(OS, HighlightColor::String);
- COS.get() << '"';
- COS.get().write_escaped(DbgStr.getValue());
- COS.get() << '"';
- }
-}
-
-Optional<const char *> DWARFFormValue::getAsCString() const {
- if (!isFormClass(FC_String))
- return None;
- if (Form == DW_FORM_string)
- return Value.cstr;
- // FIXME: Add support for DW_FORM_GNU_strp_alt
- if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
- return None;
- uint64_t Offset = Value.uval;
- if (Form == DW_FORM_line_strp) {
- // .debug_line_str is tracked in the Context.
- if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
- return Str;
- return None;
- }
- if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
- Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
- Form == DW_FORM_strx4) {
- if (!U)
- return None;
- Optional<uint64_t> StrOffset = U->getStringOffsetSectionItem(Offset);
- if (!StrOffset)
- return None;
- Offset = *StrOffset;
- }
- // Prefer the Unit's string extractor, because for .dwo it will point to
- // .debug_str.dwo, while the Context's extractor always uses .debug_str.
- if (U) {
- if (const char *Str = U->getStringExtractor().getCStr(&Offset))
- return Str;
- return None;
- }
- if (const char *Str = C->getStringExtractor().getCStr(&Offset))
- return Str;
- return None;
-}
-
-Optional<uint64_t> DWARFFormValue::getAsAddress() const {
- if (auto SA = getAsSectionedAddress())
- return SA->Address;
- return None;
-}
-
-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<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
- if (!SA)
- return None;
- return SA;
- }
- return {{Value.uval, Value.SectionIndex}};
-}
-
-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) {
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata:
- if (!U)
- return None;
- 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 UnitOffset{nullptr, Value.uval};
- default:
- return None;
- }
-}
-
-Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
- if (!isFormClass(FC_SectionOffset))
- return None;
- return Value.uval;
-}
-
-Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
- if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
- Form == DW_FORM_sdata)
- return None;
- return Value.uval;
-}
-
-Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
- if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
- (Form == DW_FORM_udata &&
- uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
- return None;
- switch (Form) {
- case DW_FORM_data4:
- return int32_t(Value.uval);
- case DW_FORM_data2:
- return int16_t(Value.uval);
- case DW_FORM_data1:
- return int8_t(Value.uval);
- case DW_FORM_sdata:
- case DW_FORM_data8:
- default:
- return Value.sval;
- }
-}
-
-Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
- if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
- Form != DW_FORM_data16)
- return None;
- return makeArrayRef(Value.data, Value.uval);
-}
-
-Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
- if (!isFormClass(FC_String) && Form == DW_FORM_string)
- return None;
- return Value.uval;
-}
-
-Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
- if (!isFormClass(FC_Reference))
- return None;
- return Value.uval;
-}
+ OS << Value.sval;
+ break;
+ case DW_FORM_udata:
+ OS << Value.uval;
+ break;
+ case DW_FORM_strp:
+ if (DumpOpts.Verbose)
+ OS << format(" .debug_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, UValue);
+ dumpString(OS);
+ break;
+ case DW_FORM_line_strp:
+ if (DumpOpts.Verbose)
+ OS << format(" .debug_line_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth,
+ UValue);
+ dumpString(OS);
+ break;
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
+ case DW_FORM_GNU_str_index:
+ if (DumpOpts.Verbose)
+ OS << format("indexed (%8.8x) string = ", (uint32_t)UValue);
+ dumpString(OS);
+ break;
+ case DW_FORM_GNU_strp_alt:
+ if (DumpOpts.Verbose)
+ OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
+ dumpString(OS);
+ break;
+ case DW_FORM_ref_addr:
+ AddrOS << format("0x%016" PRIx64, UValue);
+ break;
+ case DW_FORM_ref1:
+ CURelativeOffset = true;
+ if (DumpOpts.Verbose)
+ AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
+ break;
+ case DW_FORM_ref2:
+ CURelativeOffset = true;
+ if (DumpOpts.Verbose)
+ AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
+ break;
+ case DW_FORM_ref4:
+ CURelativeOffset = true;
+ if (DumpOpts.Verbose)
+ AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
+ break;
+ case DW_FORM_ref8:
+ CURelativeOffset = true;
+ if (DumpOpts.Verbose)
+ AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
+ break;
+ case DW_FORM_ref_udata:
+ CURelativeOffset = true;
+ if (DumpOpts.Verbose)
+ AddrOS << format("cu + 0x%" PRIx64, UValue);
+ break;
+ case DW_FORM_GNU_ref_alt:
+ AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
+ break;
+
+ // All DW_FORM_indirect attributes should be resolved prior to calling
+ // this function
+ case DW_FORM_indirect:
+ OS << "DW_FORM_indirect";
+ break;
+
+ case DW_FORM_rnglistx:
+ OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue);
+ break;
+
+ case DW_FORM_loclistx:
+ OS << format("indexed (0x%x) loclist = ", (uint32_t)UValue);
+ break;
+
+ case DW_FORM_sec_offset:
+ AddrOS << format("0x%0*" PRIx64, OffsetDumpWidth, UValue);
+ break;
+
+ default:
+ OS << format("DW_FORM(0x%4.4x)", Form);
+ break;
+ }
+
+ if (CURelativeOffset) {
+ if (DumpOpts.Verbose)
+ OS << " => {";
+ if (DumpOpts.ShowAddresses)
+ WithColor(OS, HighlightColor::Address).get()
+ << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
+ if (DumpOpts.Verbose)
+ OS << "}";
+ }
+}
+
+void DWARFFormValue::dumpString(raw_ostream &OS) const {
+ Optional<const char *> DbgStr = getAsCString();
+ if (DbgStr.hasValue()) {
+ auto COS = WithColor(OS, HighlightColor::String);
+ COS.get() << '"';
+ COS.get().write_escaped(DbgStr.getValue());
+ COS.get() << '"';
+ }
+}
+
+Optional<const char *> DWARFFormValue::getAsCString() const {
+ if (!isFormClass(FC_String))
+ return None;
+ if (Form == DW_FORM_string)
+ return Value.cstr;
+ // FIXME: Add support for DW_FORM_GNU_strp_alt
+ if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
+ return None;
+ uint64_t Offset = Value.uval;
+ if (Form == DW_FORM_line_strp) {
+ // .debug_line_str is tracked in the Context.
+ if (const char *Str = C->getLineStringExtractor().getCStr(&Offset))
+ return Str;
+ return None;
+ }
+ if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
+ Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
+ Form == DW_FORM_strx4) {
+ if (!U)
+ return None;
+ Optional<uint64_t> StrOffset = U->getStringOffsetSectionItem(Offset);
+ if (!StrOffset)
+ return None;
+ Offset = *StrOffset;
+ }
+ // Prefer the Unit's string extractor, because for .dwo it will point to
+ // .debug_str.dwo, while the Context's extractor always uses .debug_str.
+ if (U) {
+ if (const char *Str = U->getStringExtractor().getCStr(&Offset))
+ return Str;
+ return None;
+ }
+ if (const char *Str = C->getStringExtractor().getCStr(&Offset))
+ return Str;
+ return None;
+}
+
+Optional<uint64_t> DWARFFormValue::getAsAddress() const {
+ if (auto SA = getAsSectionedAddress())
+ return SA->Address;
+ return None;
+}
+
+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<object::SectionedAddress> SA = U->getAddrOffsetSectionItem(Index);
+ if (!SA)
+ return None;
+ return SA;
+ }
+ return {{Value.uval, Value.SectionIndex}};
+}
+
+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) {
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata:
+ if (!U)
+ return None;
+ 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 UnitOffset{nullptr, Value.uval};
+ default:
+ return None;
+ }
+}
+
+Optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
+ if (!isFormClass(FC_SectionOffset))
+ return None;
+ return Value.uval;
+}
+
+Optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
+ if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
+ Form == DW_FORM_sdata)
+ return None;
+ return Value.uval;
+}
+
+Optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
+ if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
+ (Form == DW_FORM_udata &&
+ uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
+ return None;
+ switch (Form) {
+ case DW_FORM_data4:
+ return int32_t(Value.uval);
+ case DW_FORM_data2:
+ return int16_t(Value.uval);
+ case DW_FORM_data1:
+ return int8_t(Value.uval);
+ case DW_FORM_sdata:
+ case DW_FORM_data8:
+ default:
+ return Value.sval;
+ }
+}
+
+Optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
+ if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
+ Form != DW_FORM_data16)
+ return None;
+ return makeArrayRef(Value.data, Value.uval);
+}
+
+Optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
+ if (!isFormClass(FC_String) && Form == DW_FORM_string)
+ return None;
+ return Value.uval;
+}
+
+Optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
+ if (!isFormClass(FC_Reference))
+ return None;
+ return Value.uval;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
index ace7000f07..b6ed48642e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFGdbIndex.cpp
@@ -1,199 +1,199 @@
-//===- DWARFGdbIndex.cpp --------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/raw_ostream.h"
-#include <algorithm>
-#include <cassert>
-#include <cinttypes>
-#include <cstdint>
-#include <utility>
-
-using namespace llvm;
-
-// .gdb_index section format reference:
-// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
-
-void DWARFGdbIndex::dumpCUList(raw_ostream &OS) const {
- OS << format("\n CU list offset = 0x%x, has %" PRId64 " entries:",
- CuListOffset, (uint64_t)CuList.size())
- << '\n';
- uint32_t I = 0;
- for (const CompUnitEntry &CU : CuList)
- OS << format(" %d: Offset = 0x%llx, Length = 0x%llx\n", I++, CU.Offset,
- CU.Length);
-}
-
-void DWARFGdbIndex::dumpTUList(raw_ostream &OS) const {
- OS << formatv("\n Types CU list offset = {0:x}, has {1} entries:\n",
- TuListOffset, TuList.size());
- uint32_t I = 0;
- for (const TypeUnitEntry &TU : TuList)
- OS << formatv(" {0}: offset = {1:x8}, type_offset = {2:x8}, "
- "type_signature = {3:x16}\n",
- I++, TU.Offset, TU.TypeOffset, TU.TypeSignature);
-}
-
-void DWARFGdbIndex::dumpAddressArea(raw_ostream &OS) const {
- OS << format("\n Address area offset = 0x%x, has %" PRId64 " entries:",
- AddressAreaOffset, (uint64_t)AddressArea.size())
- << '\n';
- for (const AddressEntry &Addr : AddressArea)
- OS << format(
- " Low/High address = [0x%llx, 0x%llx) (Size: 0x%llx), CU id = %d\n",
- Addr.LowAddress, Addr.HighAddress, Addr.HighAddress - Addr.LowAddress,
- Addr.CuIndex);
-}
-
-void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
- OS << format("\n Symbol table offset = 0x%x, size = %" PRId64
- ", filled slots:",
- SymbolTableOffset, (uint64_t)SymbolTable.size())
- << '\n';
- uint32_t I = -1;
- for (const SymTableEntry &E : SymbolTable) {
- ++I;
- if (!E.NameOffset && !E.VecOffset)
- continue;
-
- OS << format(" %d: Name offset = 0x%x, CU vector offset = 0x%x\n", I,
- E.NameOffset, E.VecOffset);
-
- StringRef Name = ConstantPoolStrings.substr(
- ConstantPoolOffset - StringPoolOffset + E.NameOffset);
-
+//===- DWARFGdbIndex.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cinttypes>
+#include <cstdint>
+#include <utility>
+
+using namespace llvm;
+
+// .gdb_index section format reference:
+// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html
+
+void DWARFGdbIndex::dumpCUList(raw_ostream &OS) const {
+ OS << format("\n CU list offset = 0x%x, has %" PRId64 " entries:",
+ CuListOffset, (uint64_t)CuList.size())
+ << '\n';
+ uint32_t I = 0;
+ for (const CompUnitEntry &CU : CuList)
+ OS << format(" %d: Offset = 0x%llx, Length = 0x%llx\n", I++, CU.Offset,
+ CU.Length);
+}
+
+void DWARFGdbIndex::dumpTUList(raw_ostream &OS) const {
+ OS << formatv("\n Types CU list offset = {0:x}, has {1} entries:\n",
+ TuListOffset, TuList.size());
+ uint32_t I = 0;
+ for (const TypeUnitEntry &TU : TuList)
+ OS << formatv(" {0}: offset = {1:x8}, type_offset = {2:x8}, "
+ "type_signature = {3:x16}\n",
+ I++, TU.Offset, TU.TypeOffset, TU.TypeSignature);
+}
+
+void DWARFGdbIndex::dumpAddressArea(raw_ostream &OS) const {
+ OS << format("\n Address area offset = 0x%x, has %" PRId64 " entries:",
+ AddressAreaOffset, (uint64_t)AddressArea.size())
+ << '\n';
+ for (const AddressEntry &Addr : AddressArea)
+ OS << format(
+ " Low/High address = [0x%llx, 0x%llx) (Size: 0x%llx), CU id = %d\n",
+ Addr.LowAddress, Addr.HighAddress, Addr.HighAddress - Addr.LowAddress,
+ Addr.CuIndex);
+}
+
+void DWARFGdbIndex::dumpSymbolTable(raw_ostream &OS) const {
+ OS << format("\n Symbol table offset = 0x%x, size = %" PRId64
+ ", filled slots:",
+ SymbolTableOffset, (uint64_t)SymbolTable.size())
+ << '\n';
+ uint32_t I = -1;
+ for (const SymTableEntry &E : SymbolTable) {
+ ++I;
+ if (!E.NameOffset && !E.VecOffset)
+ continue;
+
+ OS << format(" %d: Name offset = 0x%x, CU vector offset = 0x%x\n", I,
+ E.NameOffset, E.VecOffset);
+
+ StringRef Name = ConstantPoolStrings.substr(
+ ConstantPoolOffset - StringPoolOffset + E.NameOffset);
+
auto CuVector = llvm::find_if(
ConstantPoolVectors,
- [&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
- return V.first == E.VecOffset;
- });
- assert(CuVector != ConstantPoolVectors.end() && "Invalid symbol table");
- uint32_t CuVectorId = CuVector - ConstantPoolVectors.begin();
- OS << format(" String name: %s, CU vector index: %d\n", Name.data(),
- CuVectorId);
- }
-}
-
-void DWARFGdbIndex::dumpConstantPool(raw_ostream &OS) const {
- OS << format("\n Constant pool offset = 0x%x, has %" PRId64 " CU vectors:",
- ConstantPoolOffset, (uint64_t)ConstantPoolVectors.size());
- uint32_t I = 0;
- for (const auto &V : ConstantPoolVectors) {
- OS << format("\n %d(0x%x): ", I++, V.first);
- for (uint32_t Val : V.second)
- OS << format("0x%x ", Val);
- }
- OS << '\n';
-}
-
-void DWARFGdbIndex::dump(raw_ostream &OS) {
- if (HasError) {
- OS << "\n<error parsing>\n";
- return;
- }
-
- if (HasContent) {
- OS << " Version = " << Version << '\n';
- dumpCUList(OS);
- dumpTUList(OS);
- dumpAddressArea(OS);
- dumpSymbolTable(OS);
- dumpConstantPool(OS);
- }
-}
-
-bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
- uint64_t Offset = 0;
-
- // Only version 7 is supported at this moment.
- Version = Data.getU32(&Offset);
- if (Version != 7)
- return false;
-
- CuListOffset = Data.getU32(&Offset);
- TuListOffset = Data.getU32(&Offset);
- AddressAreaOffset = Data.getU32(&Offset);
- SymbolTableOffset = Data.getU32(&Offset);
- ConstantPoolOffset = Data.getU32(&Offset);
-
- if (Offset != CuListOffset)
- return false;
-
- uint32_t CuListSize = (TuListOffset - CuListOffset) / 16;
- CuList.reserve(CuListSize);
- for (uint32_t i = 0; i < CuListSize; ++i) {
- uint64_t CuOffset = Data.getU64(&Offset);
- uint64_t CuLength = Data.getU64(&Offset);
- CuList.push_back({CuOffset, CuLength});
- }
-
- // CU Types are no longer needed as DWARF skeleton type units never made it
- // into the standard.
- uint32_t TuListSize = (AddressAreaOffset - TuListOffset) / 24;
- TuList.resize(TuListSize);
- for (uint32_t I = 0; I < TuListSize; ++I) {
- uint64_t CuOffset = Data.getU64(&Offset);
- uint64_t TypeOffset = Data.getU64(&Offset);
- uint64_t Signature = Data.getU64(&Offset);
- TuList[I] = {CuOffset, TypeOffset, Signature};
- }
-
- uint32_t AddressAreaSize = (SymbolTableOffset - AddressAreaOffset) / 20;
- AddressArea.reserve(AddressAreaSize);
- for (uint32_t i = 0; i < AddressAreaSize; ++i) {
- uint64_t LowAddress = Data.getU64(&Offset);
- uint64_t HighAddress = Data.getU64(&Offset);
- uint32_t CuIndex = Data.getU32(&Offset);
- AddressArea.push_back({LowAddress, HighAddress, CuIndex});
- }
-
- // The symbol table. This is an open addressed hash table. The size of the
- // hash table is always a power of 2.
- // Each slot in the hash table consists of a pair of offset_type values. The
- // first value is the offset of the symbol's name in the constant pool. The
- // second value is the offset of the CU vector in the constant pool.
- // If both values are 0, then this slot in the hash table is empty. This is ok
- // because while 0 is a valid constant pool index, it cannot be a valid index
- // for both a string and a CU vector.
- uint32_t SymTableSize = (ConstantPoolOffset - SymbolTableOffset) / 8;
- SymbolTable.reserve(SymTableSize);
- uint32_t CuVectorsTotal = 0;
- for (uint32_t i = 0; i < SymTableSize; ++i) {
- uint32_t NameOffset = Data.getU32(&Offset);
- uint32_t CuVecOffset = Data.getU32(&Offset);
- SymbolTable.push_back({NameOffset, CuVecOffset});
- if (NameOffset || CuVecOffset)
- ++CuVectorsTotal;
- }
-
- // The constant pool. CU vectors are stored first, followed by strings.
- // The first value is the number of CU indices in the vector. Each subsequent
- // value is the index and symbol attributes of a CU in the CU list.
- for (uint32_t i = 0; i < CuVectorsTotal; ++i) {
- ConstantPoolVectors.emplace_back(0, SmallVector<uint32_t, 0>());
- auto &Vec = ConstantPoolVectors.back();
- Vec.first = Offset - ConstantPoolOffset;
-
- uint32_t Num = Data.getU32(&Offset);
- for (uint32_t j = 0; j < Num; ++j)
- Vec.second.push_back(Data.getU32(&Offset));
- }
-
- ConstantPoolStrings = Data.getData().drop_front(Offset);
- StringPoolOffset = Offset;
- return true;
-}
-
-void DWARFGdbIndex::parse(DataExtractor Data) {
- HasContent = !Data.getData().empty();
- HasError = HasContent && !parseImpl(Data);
-}
+ [&](const std::pair<uint32_t, SmallVector<uint32_t, 0>> &V) {
+ return V.first == E.VecOffset;
+ });
+ assert(CuVector != ConstantPoolVectors.end() && "Invalid symbol table");
+ uint32_t CuVectorId = CuVector - ConstantPoolVectors.begin();
+ OS << format(" String name: %s, CU vector index: %d\n", Name.data(),
+ CuVectorId);
+ }
+}
+
+void DWARFGdbIndex::dumpConstantPool(raw_ostream &OS) const {
+ OS << format("\n Constant pool offset = 0x%x, has %" PRId64 " CU vectors:",
+ ConstantPoolOffset, (uint64_t)ConstantPoolVectors.size());
+ uint32_t I = 0;
+ for (const auto &V : ConstantPoolVectors) {
+ OS << format("\n %d(0x%x): ", I++, V.first);
+ for (uint32_t Val : V.second)
+ OS << format("0x%x ", Val);
+ }
+ OS << '\n';
+}
+
+void DWARFGdbIndex::dump(raw_ostream &OS) {
+ if (HasError) {
+ OS << "\n<error parsing>\n";
+ return;
+ }
+
+ if (HasContent) {
+ OS << " Version = " << Version << '\n';
+ dumpCUList(OS);
+ dumpTUList(OS);
+ dumpAddressArea(OS);
+ dumpSymbolTable(OS);
+ dumpConstantPool(OS);
+ }
+}
+
+bool DWARFGdbIndex::parseImpl(DataExtractor Data) {
+ uint64_t Offset = 0;
+
+ // Only version 7 is supported at this moment.
+ Version = Data.getU32(&Offset);
+ if (Version != 7)
+ return false;
+
+ CuListOffset = Data.getU32(&Offset);
+ TuListOffset = Data.getU32(&Offset);
+ AddressAreaOffset = Data.getU32(&Offset);
+ SymbolTableOffset = Data.getU32(&Offset);
+ ConstantPoolOffset = Data.getU32(&Offset);
+
+ if (Offset != CuListOffset)
+ return false;
+
+ uint32_t CuListSize = (TuListOffset - CuListOffset) / 16;
+ CuList.reserve(CuListSize);
+ for (uint32_t i = 0; i < CuListSize; ++i) {
+ uint64_t CuOffset = Data.getU64(&Offset);
+ uint64_t CuLength = Data.getU64(&Offset);
+ CuList.push_back({CuOffset, CuLength});
+ }
+
+ // CU Types are no longer needed as DWARF skeleton type units never made it
+ // into the standard.
+ uint32_t TuListSize = (AddressAreaOffset - TuListOffset) / 24;
+ TuList.resize(TuListSize);
+ for (uint32_t I = 0; I < TuListSize; ++I) {
+ uint64_t CuOffset = Data.getU64(&Offset);
+ uint64_t TypeOffset = Data.getU64(&Offset);
+ uint64_t Signature = Data.getU64(&Offset);
+ TuList[I] = {CuOffset, TypeOffset, Signature};
+ }
+
+ uint32_t AddressAreaSize = (SymbolTableOffset - AddressAreaOffset) / 20;
+ AddressArea.reserve(AddressAreaSize);
+ for (uint32_t i = 0; i < AddressAreaSize; ++i) {
+ uint64_t LowAddress = Data.getU64(&Offset);
+ uint64_t HighAddress = Data.getU64(&Offset);
+ uint32_t CuIndex = Data.getU32(&Offset);
+ AddressArea.push_back({LowAddress, HighAddress, CuIndex});
+ }
+
+ // The symbol table. This is an open addressed hash table. The size of the
+ // hash table is always a power of 2.
+ // Each slot in the hash table consists of a pair of offset_type values. The
+ // first value is the offset of the symbol's name in the constant pool. The
+ // second value is the offset of the CU vector in the constant pool.
+ // If both values are 0, then this slot in the hash table is empty. This is ok
+ // because while 0 is a valid constant pool index, it cannot be a valid index
+ // for both a string and a CU vector.
+ uint32_t SymTableSize = (ConstantPoolOffset - SymbolTableOffset) / 8;
+ SymbolTable.reserve(SymTableSize);
+ uint32_t CuVectorsTotal = 0;
+ for (uint32_t i = 0; i < SymTableSize; ++i) {
+ uint32_t NameOffset = Data.getU32(&Offset);
+ uint32_t CuVecOffset = Data.getU32(&Offset);
+ SymbolTable.push_back({NameOffset, CuVecOffset});
+ if (NameOffset || CuVecOffset)
+ ++CuVectorsTotal;
+ }
+
+ // The constant pool. CU vectors are stored first, followed by strings.
+ // The first value is the number of CU indices in the vector. Each subsequent
+ // value is the index and symbol attributes of a CU in the CU list.
+ for (uint32_t i = 0; i < CuVectorsTotal; ++i) {
+ ConstantPoolVectors.emplace_back(0, SmallVector<uint32_t, 0>());
+ auto &Vec = ConstantPoolVectors.back();
+ Vec.first = Offset - ConstantPoolOffset;
+
+ uint32_t Num = Data.getU32(&Offset);
+ for (uint32_t j = 0; j < Num; ++j)
+ Vec.second.push_back(Data.getU32(&Offset));
+ }
+
+ ConstantPoolStrings = Data.getData().drop_front(Offset);
+ StringPoolOffset = Offset;
+ return true;
+}
+
+void DWARFGdbIndex::parse(DataExtractor Data) {
+ HasContent = !Data.getData().empty();
+ HasError = HasContent && !parseImpl(Data);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp
index c876af1e9b..9aa07dd451 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFListTable.cpp
@@ -1,109 +1,109 @@
-//===- DWARFListTable.cpp ---------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
-#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-
-Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
- uint64_t *OffsetPtr) {
- HeaderOffset = *OffsetPtr;
- Error Err = Error::success();
-
- std::tie(HeaderData.Length, Format) = Data.getInitialLength(OffsetPtr, &Err);
- if (Err)
- return createStringError(
- errc::invalid_argument, "parsing %s table at offset 0x%" PRIx64 ": %s",
- SectionName.data(), HeaderOffset, toString(std::move(Err)).c_str());
-
- uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4;
- uint64_t FullLength =
- HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
- if (FullLength < getHeaderSize(Format))
- return createStringError(errc::invalid_argument,
- "%s table at offset 0x%" PRIx64
- " has too small length (0x%" PRIx64
- ") to contain a complete header",
- SectionName.data(), HeaderOffset, FullLength);
- assert(FullLength == length() && "Inconsistent calculation of length.");
- uint64_t End = HeaderOffset + FullLength;
- if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))
- return createStringError(errc::invalid_argument,
- "section is not large enough to contain a %s table "
- "of length 0x%" PRIx64 " at offset 0x%" PRIx64,
- SectionName.data(), FullLength, HeaderOffset);
-
- HeaderData.Version = Data.getU16(OffsetPtr);
- HeaderData.AddrSize = Data.getU8(OffsetPtr);
- HeaderData.SegSize = Data.getU8(OffsetPtr);
- HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr);
-
- // Perform basic validation of the remaining header fields.
- if (HeaderData.Version != 5)
- return createStringError(errc::invalid_argument,
- "unrecognised %s table version %" PRIu16
- " in table at offset 0x%" PRIx64,
- SectionName.data(), HeaderData.Version, HeaderOffset);
- if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
- return createStringError(errc::not_supported,
- "%s table at offset 0x%" PRIx64
- " has unsupported address size %" PRIu8,
- SectionName.data(), HeaderOffset, HeaderData.AddrSize);
- if (HeaderData.SegSize != 0)
- return createStringError(errc::not_supported,
- "%s table at offset 0x%" PRIx64
- " has unsupported segment selector size %" PRIu8,
- SectionName.data(), HeaderOffset, HeaderData.SegSize);
- if (End < HeaderOffset + getHeaderSize(Format) +
- HeaderData.OffsetEntryCount * OffsetByteSize)
- return createStringError(errc::invalid_argument,
- "%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32
- ") than there is space for",
- SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
- Data.setAddressSize(HeaderData.AddrSize);
+//===- DWARFListTable.cpp ---------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFListTable.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+Error DWARFListTableHeader::extract(DWARFDataExtractor Data,
+ uint64_t *OffsetPtr) {
+ HeaderOffset = *OffsetPtr;
+ Error Err = Error::success();
+
+ std::tie(HeaderData.Length, Format) = Data.getInitialLength(OffsetPtr, &Err);
+ if (Err)
+ return createStringError(
+ errc::invalid_argument, "parsing %s table at offset 0x%" PRIx64 ": %s",
+ SectionName.data(), HeaderOffset, toString(std::move(Err)).c_str());
+
+ uint8_t OffsetByteSize = Format == dwarf::DWARF64 ? 8 : 4;
+ uint64_t FullLength =
+ HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
+ if (FullLength < getHeaderSize(Format))
+ return createStringError(errc::invalid_argument,
+ "%s table at offset 0x%" PRIx64
+ " has too small length (0x%" PRIx64
+ ") to contain a complete header",
+ SectionName.data(), HeaderOffset, FullLength);
+ assert(FullLength == length() && "Inconsistent calculation of length.");
+ uint64_t End = HeaderOffset + FullLength;
+ if (!Data.isValidOffsetForDataOfSize(HeaderOffset, FullLength))
+ return createStringError(errc::invalid_argument,
+ "section is not large enough to contain a %s table "
+ "of length 0x%" PRIx64 " at offset 0x%" PRIx64,
+ SectionName.data(), FullLength, HeaderOffset);
+
+ HeaderData.Version = Data.getU16(OffsetPtr);
+ HeaderData.AddrSize = Data.getU8(OffsetPtr);
+ HeaderData.SegSize = Data.getU8(OffsetPtr);
+ HeaderData.OffsetEntryCount = Data.getU32(OffsetPtr);
+
+ // Perform basic validation of the remaining header fields.
+ if (HeaderData.Version != 5)
+ return createStringError(errc::invalid_argument,
+ "unrecognised %s table version %" PRIu16
+ " in table at offset 0x%" PRIx64,
+ SectionName.data(), HeaderData.Version, HeaderOffset);
+ if (HeaderData.AddrSize != 4 && HeaderData.AddrSize != 8)
+ return createStringError(errc::not_supported,
+ "%s table at offset 0x%" PRIx64
+ " has unsupported address size %" PRIu8,
+ SectionName.data(), HeaderOffset, HeaderData.AddrSize);
+ if (HeaderData.SegSize != 0)
+ return createStringError(errc::not_supported,
+ "%s table at offset 0x%" PRIx64
+ " has unsupported segment selector size %" PRIu8,
+ SectionName.data(), HeaderOffset, HeaderData.SegSize);
+ if (End < HeaderOffset + getHeaderSize(Format) +
+ HeaderData.OffsetEntryCount * OffsetByteSize)
+ return createStringError(errc::invalid_argument,
+ "%s table at offset 0x%" PRIx64 " has more offset entries (%" PRIu32
+ ") than there is space for",
+ SectionName.data(), HeaderOffset, HeaderData.OffsetEntryCount);
+ Data.setAddressSize(HeaderData.AddrSize);
*OffsetPtr += HeaderData.OffsetEntryCount * OffsetByteSize;
- return Error::success();
-}
-
+ return Error::success();
+}
+
void DWARFListTableHeader::dump(DataExtractor Data, raw_ostream &OS,
DIDumpOptions DumpOpts) const {
- if (DumpOpts.Verbose)
- OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
- OS << format("%s list header: length = 0x%0*" PRIx64, ListTypeString.data(),
- OffsetDumpWidth, HeaderData.Length)
- << ", format = " << dwarf::FormatString(Format)
- << format(", version = 0x%4.4" PRIx16 ", addr_size = 0x%2.2" PRIx8
- ", seg_size = 0x%2.2" PRIx8
- ", offset_entry_count = 0x%8.8" PRIx32 "\n",
- HeaderData.Version, HeaderData.AddrSize, HeaderData.SegSize,
- HeaderData.OffsetEntryCount);
-
- if (HeaderData.OffsetEntryCount > 0) {
- OS << "offsets: [";
+ if (DumpOpts.Verbose)
+ OS << format("0x%8.8" PRIx64 ": ", HeaderOffset);
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
+ OS << format("%s list header: length = 0x%0*" PRIx64, ListTypeString.data(),
+ OffsetDumpWidth, HeaderData.Length)
+ << ", format = " << dwarf::FormatString(Format)
+ << format(", version = 0x%4.4" PRIx16 ", addr_size = 0x%2.2" PRIx8
+ ", seg_size = 0x%2.2" PRIx8
+ ", offset_entry_count = 0x%8.8" PRIx32 "\n",
+ HeaderData.Version, HeaderData.AddrSize, HeaderData.SegSize,
+ HeaderData.OffsetEntryCount);
+
+ if (HeaderData.OffsetEntryCount > 0) {
+ OS << "offsets: [";
for (uint32_t I = 0; I < HeaderData.OffsetEntryCount; ++I) {
auto Off = *getOffsetEntry(Data, I);
- OS << format("\n0x%0*" PRIx64, OffsetDumpWidth, Off);
- if (DumpOpts.Verbose)
- OS << format(" => 0x%08" PRIx64,
- Off + HeaderOffset + getHeaderSize(Format));
- }
- OS << "\n]\n";
- }
-}
-
-uint64_t DWARFListTableHeader::length() const {
- if (HeaderData.Length == 0)
- return 0;
- return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
-}
+ OS << format("\n0x%0*" PRIx64, OffsetDumpWidth, Off);
+ if (DumpOpts.Verbose)
+ OS << format(" => 0x%08" PRIx64,
+ Off + HeaderOffset + getHeaderSize(Format));
+ }
+ OS << "\n]\n";
+ }
+}
+
+uint64_t DWARFListTableHeader::length() const {
+ if (HeaderData.Length == 0)
+ return 0;
+ return HeaderData.Length + dwarf::getUnitLengthFieldByteSize(Format);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp
index 1cf73a6667..880d3c2c68 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFLocationExpression.cpp
@@ -1,19 +1,19 @@
-//===- DWARFLocationExpression.cpp ----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/Support/FormatVariadic.h"
-
-using namespace llvm;
-
-raw_ostream &llvm::operator<<(raw_ostream &OS,
- const DWARFLocationExpression &Loc) {
- return OS << Loc.Range << ": "
- << formatv("{0}", make_range(Loc.Expr.begin(), Loc.Expr.end()));
-}
+//===- DWARFLocationExpression.cpp ----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+
+raw_ostream &llvm::operator<<(raw_ostream &OS,
+ const DWARFLocationExpression &Loc) {
+ return OS << Loc.Range << ": "
+ << formatv("{0}", make_range(Loc.Expr.begin(), Loc.Expr.end()));
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
index a301b65dd4..307494a0c1 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFTypeUnit.cpp
@@ -1,53 +1,53 @@
-//===- DWARFTypeUnit.cpp --------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
-#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cinttypes>
-
-using namespace llvm;
-
-void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
- DWARFDie TD = getDIEForOffset(getTypeOffset() + getOffset());
- const char *Name = TD.getName(DINameKind::ShortName);
- int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(getFormat());
-
- if (DumpOpts.SummarizeTypes) {
- OS << "name = '" << Name << "'"
- << ", type_signature = " << format("0x%016" PRIx64, getTypeHash())
- << ", length = " << format("0x%0*" PRIx64, OffsetDumpWidth, getLength())
- << '\n';
- return;
- }
-
- OS << format("0x%08" PRIx64, getOffset()) << ": Type Unit:"
- << " length = " << format("0x%0*" PRIx64, OffsetDumpWidth, getLength())
- << ", format = " << dwarf::FormatString(getFormat())
- << ", version = " << format("0x%04x", getVersion());
- if (getVersion() >= 5)
- OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
+//===- DWARFTypeUnit.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cinttypes>
+
+using namespace llvm;
+
+void DWARFTypeUnit::dump(raw_ostream &OS, DIDumpOptions DumpOpts) {
+ DWARFDie TD = getDIEForOffset(getTypeOffset() + getOffset());
+ const char *Name = TD.getName(DINameKind::ShortName);
+ int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(getFormat());
+
+ if (DumpOpts.SummarizeTypes) {
+ OS << "name = '" << Name << "'"
+ << ", type_signature = " << format("0x%016" PRIx64, getTypeHash())
+ << ", length = " << format("0x%0*" PRIx64, OffsetDumpWidth, getLength())
+ << '\n';
+ return;
+ }
+
+ OS << format("0x%08" PRIx64, getOffset()) << ": Type Unit:"
+ << " length = " << format("0x%0*" PRIx64, OffsetDumpWidth, getLength())
+ << ", format = " << dwarf::FormatString(getFormat())
+ << ", version = " << format("0x%04x", getVersion());
+ if (getVersion() >= 5)
+ OS << ", unit_type = " << dwarf::UnitTypeString(getUnitType());
OS << ", abbr_offset = " << format("0x%04" PRIx64, getAbbrOffset());
if (!getAbbreviations())
OS << " (invalid)";
OS << ", addr_size = " << format("0x%02x", getAddressByteSize())
- << ", name = '" << Name << "'"
- << ", type_signature = " << format("0x%016" PRIx64, getTypeHash())
- << ", type_offset = " << format("0x%04" PRIx64, getTypeOffset())
- << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
- << ")\n";
-
- if (DWARFDie TU = getUnitDIE(false))
- TU.dump(OS, 0, DumpOpts);
- else
- OS << "<type unit can't be parsed!>\n\n";
-}
+ << ", name = '" << Name << "'"
+ << ", type_signature = " << format("0x%016" PRIx64, getTypeHash())
+ << ", type_offset = " << format("0x%04" PRIx64, getTypeOffset())
+ << " (next unit at " << format("0x%08" PRIx64, getNextUnitOffset())
+ << ")\n";
+
+ if (DWARFDie TU = getUnitDIE(false))
+ TU.dump(OS, 0, DumpOpts);
+ else
+ OS << "<type unit can't be parsed!>\n\n";
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 8493950a29..7268cbd4ab 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -1,487 +1,487 @@
-//===- DWARFUnit.cpp ------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
-#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
-#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
-#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/Path.h"
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-#include <cstdio>
-#include <utility>
-#include <vector>
-
-using namespace llvm;
-using namespace dwarf;
-
-void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
- const DWARFSection &Section,
- DWARFSectionKind SectionKind) {
- const DWARFObject &D = C.getDWARFObj();
- addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
- &D.getLocSection(), D.getStrSection(),
- D.getStrOffsetsSection(), &D.getAddrSection(),
- D.getLineSection(), D.isLittleEndian(), false, false,
- SectionKind);
-}
-
-void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
- const DWARFSection &DWOSection,
- DWARFSectionKind SectionKind,
- bool Lazy) {
- const DWARFObject &D = C.getDWARFObj();
- addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
- &D.getLocDWOSection(), D.getStrDWOSection(),
- D.getStrOffsetsDWOSection(), &D.getAddrSection(),
- D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
- SectionKind);
-}
-
-void DWARFUnitVector::addUnitsImpl(
- DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
- const DWARFDebugAbbrev *DA, const DWARFSection *RS,
- const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
- const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
- bool Lazy, DWARFSectionKind SectionKind) {
- DWARFDataExtractor Data(Obj, Section, LE, 0);
- // Lazy initialization of Parser, now that we have all section info.
- if (!Parser) {
- Parser = [=, &Context, &Obj, &Section, &SOS,
- &LS](uint64_t Offset, DWARFSectionKind SectionKind,
- const DWARFSection *CurSection,
- const DWARFUnitIndex::Entry *IndexEntry)
- -> std::unique_ptr<DWARFUnit> {
- const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
- DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
- if (!Data.isValidOffset(Offset))
- return nullptr;
- DWARFUnitHeader Header;
- if (!Header.extract(Context, Data, &Offset, SectionKind))
- return nullptr;
- if (!IndexEntry && IsDWO) {
- const DWARFUnitIndex &Index = getDWARFUnitIndex(
- Context, Header.isTypeUnit() ? DW_SECT_EXT_TYPES : DW_SECT_INFO);
- IndexEntry = Index.getFromOffset(Header.getOffset());
- }
- if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
- return nullptr;
- std::unique_ptr<DWARFUnit> U;
- if (Header.isTypeUnit())
- U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
- RS, LocSection, SS, SOS, AOS, LS,
- LE, IsDWO, *this);
- else
- U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
- DA, RS, LocSection, SS, SOS,
- AOS, LS, LE, IsDWO, *this);
- return U;
- };
- }
- if (Lazy)
- return;
- // Find a reasonable insertion point within the vector. We skip over
- // (a) units from a different section, (b) units from the same section
- // but with lower offset-within-section. This keeps units in order
- // within a section, although not necessarily within the object file,
- // even if we do lazy parsing.
- auto I = this->begin();
- uint64_t Offset = 0;
- while (Data.isValidOffset(Offset)) {
- if (I != this->end() &&
- (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
- ++I;
- continue;
- }
- auto U = Parser(Offset, SectionKind, &Section, nullptr);
- // If parsing failed, we're done with this section.
- if (!U)
- break;
- Offset = U->getNextUnitOffset();
- I = std::next(this->insert(I, std::move(U)));
- }
-}
-
-DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
- auto I = std::upper_bound(begin(), end(), Unit,
- [](const std::unique_ptr<DWARFUnit> &LHS,
- const std::unique_ptr<DWARFUnit> &RHS) {
- return LHS->getOffset() < RHS->getOffset();
- });
- return this->insert(I, std::move(Unit))->get();
-}
-
-DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const {
- auto end = begin() + getNumInfoUnits();
- auto *CU =
- std::upper_bound(begin(), end, Offset,
- [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
- return LHS < RHS->getNextUnitOffset();
- });
- if (CU != end && (*CU)->getOffset() <= Offset)
- return CU->get();
- return nullptr;
-}
-
-DWARFUnit *
-DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
- const auto *CUOff = E.getContribution(DW_SECT_INFO);
- if (!CUOff)
- return nullptr;
-
- auto Offset = CUOff->Offset;
- auto end = begin() + getNumInfoUnits();
-
- auto *CU =
- std::upper_bound(begin(), end, CUOff->Offset,
- [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
- return LHS < RHS->getNextUnitOffset();
- });
- if (CU != end && (*CU)->getOffset() <= Offset)
- return CU->get();
-
- if (!Parser)
- return nullptr;
-
- auto U = Parser(Offset, DW_SECT_INFO, nullptr, &E);
- if (!U)
- U = nullptr;
-
- auto *NewCU = U.get();
- this->insert(CU, std::move(U));
- ++NumInfoUnits;
- return NewCU;
-}
-
-DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
- const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
- const DWARFSection *RS, const DWARFSection *LocSection,
- StringRef SS, const DWARFSection &SOS,
- const DWARFSection *AOS, const DWARFSection &LS, bool LE,
- bool IsDWO, const DWARFUnitVector &UnitVector)
- : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
- RangeSection(RS), LineSection(LS), StringSection(SS),
- StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
- IsDWO(IsDWO), UnitVector(UnitVector) {
- clear();
-}
-
-DWARFUnit::~DWARFUnit() = default;
-
-DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
- return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
- getAddressByteSize());
-}
-
-Optional<object::SectionedAddress>
-DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
- if (IsDWO) {
- auto R = Context.info_section_units();
- // Surprising if a DWO file has more than one skeleton unit in it - this
- // probably shouldn't be valid, but if a use case is found, here's where to
- // support it (probably have to linearly search for the matching skeleton CU
- // here)
+//===- DWARFUnit.cpp ------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFUnit.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/DWARF/DWARFAbbreviationDeclaration.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFTypeUnit.h"
+#include "llvm/Support/DataExtractor.h"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/Path.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <cstdio>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+
+void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
+ const DWARFSection &Section,
+ DWARFSectionKind SectionKind) {
+ const DWARFObject &D = C.getDWARFObj();
+ addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangesSection(),
+ &D.getLocSection(), D.getStrSection(),
+ D.getStrOffsetsSection(), &D.getAddrSection(),
+ D.getLineSection(), D.isLittleEndian(), false, false,
+ SectionKind);
+}
+
+void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
+ const DWARFSection &DWOSection,
+ DWARFSectionKind SectionKind,
+ bool Lazy) {
+ const DWARFObject &D = C.getDWARFObj();
+ addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangesDWOSection(),
+ &D.getLocDWOSection(), D.getStrDWOSection(),
+ D.getStrOffsetsDWOSection(), &D.getAddrSection(),
+ D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
+ SectionKind);
+}
+
+void DWARFUnitVector::addUnitsImpl(
+ DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
+ const DWARFDebugAbbrev *DA, const DWARFSection *RS,
+ const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
+ const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
+ bool Lazy, DWARFSectionKind SectionKind) {
+ DWARFDataExtractor Data(Obj, Section, LE, 0);
+ // Lazy initialization of Parser, now that we have all section info.
+ if (!Parser) {
+ Parser = [=, &Context, &Obj, &Section, &SOS,
+ &LS](uint64_t Offset, DWARFSectionKind SectionKind,
+ const DWARFSection *CurSection,
+ const DWARFUnitIndex::Entry *IndexEntry)
+ -> std::unique_ptr<DWARFUnit> {
+ const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
+ DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
+ if (!Data.isValidOffset(Offset))
+ return nullptr;
+ DWARFUnitHeader Header;
+ if (!Header.extract(Context, Data, &Offset, SectionKind))
+ return nullptr;
+ if (!IndexEntry && IsDWO) {
+ const DWARFUnitIndex &Index = getDWARFUnitIndex(
+ Context, Header.isTypeUnit() ? DW_SECT_EXT_TYPES : DW_SECT_INFO);
+ IndexEntry = Index.getFromOffset(Header.getOffset());
+ }
+ if (IndexEntry && !Header.applyIndexEntry(IndexEntry))
+ return nullptr;
+ std::unique_ptr<DWARFUnit> U;
+ if (Header.isTypeUnit())
+ U = std::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
+ RS, LocSection, SS, SOS, AOS, LS,
+ LE, IsDWO, *this);
+ else
+ U = std::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
+ DA, RS, LocSection, SS, SOS,
+ AOS, LS, LE, IsDWO, *this);
+ return U;
+ };
+ }
+ if (Lazy)
+ return;
+ // Find a reasonable insertion point within the vector. We skip over
+ // (a) units from a different section, (b) units from the same section
+ // but with lower offset-within-section. This keeps units in order
+ // within a section, although not necessarily within the object file,
+ // even if we do lazy parsing.
+ auto I = this->begin();
+ uint64_t Offset = 0;
+ while (Data.isValidOffset(Offset)) {
+ if (I != this->end() &&
+ (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
+ ++I;
+ continue;
+ }
+ auto U = Parser(Offset, SectionKind, &Section, nullptr);
+ // If parsing failed, we're done with this section.
+ if (!U)
+ break;
+ Offset = U->getNextUnitOffset();
+ I = std::next(this->insert(I, std::move(U)));
+ }
+}
+
+DWARFUnit *DWARFUnitVector::addUnit(std::unique_ptr<DWARFUnit> Unit) {
+ auto I = std::upper_bound(begin(), end(), Unit,
+ [](const std::unique_ptr<DWARFUnit> &LHS,
+ const std::unique_ptr<DWARFUnit> &RHS) {
+ return LHS->getOffset() < RHS->getOffset();
+ });
+ return this->insert(I, std::move(Unit))->get();
+}
+
+DWARFUnit *DWARFUnitVector::getUnitForOffset(uint64_t Offset) const {
+ auto end = begin() + getNumInfoUnits();
+ auto *CU =
+ std::upper_bound(begin(), end, Offset,
+ [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+ return LHS < RHS->getNextUnitOffset();
+ });
+ if (CU != end && (*CU)->getOffset() <= Offset)
+ return CU->get();
+ return nullptr;
+}
+
+DWARFUnit *
+DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
+ const auto *CUOff = E.getContribution(DW_SECT_INFO);
+ if (!CUOff)
+ return nullptr;
+
+ auto Offset = CUOff->Offset;
+ auto end = begin() + getNumInfoUnits();
+
+ auto *CU =
+ std::upper_bound(begin(), end, CUOff->Offset,
+ [](uint64_t LHS, const std::unique_ptr<DWARFUnit> &RHS) {
+ return LHS < RHS->getNextUnitOffset();
+ });
+ if (CU != end && (*CU)->getOffset() <= Offset)
+ return CU->get();
+
+ if (!Parser)
+ return nullptr;
+
+ auto U = Parser(Offset, DW_SECT_INFO, nullptr, &E);
+ if (!U)
+ U = nullptr;
+
+ auto *NewCU = U.get();
+ this->insert(CU, std::move(U));
+ ++NumInfoUnits;
+ return NewCU;
+}
+
+DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
+ const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
+ const DWARFSection *RS, const DWARFSection *LocSection,
+ StringRef SS, const DWARFSection &SOS,
+ const DWARFSection *AOS, const DWARFSection &LS, bool LE,
+ bool IsDWO, const DWARFUnitVector &UnitVector)
+ : Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
+ RangeSection(RS), LineSection(LS), StringSection(SS),
+ StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
+ IsDWO(IsDWO), UnitVector(UnitVector) {
+ clear();
+}
+
+DWARFUnit::~DWARFUnit() = default;
+
+DWARFDataExtractor DWARFUnit::getDebugInfoExtractor() const {
+ return DWARFDataExtractor(Context.getDWARFObj(), InfoSection, isLittleEndian,
+ getAddressByteSize());
+}
+
+Optional<object::SectionedAddress>
+DWARFUnit::getAddrOffsetSectionItem(uint32_t Index) const {
+ if (IsDWO) {
+ auto R = Context.info_section_units();
+ // Surprising if a DWO file has more than one skeleton unit in it - this
+ // probably shouldn't be valid, but if a use case is found, here's where to
+ // support it (probably have to linearly search for the matching skeleton CU
+ // here)
if (hasSingleElement(R))
return (*R.begin())->getAddrOffsetSectionItem(Index);
- }
- if (!AddrOffsetSectionBase)
- return None;
- uint64_t Offset = *AddrOffsetSectionBase + Index * getAddressByteSize();
- if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
- return None;
- DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
- isLittleEndian, getAddressByteSize());
- uint64_t Section;
- uint64_t Address = DA.getRelocatedAddress(&Offset, &Section);
- return {{Address, Section}};
-}
-
-Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
- if (!StringOffsetsTableContribution)
- return None;
- unsigned ItemSize = getDwarfStringOffsetsByteSize();
- uint64_t Offset = getStringOffsetsBase() + Index * ItemSize;
- if (StringOffsetSection.Data.size() < Offset + ItemSize)
- return None;
- DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
- isLittleEndian, 0);
- return DA.getRelocatedValue(ItemSize, &Offset);
-}
-
-bool DWARFUnitHeader::extract(DWARFContext &Context,
- const DWARFDataExtractor &debug_info,
- uint64_t *offset_ptr,
- DWARFSectionKind SectionKind) {
- Offset = *offset_ptr;
- Error Err = Error::success();
- IndexEntry = nullptr;
- std::tie(Length, FormParams.Format) =
- debug_info.getInitialLength(offset_ptr, &Err);
- FormParams.Version = debug_info.getU16(offset_ptr, &Err);
- if (FormParams.Version >= 5) {
- UnitType = debug_info.getU8(offset_ptr, &Err);
- FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
- AbbrOffset = debug_info.getRelocatedValue(
- FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
- } else {
- AbbrOffset = debug_info.getRelocatedValue(
- FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
- FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
- // Fake a unit type based on the section type. This isn't perfect,
- // but distinguishing compile and type units is generally enough.
- if (SectionKind == DW_SECT_EXT_TYPES)
- UnitType = DW_UT_type;
- else
- UnitType = DW_UT_compile;
- }
- if (isTypeUnit()) {
- TypeHash = debug_info.getU64(offset_ptr, &Err);
- TypeOffset = debug_info.getUnsigned(
- offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);
- } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
- DWOId = debug_info.getU64(offset_ptr, &Err);
-
- if (errorToBool(std::move(Err)))
- return false;
-
- // Header fields all parsed, capture the size of this unit header.
- assert(*offset_ptr - Offset <= 255 && "unexpected header size");
- Size = uint8_t(*offset_ptr - Offset);
-
- // Type offset is unit-relative; should be after the header and before
- // the end of the current unit.
- bool TypeOffsetOK =
- !isTypeUnit()
- ? true
- : TypeOffset >= Size &&
- TypeOffset < getLength() + getUnitLengthFieldByteSize();
- bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
- bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
- bool AddrSizeOK = DWARFContext::isAddressSizeSupported(getAddressByteSize());
-
- if (!LengthOK || !VersionOK || !AddrSizeOK || !TypeOffsetOK)
- return false;
-
- // Keep track of the highest DWARF version we encounter across all units.
- Context.setMaxVersionIfGreater(getVersion());
- return true;
-}
-
-bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
- assert(Entry);
- assert(!IndexEntry);
- IndexEntry = Entry;
- if (AbbrOffset)
- return false;
- auto *UnitContrib = IndexEntry->getContribution();
- if (!UnitContrib ||
- UnitContrib->Length != (getLength() + getUnitLengthFieldByteSize()))
- return false;
- auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
- if (!AbbrEntry)
- return false;
- AbbrOffset = AbbrEntry->Offset;
- return true;
-}
-
-// Parse the rangelist table header, including the optional array of offsets
-// following it (DWARF v5 and later).
-template<typename ListTableType>
-static Expected<ListTableType>
-parseListTableHeader(DWARFDataExtractor &DA, uint64_t Offset,
- DwarfFormat Format) {
- // We are expected to be called with Offset 0 or pointing just past the table
- // header. Correct Offset in the latter case so that it points to the start
- // of the header.
- if (Offset > 0) {
- uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Format);
- if (Offset < HeaderSize)
- return createStringError(errc::invalid_argument, "did not detect a valid"
- " list table with base = 0x%" PRIx64 "\n",
- Offset);
- Offset -= HeaderSize;
- }
- ListTableType Table;
- if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))
- return std::move(E);
- return Table;
-}
-
-Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
- DWARFDebugRangeList &RangeList) const {
- // Require that compile unit is extracted.
- assert(!DieArray.empty());
- DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
- isLittleEndian, getAddressByteSize());
- uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
- return RangeList.extract(RangesData, &ActualRangeListOffset);
-}
-
-void DWARFUnit::clear() {
- Abbrevs = nullptr;
- BaseAddr.reset();
- RangeSectionBase = 0;
- LocSectionBase = 0;
- AddrOffsetSectionBase = None;
- clearDIEs(false);
- DWO.reset();
-}
-
-const char *DWARFUnit::getCompilationDir() {
- return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
-}
-
-void DWARFUnit::extractDIEsToVector(
- bool AppendCUDie, bool AppendNonCUDies,
- std::vector<DWARFDebugInfoEntry> &Dies) const {
- if (!AppendCUDie && !AppendNonCUDies)
- return;
-
- // Set the offset to that of the first DIE and calculate the start of the
- // next compilation unit header.
- uint64_t DIEOffset = getOffset() + getHeaderSize();
- uint64_t NextCUOffset = getNextUnitOffset();
- DWARFDebugInfoEntry DIE;
- DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
- uint32_t Depth = 0;
- bool IsCUDie = true;
-
- while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
- Depth)) {
- if (IsCUDie) {
- if (AppendCUDie)
- Dies.push_back(DIE);
- if (!AppendNonCUDies)
- break;
- // The average bytes per DIE entry has been seen to be
- // around 14-20 so let's pre-reserve the needed memory for
- // our DIE entries accordingly.
- Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
- IsCUDie = false;
- } else {
- Dies.push_back(DIE);
- }
-
- if (const DWARFAbbreviationDeclaration *AbbrDecl =
- DIE.getAbbreviationDeclarationPtr()) {
- // Normal DIE
- if (AbbrDecl->hasChildren())
- ++Depth;
- } else {
- // NULL DIE.
- if (Depth > 0)
- --Depth;
- if (Depth == 0)
- break; // We are done with this compile unit!
- }
- }
-
- // Give a little bit of info if we encounter corrupt DWARF (our offset
- // should always terminate at or before the start of the next compilation
- // unit header).
- if (DIEOffset > NextCUOffset)
- Context.getWarningHandler()(
- createStringError(errc::invalid_argument,
- "DWARF compile unit extends beyond its "
- "bounds cu 0x%8.8" PRIx64 " "
- "at 0x%8.8" PRIx64 "\n",
- getOffset(), DIEOffset));
-}
-
-void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
- if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
- Context.getRecoverableErrorHandler()(std::move(e));
-}
-
-Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
- if ((CUDieOnly && !DieArray.empty()) ||
- DieArray.size() > 1)
- return Error::success(); // Already parsed.
-
- bool HasCUDie = !DieArray.empty();
- extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
-
- if (DieArray.empty())
- return Error::success();
-
- // If CU DIE was just parsed, copy several attribute values from it.
- if (HasCUDie)
- return Error::success();
-
- DWARFDie UnitDie(this, &DieArray[0]);
- if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
- Header.setDWOId(*DWOId);
- if (!IsDWO) {
- assert(AddrOffsetSectionBase == None);
- assert(RangeSectionBase == 0);
- assert(LocSectionBase == 0);
- AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
- if (!AddrOffsetSectionBase)
- AddrOffsetSectionBase =
- toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
- RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
- LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
- }
-
- // In general, in DWARF v5 and beyond we derive the start of the unit's
- // contribution to the string offsets table from the unit DIE's
- // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
- // attribute, so we assume that there is a contribution to the string
- // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
- // In both cases we need to determine the format of the contribution,
- // which may differ from the unit's format.
- DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
- isLittleEndian, 0);
- if (IsDWO || getVersion() >= 5) {
- auto StringOffsetOrError =
- IsDWO ? determineStringOffsetsTableContributionDWO(DA)
- : determineStringOffsetsTableContribution(DA);
- if (!StringOffsetOrError)
- return createStringError(errc::invalid_argument,
- "invalid reference to or invalid content in "
- ".debug_str_offsets[.dwo]: " +
- toString(StringOffsetOrError.takeError()));
-
- StringOffsetsTableContribution = *StringOffsetOrError;
- }
-
- // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
- // describe address ranges.
- if (getVersion() >= 5) {
- // In case of DWP, the base offset from the index has to be added.
- if (IsDWO) {
+ }
+ if (!AddrOffsetSectionBase)
+ return None;
+ uint64_t Offset = *AddrOffsetSectionBase + Index * getAddressByteSize();
+ if (AddrOffsetSection->Data.size() < Offset + getAddressByteSize())
+ return None;
+ DWARFDataExtractor DA(Context.getDWARFObj(), *AddrOffsetSection,
+ isLittleEndian, getAddressByteSize());
+ uint64_t Section;
+ uint64_t Address = DA.getRelocatedAddress(&Offset, &Section);
+ return {{Address, Section}};
+}
+
+Optional<uint64_t> DWARFUnit::getStringOffsetSectionItem(uint32_t Index) const {
+ if (!StringOffsetsTableContribution)
+ return None;
+ unsigned ItemSize = getDwarfStringOffsetsByteSize();
+ uint64_t Offset = getStringOffsetsBase() + Index * ItemSize;
+ if (StringOffsetSection.Data.size() < Offset + ItemSize)
+ return None;
+ DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+ isLittleEndian, 0);
+ return DA.getRelocatedValue(ItemSize, &Offset);
+}
+
+bool DWARFUnitHeader::extract(DWARFContext &Context,
+ const DWARFDataExtractor &debug_info,
+ uint64_t *offset_ptr,
+ DWARFSectionKind SectionKind) {
+ Offset = *offset_ptr;
+ Error Err = Error::success();
+ IndexEntry = nullptr;
+ std::tie(Length, FormParams.Format) =
+ debug_info.getInitialLength(offset_ptr, &Err);
+ FormParams.Version = debug_info.getU16(offset_ptr, &Err);
+ if (FormParams.Version >= 5) {
+ UnitType = debug_info.getU8(offset_ptr, &Err);
+ FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
+ AbbrOffset = debug_info.getRelocatedValue(
+ FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
+ } else {
+ AbbrOffset = debug_info.getRelocatedValue(
+ FormParams.getDwarfOffsetByteSize(), offset_ptr, nullptr, &Err);
+ FormParams.AddrSize = debug_info.getU8(offset_ptr, &Err);
+ // Fake a unit type based on the section type. This isn't perfect,
+ // but distinguishing compile and type units is generally enough.
+ if (SectionKind == DW_SECT_EXT_TYPES)
+ UnitType = DW_UT_type;
+ else
+ UnitType = DW_UT_compile;
+ }
+ if (isTypeUnit()) {
+ TypeHash = debug_info.getU64(offset_ptr, &Err);
+ TypeOffset = debug_info.getUnsigned(
+ offset_ptr, FormParams.getDwarfOffsetByteSize(), &Err);
+ } else if (UnitType == DW_UT_split_compile || UnitType == DW_UT_skeleton)
+ DWOId = debug_info.getU64(offset_ptr, &Err);
+
+ if (errorToBool(std::move(Err)))
+ return false;
+
+ // Header fields all parsed, capture the size of this unit header.
+ assert(*offset_ptr - Offset <= 255 && "unexpected header size");
+ Size = uint8_t(*offset_ptr - Offset);
+
+ // Type offset is unit-relative; should be after the header and before
+ // the end of the current unit.
+ bool TypeOffsetOK =
+ !isTypeUnit()
+ ? true
+ : TypeOffset >= Size &&
+ TypeOffset < getLength() + getUnitLengthFieldByteSize();
+ bool LengthOK = debug_info.isValidOffset(getNextUnitOffset() - 1);
+ bool VersionOK = DWARFContext::isSupportedVersion(getVersion());
+ bool AddrSizeOK = DWARFContext::isAddressSizeSupported(getAddressByteSize());
+
+ if (!LengthOK || !VersionOK || !AddrSizeOK || !TypeOffsetOK)
+ return false;
+
+ // Keep track of the highest DWARF version we encounter across all units.
+ Context.setMaxVersionIfGreater(getVersion());
+ return true;
+}
+
+bool DWARFUnitHeader::applyIndexEntry(const DWARFUnitIndex::Entry *Entry) {
+ assert(Entry);
+ assert(!IndexEntry);
+ IndexEntry = Entry;
+ if (AbbrOffset)
+ return false;
+ auto *UnitContrib = IndexEntry->getContribution();
+ if (!UnitContrib ||
+ UnitContrib->Length != (getLength() + getUnitLengthFieldByteSize()))
+ return false;
+ auto *AbbrEntry = IndexEntry->getContribution(DW_SECT_ABBREV);
+ if (!AbbrEntry)
+ return false;
+ AbbrOffset = AbbrEntry->Offset;
+ return true;
+}
+
+// Parse the rangelist table header, including the optional array of offsets
+// following it (DWARF v5 and later).
+template<typename ListTableType>
+static Expected<ListTableType>
+parseListTableHeader(DWARFDataExtractor &DA, uint64_t Offset,
+ DwarfFormat Format) {
+ // We are expected to be called with Offset 0 or pointing just past the table
+ // header. Correct Offset in the latter case so that it points to the start
+ // of the header.
+ if (Offset > 0) {
+ uint64_t HeaderSize = DWARFListTableHeader::getHeaderSize(Format);
+ if (Offset < HeaderSize)
+ return createStringError(errc::invalid_argument, "did not detect a valid"
+ " list table with base = 0x%" PRIx64 "\n",
+ Offset);
+ Offset -= HeaderSize;
+ }
+ ListTableType Table;
+ if (Error E = Table.extractHeaderAndOffsets(DA, &Offset))
+ return std::move(E);
+ return Table;
+}
+
+Error DWARFUnit::extractRangeList(uint64_t RangeListOffset,
+ DWARFDebugRangeList &RangeList) const {
+ // Require that compile unit is extracted.
+ assert(!DieArray.empty());
+ DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
+ isLittleEndian, getAddressByteSize());
+ uint64_t ActualRangeListOffset = RangeSectionBase + RangeListOffset;
+ return RangeList.extract(RangesData, &ActualRangeListOffset);
+}
+
+void DWARFUnit::clear() {
+ Abbrevs = nullptr;
+ BaseAddr.reset();
+ RangeSectionBase = 0;
+ LocSectionBase = 0;
+ AddrOffsetSectionBase = None;
+ clearDIEs(false);
+ DWO.reset();
+}
+
+const char *DWARFUnit::getCompilationDir() {
+ return dwarf::toString(getUnitDIE().find(DW_AT_comp_dir), nullptr);
+}
+
+void DWARFUnit::extractDIEsToVector(
+ bool AppendCUDie, bool AppendNonCUDies,
+ std::vector<DWARFDebugInfoEntry> &Dies) const {
+ if (!AppendCUDie && !AppendNonCUDies)
+ return;
+
+ // Set the offset to that of the first DIE and calculate the start of the
+ // next compilation unit header.
+ uint64_t DIEOffset = getOffset() + getHeaderSize();
+ uint64_t NextCUOffset = getNextUnitOffset();
+ DWARFDebugInfoEntry DIE;
+ DWARFDataExtractor DebugInfoData = getDebugInfoExtractor();
+ uint32_t Depth = 0;
+ bool IsCUDie = true;
+
+ while (DIE.extractFast(*this, &DIEOffset, DebugInfoData, NextCUOffset,
+ Depth)) {
+ if (IsCUDie) {
+ if (AppendCUDie)
+ Dies.push_back(DIE);
+ if (!AppendNonCUDies)
+ break;
+ // The average bytes per DIE entry has been seen to be
+ // around 14-20 so let's pre-reserve the needed memory for
+ // our DIE entries accordingly.
+ Dies.reserve(Dies.size() + getDebugInfoSize() / 14);
+ IsCUDie = false;
+ } else {
+ Dies.push_back(DIE);
+ }
+
+ if (const DWARFAbbreviationDeclaration *AbbrDecl =
+ DIE.getAbbreviationDeclarationPtr()) {
+ // Normal DIE
+ if (AbbrDecl->hasChildren())
+ ++Depth;
+ } else {
+ // NULL DIE.
+ if (Depth > 0)
+ --Depth;
+ if (Depth == 0)
+ break; // We are done with this compile unit!
+ }
+ }
+
+ // Give a little bit of info if we encounter corrupt DWARF (our offset
+ // should always terminate at or before the start of the next compilation
+ // unit header).
+ if (DIEOffset > NextCUOffset)
+ Context.getWarningHandler()(
+ createStringError(errc::invalid_argument,
+ "DWARF compile unit extends beyond its "
+ "bounds cu 0x%8.8" PRIx64 " "
+ "at 0x%8.8" PRIx64 "\n",
+ getOffset(), DIEOffset));
+}
+
+void DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
+ if (Error e = tryExtractDIEsIfNeeded(CUDieOnly))
+ Context.getRecoverableErrorHandler()(std::move(e));
+}
+
+Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
+ if ((CUDieOnly && !DieArray.empty()) ||
+ DieArray.size() > 1)
+ return Error::success(); // Already parsed.
+
+ bool HasCUDie = !DieArray.empty();
+ extractDIEsToVector(!HasCUDie, !CUDieOnly, DieArray);
+
+ if (DieArray.empty())
+ return Error::success();
+
+ // If CU DIE was just parsed, copy several attribute values from it.
+ if (HasCUDie)
+ return Error::success();
+
+ DWARFDie UnitDie(this, &DieArray[0]);
+ if (Optional<uint64_t> DWOId = toUnsigned(UnitDie.find(DW_AT_GNU_dwo_id)))
+ Header.setDWOId(*DWOId);
+ if (!IsDWO) {
+ assert(AddrOffsetSectionBase == None);
+ assert(RangeSectionBase == 0);
+ assert(LocSectionBase == 0);
+ AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_addr_base));
+ if (!AddrOffsetSectionBase)
+ AddrOffsetSectionBase =
+ toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base));
+ RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
+ LocSectionBase = toSectionOffset(UnitDie.find(DW_AT_loclists_base), 0);
+ }
+
+ // In general, in DWARF v5 and beyond we derive the start of the unit's
+ // contribution to the string offsets table from the unit DIE's
+ // DW_AT_str_offsets_base attribute. Split DWARF units do not use this
+ // attribute, so we assume that there is a contribution to the string
+ // offsets table starting at offset 0 of the debug_str_offsets.dwo section.
+ // In both cases we need to determine the format of the contribution,
+ // which may differ from the unit's format.
+ DWARFDataExtractor DA(Context.getDWARFObj(), StringOffsetSection,
+ isLittleEndian, 0);
+ if (IsDWO || getVersion() >= 5) {
+ auto StringOffsetOrError =
+ IsDWO ? determineStringOffsetsTableContributionDWO(DA)
+ : determineStringOffsetsTableContribution(DA);
+ if (!StringOffsetOrError)
+ return createStringError(errc::invalid_argument,
+ "invalid reference to or invalid content in "
+ ".debug_str_offsets[.dwo]: " +
+ toString(StringOffsetOrError.takeError()));
+
+ StringOffsetsTableContribution = *StringOffsetOrError;
+ }
+
+ // DWARF v5 uses the .debug_rnglists and .debug_rnglists.dwo sections to
+ // describe address ranges.
+ if (getVersion() >= 5) {
+ // In case of DWP, the base offset from the index has to be added.
+ if (IsDWO) {
uint64_t ContributionBaseOffset = 0;
- if (auto *IndexEntry = Header.getIndexEntry())
- if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
- ContributionBaseOffset = Contrib->Offset;
- setRangesSection(
- &Context.getDWARFObj().getRnglistsDWOSection(),
- ContributionBaseOffset +
- DWARFListTableHeader::getHeaderSize(Header.getFormat()));
- } else
- setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
+ if (auto *IndexEntry = Header.getIndexEntry())
+ if (auto *Contrib = IndexEntry->getContribution(DW_SECT_RNGLISTS))
+ ContributionBaseOffset = Contrib->Offset;
+ setRangesSection(
+ &Context.getDWARFObj().getRnglistsDWOSection(),
+ ContributionBaseOffset +
+ DWARFListTableHeader::getHeaderSize(Header.getFormat()));
+ } else
+ setRangesSection(&Context.getDWARFObj().getRnglistsSection(),
toSectionOffset(UnitDie.find(DW_AT_rnglists_base),
DWARFListTableHeader::getHeaderSize(
Header.getFormat())));
}
-
+
if (IsDWO) {
// If we are reading a package file, we need to adjust the location list
// data based on the index entries.
@@ -492,7 +492,7 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
if (const auto *C = IndexEntry->getContribution(
Header.getVersion() >= 5 ? DW_SECT_LOCLISTS : DW_SECT_EXT_LOC))
Data = Data.substr(C->Offset, C->Length);
-
+
DWARFDataExtractor DWARFData(Data, isLittleEndian, getAddressByteSize());
LocTable =
std::make_unique<DWARFDebugLoclists>(DWARFData, Header.getVersion());
@@ -507,73 +507,73 @@ Error DWARFUnit::tryExtractDIEsIfNeeded(bool CUDieOnly) {
LocTable = std::make_unique<DWARFDebugLoc>(DWARFDataExtractor(
Context.getDWARFObj(), Context.getDWARFObj().getLocSection(),
isLittleEndian, getAddressByteSize()));
- }
-
- // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
- // skeleton CU DIE, so that DWARF users not aware of it are not broken.
- return Error::success();
-}
-
-bool DWARFUnit::parseDWO() {
- if (IsDWO)
- return false;
- if (DWO.get())
- return false;
- DWARFDie UnitDie = getUnitDIE();
- if (!UnitDie)
- return false;
- auto DWOFileName = getVersion() >= 5
- ? dwarf::toString(UnitDie.find(DW_AT_dwo_name))
- : dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
- if (!DWOFileName)
- return false;
- auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
- SmallString<16> AbsolutePath;
- if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
- *CompilationDir) {
- sys::path::append(AbsolutePath, *CompilationDir);
- }
- sys::path::append(AbsolutePath, *DWOFileName);
- auto DWOId = getDWOId();
- if (!DWOId)
- return false;
- auto DWOContext = Context.getDWOContext(AbsolutePath);
- if (!DWOContext)
- return false;
-
- DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
- if (!DWOCU)
- return false;
- DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
- // Share .debug_addr and .debug_ranges section with compile unit in .dwo
- if (AddrOffsetSectionBase)
- DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
- if (getVersion() >= 5) {
+ }
+
+ // Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
+ // skeleton CU DIE, so that DWARF users not aware of it are not broken.
+ return Error::success();
+}
+
+bool DWARFUnit::parseDWO() {
+ if (IsDWO)
+ return false;
+ if (DWO.get())
+ return false;
+ DWARFDie UnitDie = getUnitDIE();
+ if (!UnitDie)
+ return false;
+ auto DWOFileName = getVersion() >= 5
+ ? dwarf::toString(UnitDie.find(DW_AT_dwo_name))
+ : dwarf::toString(UnitDie.find(DW_AT_GNU_dwo_name));
+ if (!DWOFileName)
+ return false;
+ auto CompilationDir = dwarf::toString(UnitDie.find(DW_AT_comp_dir));
+ SmallString<16> AbsolutePath;
+ if (sys::path::is_relative(*DWOFileName) && CompilationDir &&
+ *CompilationDir) {
+ sys::path::append(AbsolutePath, *CompilationDir);
+ }
+ sys::path::append(AbsolutePath, *DWOFileName);
+ auto DWOId = getDWOId();
+ if (!DWOId)
+ return false;
+ auto DWOContext = Context.getDWOContext(AbsolutePath);
+ if (!DWOContext)
+ return false;
+
+ DWARFCompileUnit *DWOCU = DWOContext->getDWOCompileUnitForHash(*DWOId);
+ if (!DWOCU)
+ return false;
+ DWO = std::shared_ptr<DWARFCompileUnit>(std::move(DWOContext), DWOCU);
+ // Share .debug_addr and .debug_ranges section with compile unit in .dwo
+ if (AddrOffsetSectionBase)
+ DWO->setAddrOffsetSection(AddrOffsetSection, *AddrOffsetSectionBase);
+ if (getVersion() >= 5) {
DWO->setRangesSection(&Context.getDWARFObj().getRnglistsDWOSection(),
DWARFListTableHeader::getHeaderSize(getFormat()));
- } else {
- auto DWORangesBase = UnitDie.getRangesBaseAttribute();
- DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
- }
-
- return true;
-}
-
-void DWARFUnit::clearDIEs(bool KeepCUDie) {
- if (DieArray.size() > (unsigned)KeepCUDie) {
- DieArray.resize((unsigned)KeepCUDie);
- DieArray.shrink_to_fit();
- }
-}
-
-Expected<DWARFAddressRangesVector>
-DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
- if (getVersion() <= 4) {
- DWARFDebugRangeList RangeList;
- if (Error E = extractRangeList(Offset, RangeList))
- return std::move(E);
- return RangeList.getAbsoluteRanges(getBaseAddress());
- }
+ } else {
+ auto DWORangesBase = UnitDie.getRangesBaseAttribute();
+ DWO->setRangesSection(RangeSection, DWORangesBase ? *DWORangesBase : 0);
+ }
+
+ return true;
+}
+
+void DWARFUnit::clearDIEs(bool KeepCUDie) {
+ if (DieArray.size() > (unsigned)KeepCUDie) {
+ DieArray.resize((unsigned)KeepCUDie);
+ DieArray.shrink_to_fit();
+ }
+}
+
+Expected<DWARFAddressRangesVector>
+DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
+ if (getVersion() <= 4) {
+ DWARFDebugRangeList RangeList;
+ if (Error E = extractRangeList(Offset, RangeList))
+ return std::move(E);
+ return RangeList.getAbsoluteRanges(getBaseAddress());
+ }
DWARFDataExtractor RangesData(Context.getDWARFObj(), *RangeSection,
isLittleEndian, Header.getAddressByteSize());
DWARFDebugRnglistTable RnglistTable;
@@ -581,348 +581,348 @@ DWARFUnit::findRnglistFromOffset(uint64_t Offset) {
if (RangeListOrError)
return RangeListOrError.get().getAbsoluteRanges(getBaseAddress(), *this);
return RangeListOrError.takeError();
-}
-
-Expected<DWARFAddressRangesVector>
-DWARFUnit::findRnglistFromIndex(uint32_t Index) {
- if (auto Offset = getRnglistOffset(Index))
- return findRnglistFromOffset(*Offset);
-
- return createStringError(errc::invalid_argument,
+}
+
+Expected<DWARFAddressRangesVector>
+DWARFUnit::findRnglistFromIndex(uint32_t Index) {
+ if (auto Offset = getRnglistOffset(Index))
+ return findRnglistFromOffset(*Offset);
+
+ return createStringError(errc::invalid_argument,
"invalid range list table index %d (possibly "
"missing the entire range list table)",
Index);
-}
-
-Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
- DWARFDie UnitDie = getUnitDIE();
- if (!UnitDie)
- return createStringError(errc::invalid_argument, "No unit DIE");
-
- // First, check if unit DIE describes address ranges for the whole unit.
- auto CUDIERangesOrError = UnitDie.getAddressRanges();
- if (!CUDIERangesOrError)
- return createStringError(errc::invalid_argument,
- "decoding address ranges: %s",
- toString(CUDIERangesOrError.takeError()).c_str());
- return *CUDIERangesOrError;
-}
-
-Expected<DWARFLocationExpressionsVector>
-DWARFUnit::findLoclistFromOffset(uint64_t Offset) {
- DWARFLocationExpressionsVector Result;
-
- Error InterpretationError = Error::success();
-
- Error ParseError = getLocationTable().visitAbsoluteLocationList(
- Offset, getBaseAddress(),
- [this](uint32_t Index) { return getAddrOffsetSectionItem(Index); },
- [&](Expected<DWARFLocationExpression> L) {
- if (L)
- Result.push_back(std::move(*L));
- else
- InterpretationError =
- joinErrors(L.takeError(), std::move(InterpretationError));
- return !InterpretationError;
- });
-
- if (ParseError || InterpretationError)
- return joinErrors(std::move(ParseError), std::move(InterpretationError));
-
- return Result;
-}
-
-void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
- if (Die.isSubroutineDIE()) {
- auto DIERangesOrError = Die.getAddressRanges();
- if (DIERangesOrError) {
- for (const auto &R : DIERangesOrError.get()) {
- // Ignore 0-sized ranges.
- if (R.LowPC == R.HighPC)
- continue;
- auto B = AddrDieMap.upper_bound(R.LowPC);
- if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
- // The range is a sub-range of existing ranges, we need to split the
- // existing range.
- if (R.HighPC < B->second.first)
- AddrDieMap[R.HighPC] = B->second;
- if (R.LowPC > B->first)
- AddrDieMap[B->first].first = R.LowPC;
- }
- AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
- }
- } else
- llvm::consumeError(DIERangesOrError.takeError());
- }
- // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
- // simplify the logic to update AddrDieMap. The child's range will always
- // be equal or smaller than the parent's range. With this assumption, when
- // adding one range into the map, it will at most split a range into 3
- // sub-ranges.
- for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
- updateAddressDieMap(Child);
-}
-
-DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
- extractDIEsIfNeeded(false);
- if (AddrDieMap.empty())
- updateAddressDieMap(getUnitDIE());
- auto R = AddrDieMap.upper_bound(Address);
- if (R == AddrDieMap.begin())
- return DWARFDie();
- // upper_bound's previous item contains Address.
- --R;
- if (Address >= R->second.first)
- return DWARFDie();
- return R->second.second;
-}
-
-void
-DWARFUnit::getInlinedChainForAddress(uint64_t Address,
- SmallVectorImpl<DWARFDie> &InlinedChain) {
- assert(InlinedChain.empty());
- // Try to look for subprogram DIEs in the DWO file.
- parseDWO();
- // First, find the subroutine that contains the given address (the leaf
- // of inlined chain).
- DWARFDie SubroutineDIE =
- (DWO ? *DWO : *this).getSubroutineForAddress(Address);
-
- if (!SubroutineDIE)
- return;
-
- while (!SubroutineDIE.isSubprogramDIE()) {
- if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
- InlinedChain.push_back(SubroutineDIE);
- SubroutineDIE = SubroutineDIE.getParent();
- }
- InlinedChain.push_back(SubroutineDIE);
-}
-
-const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
- DWARFSectionKind Kind) {
- if (Kind == DW_SECT_INFO)
- return Context.getCUIndex();
- assert(Kind == DW_SECT_EXT_TYPES);
- return Context.getTUIndex();
-}
-
-DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
- if (!Die)
- return DWARFDie();
- const uint32_t Depth = Die->getDepth();
- // Unit DIEs always have a depth of zero and never have parents.
- if (Depth == 0)
- return DWARFDie();
- // Depth of 1 always means parent is the compile/type unit.
- if (Depth == 1)
- return getUnitDIE();
- // Look for previous DIE with a depth that is one less than the Die's depth.
- const uint32_t ParentDepth = Depth - 1;
- for (uint32_t I = getDIEIndex(Die) - 1; I > 0; --I) {
- if (DieArray[I].getDepth() == ParentDepth)
- return DWARFDie(this, &DieArray[I]);
- }
- return DWARFDie();
-}
-
-DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
- if (!Die)
- return DWARFDie();
- uint32_t Depth = Die->getDepth();
- // Unit DIEs always have a depth of zero and never have siblings.
- if (Depth == 0)
- return DWARFDie();
- // NULL DIEs don't have siblings.
- if (Die->getAbbreviationDeclarationPtr() == nullptr)
- return DWARFDie();
-
- // Find the next DIE whose depth is the same as the Die's depth.
- for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
- ++I) {
- if (DieArray[I].getDepth() == Depth)
- return DWARFDie(this, &DieArray[I]);
- }
- return DWARFDie();
-}
-
-DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
- if (!Die)
- return DWARFDie();
- uint32_t Depth = Die->getDepth();
- // Unit DIEs always have a depth of zero and never have siblings.
- if (Depth == 0)
- return DWARFDie();
-
- // Find the previous DIE whose depth is the same as the Die's depth.
- for (size_t I = getDIEIndex(Die); I > 0;) {
- --I;
- if (DieArray[I].getDepth() == Depth - 1)
- return DWARFDie();
- if (DieArray[I].getDepth() == Depth)
- return DWARFDie(this, &DieArray[I]);
- }
- return DWARFDie();
-}
-
-DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
- if (!Die->hasChildren())
- return DWARFDie();
-
- // We do not want access out of bounds when parsing corrupted debug data.
- size_t I = getDIEIndex(Die) + 1;
- if (I >= DieArray.size())
- return DWARFDie();
- return DWARFDie(this, &DieArray[I]);
-}
-
-DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
- if (!Die->hasChildren())
- return DWARFDie();
-
- uint32_t Depth = Die->getDepth();
- for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
- ++I) {
- if (DieArray[I].getDepth() == Depth + 1 &&
- DieArray[I].getTag() == dwarf::DW_TAG_null)
- return DWARFDie(this, &DieArray[I]);
- assert(DieArray[I].getDepth() > Depth && "Not processing children?");
- }
- return DWARFDie();
-}
-
-const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
- if (!Abbrevs)
- Abbrevs = Abbrev->getAbbreviationDeclarationSet(Header.getAbbrOffset());
- return Abbrevs;
-}
-
-llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
- if (BaseAddr)
- return BaseAddr;
-
- DWARFDie UnitDie = getUnitDIE();
- Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
- BaseAddr = toSectionedAddress(PC);
- return BaseAddr;
-}
-
-Expected<StrOffsetsContributionDescriptor>
-StrOffsetsContributionDescriptor::validateContributionSize(
- DWARFDataExtractor &DA) {
- uint8_t EntrySize = getDwarfOffsetByteSize();
- // In order to ensure that we don't read a partial record at the end of
- // the section we validate for a multiple of the entry size.
- uint64_t ValidationSize = alignTo(Size, EntrySize);
- // Guard against overflow.
- if (ValidationSize >= Size)
- if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
- return *this;
- 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 Expected<StrOffsetsContributionDescriptor>
-parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
- if (!DA.isValidOffsetForDataOfSize(Offset, 16))
- return createStringError(errc::invalid_argument, "section offset exceeds section size");
-
- if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64)
- 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 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 Expected<StrOffsetsContributionDescriptor>
-parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
- if (!DA.isValidOffsetForDataOfSize(Offset, 8))
- return createStringError(errc::invalid_argument, "section offset exceeds section size");
-
- uint32_t ContributionSize = DA.getU32(&Offset);
- if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
- 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 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, 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, Offset - 8);
- if (!DescOrError)
- return DescOrError.takeError();
- Desc = *DescOrError;
- break;
- }
- }
- return Desc.validateContributionSize(DA);
-}
-
-Expected<Optional<StrOffsetsContributionDescriptor>>
-DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) {
- assert(!IsDWO);
- auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base));
- if (!OptOffset)
- return None;
- auto DescOrError =
- parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), *OptOffset);
- if (!DescOrError)
- return DescOrError.takeError();
- return *DescOrError;
-}
-
-Expected<Optional<StrOffsetsContributionDescriptor>>
-DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
- assert(IsDWO);
- uint64_t Offset = 0;
- auto IndexEntry = Header.getIndexEntry();
- const auto *C =
- IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr;
- 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 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.
+}
+
+Expected<DWARFAddressRangesVector> DWARFUnit::collectAddressRanges() {
+ DWARFDie UnitDie = getUnitDIE();
+ if (!UnitDie)
+ return createStringError(errc::invalid_argument, "No unit DIE");
+
+ // First, check if unit DIE describes address ranges for the whole unit.
+ auto CUDIERangesOrError = UnitDie.getAddressRanges();
+ if (!CUDIERangesOrError)
+ return createStringError(errc::invalid_argument,
+ "decoding address ranges: %s",
+ toString(CUDIERangesOrError.takeError()).c_str());
+ return *CUDIERangesOrError;
+}
+
+Expected<DWARFLocationExpressionsVector>
+DWARFUnit::findLoclistFromOffset(uint64_t Offset) {
+ DWARFLocationExpressionsVector Result;
+
+ Error InterpretationError = Error::success();
+
+ Error ParseError = getLocationTable().visitAbsoluteLocationList(
+ Offset, getBaseAddress(),
+ [this](uint32_t Index) { return getAddrOffsetSectionItem(Index); },
+ [&](Expected<DWARFLocationExpression> L) {
+ if (L)
+ Result.push_back(std::move(*L));
+ else
+ InterpretationError =
+ joinErrors(L.takeError(), std::move(InterpretationError));
+ return !InterpretationError;
+ });
+
+ if (ParseError || InterpretationError)
+ return joinErrors(std::move(ParseError), std::move(InterpretationError));
+
+ return Result;
+}
+
+void DWARFUnit::updateAddressDieMap(DWARFDie Die) {
+ if (Die.isSubroutineDIE()) {
+ auto DIERangesOrError = Die.getAddressRanges();
+ if (DIERangesOrError) {
+ for (const auto &R : DIERangesOrError.get()) {
+ // Ignore 0-sized ranges.
+ if (R.LowPC == R.HighPC)
+ continue;
+ auto B = AddrDieMap.upper_bound(R.LowPC);
+ if (B != AddrDieMap.begin() && R.LowPC < (--B)->second.first) {
+ // The range is a sub-range of existing ranges, we need to split the
+ // existing range.
+ if (R.HighPC < B->second.first)
+ AddrDieMap[R.HighPC] = B->second;
+ if (R.LowPC > B->first)
+ AddrDieMap[B->first].first = R.LowPC;
+ }
+ AddrDieMap[R.LowPC] = std::make_pair(R.HighPC, Die);
+ }
+ } else
+ llvm::consumeError(DIERangesOrError.takeError());
+ }
+ // Parent DIEs are added to the AddrDieMap prior to the Children DIEs to
+ // simplify the logic to update AddrDieMap. The child's range will always
+ // be equal or smaller than the parent's range. With this assumption, when
+ // adding one range into the map, it will at most split a range into 3
+ // sub-ranges.
+ for (DWARFDie Child = Die.getFirstChild(); Child; Child = Child.getSibling())
+ updateAddressDieMap(Child);
+}
+
+DWARFDie DWARFUnit::getSubroutineForAddress(uint64_t Address) {
+ extractDIEsIfNeeded(false);
+ if (AddrDieMap.empty())
+ updateAddressDieMap(getUnitDIE());
+ auto R = AddrDieMap.upper_bound(Address);
+ if (R == AddrDieMap.begin())
+ return DWARFDie();
+ // upper_bound's previous item contains Address.
+ --R;
+ if (Address >= R->second.first)
+ return DWARFDie();
+ return R->second.second;
+}
+
+void
+DWARFUnit::getInlinedChainForAddress(uint64_t Address,
+ SmallVectorImpl<DWARFDie> &InlinedChain) {
+ assert(InlinedChain.empty());
+ // Try to look for subprogram DIEs in the DWO file.
+ parseDWO();
+ // First, find the subroutine that contains the given address (the leaf
+ // of inlined chain).
+ DWARFDie SubroutineDIE =
+ (DWO ? *DWO : *this).getSubroutineForAddress(Address);
+
+ if (!SubroutineDIE)
+ return;
+
+ while (!SubroutineDIE.isSubprogramDIE()) {
+ if (SubroutineDIE.getTag() == DW_TAG_inlined_subroutine)
+ InlinedChain.push_back(SubroutineDIE);
+ SubroutineDIE = SubroutineDIE.getParent();
+ }
+ InlinedChain.push_back(SubroutineDIE);
+}
+
+const DWARFUnitIndex &llvm::getDWARFUnitIndex(DWARFContext &Context,
+ DWARFSectionKind Kind) {
+ if (Kind == DW_SECT_INFO)
+ return Context.getCUIndex();
+ assert(Kind == DW_SECT_EXT_TYPES);
+ return Context.getTUIndex();
+}
+
+DWARFDie DWARFUnit::getParent(const DWARFDebugInfoEntry *Die) {
+ if (!Die)
+ return DWARFDie();
+ const uint32_t Depth = Die->getDepth();
+ // Unit DIEs always have a depth of zero and never have parents.
+ if (Depth == 0)
+ return DWARFDie();
+ // Depth of 1 always means parent is the compile/type unit.
+ if (Depth == 1)
+ return getUnitDIE();
+ // Look for previous DIE with a depth that is one less than the Die's depth.
+ const uint32_t ParentDepth = Depth - 1;
+ for (uint32_t I = getDIEIndex(Die) - 1; I > 0; --I) {
+ if (DieArray[I].getDepth() == ParentDepth)
+ return DWARFDie(this, &DieArray[I]);
+ }
+ return DWARFDie();
+}
+
+DWARFDie DWARFUnit::getSibling(const DWARFDebugInfoEntry *Die) {
+ if (!Die)
+ return DWARFDie();
+ uint32_t Depth = Die->getDepth();
+ // Unit DIEs always have a depth of zero and never have siblings.
+ if (Depth == 0)
+ return DWARFDie();
+ // NULL DIEs don't have siblings.
+ if (Die->getAbbreviationDeclarationPtr() == nullptr)
+ return DWARFDie();
+
+ // Find the next DIE whose depth is the same as the Die's depth.
+ for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
+ ++I) {
+ if (DieArray[I].getDepth() == Depth)
+ return DWARFDie(this, &DieArray[I]);
+ }
+ return DWARFDie();
+}
+
+DWARFDie DWARFUnit::getPreviousSibling(const DWARFDebugInfoEntry *Die) {
+ if (!Die)
+ return DWARFDie();
+ uint32_t Depth = Die->getDepth();
+ // Unit DIEs always have a depth of zero and never have siblings.
+ if (Depth == 0)
+ return DWARFDie();
+
+ // Find the previous DIE whose depth is the same as the Die's depth.
+ for (size_t I = getDIEIndex(Die); I > 0;) {
+ --I;
+ if (DieArray[I].getDepth() == Depth - 1)
+ return DWARFDie();
+ if (DieArray[I].getDepth() == Depth)
+ return DWARFDie(this, &DieArray[I]);
+ }
+ return DWARFDie();
+}
+
+DWARFDie DWARFUnit::getFirstChild(const DWARFDebugInfoEntry *Die) {
+ if (!Die->hasChildren())
+ return DWARFDie();
+
+ // We do not want access out of bounds when parsing corrupted debug data.
+ size_t I = getDIEIndex(Die) + 1;
+ if (I >= DieArray.size())
+ return DWARFDie();
+ return DWARFDie(this, &DieArray[I]);
+}
+
+DWARFDie DWARFUnit::getLastChild(const DWARFDebugInfoEntry *Die) {
+ if (!Die->hasChildren())
+ return DWARFDie();
+
+ uint32_t Depth = Die->getDepth();
+ for (size_t I = getDIEIndex(Die) + 1, EndIdx = DieArray.size(); I < EndIdx;
+ ++I) {
+ if (DieArray[I].getDepth() == Depth + 1 &&
+ DieArray[I].getTag() == dwarf::DW_TAG_null)
+ return DWARFDie(this, &DieArray[I]);
+ assert(DieArray[I].getDepth() > Depth && "Not processing children?");
+ }
+ return DWARFDie();
+}
+
+const DWARFAbbreviationDeclarationSet *DWARFUnit::getAbbreviations() const {
+ if (!Abbrevs)
+ Abbrevs = Abbrev->getAbbreviationDeclarationSet(Header.getAbbrOffset());
+ return Abbrevs;
+}
+
+llvm::Optional<object::SectionedAddress> DWARFUnit::getBaseAddress() {
+ if (BaseAddr)
+ return BaseAddr;
+
+ DWARFDie UnitDie = getUnitDIE();
+ Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
+ BaseAddr = toSectionedAddress(PC);
+ return BaseAddr;
+}
+
+Expected<StrOffsetsContributionDescriptor>
+StrOffsetsContributionDescriptor::validateContributionSize(
+ DWARFDataExtractor &DA) {
+ uint8_t EntrySize = getDwarfOffsetByteSize();
+ // In order to ensure that we don't read a partial record at the end of
+ // the section we validate for a multiple of the entry size.
+ uint64_t ValidationSize = alignTo(Size, EntrySize);
+ // Guard against overflow.
+ if (ValidationSize >= Size)
+ if (DA.isValidOffsetForDataOfSize((uint32_t)Base, ValidationSize))
+ return *this;
+ 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 Expected<StrOffsetsContributionDescriptor>
+parseDWARF64StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
+ if (!DA.isValidOffsetForDataOfSize(Offset, 16))
+ return createStringError(errc::invalid_argument, "section offset exceeds section size");
+
+ if (DA.getU32(&Offset) != dwarf::DW_LENGTH_DWARF64)
+ 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 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 Expected<StrOffsetsContributionDescriptor>
+parseDWARF32StringOffsetsTableHeader(DWARFDataExtractor &DA, uint64_t Offset) {
+ if (!DA.isValidOffsetForDataOfSize(Offset, 8))
+ return createStringError(errc::invalid_argument, "section offset exceeds section size");
+
+ uint32_t ContributionSize = DA.getU32(&Offset);
+ if (ContributionSize >= dwarf::DW_LENGTH_lo_reserved)
+ 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 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, 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, Offset - 8);
+ if (!DescOrError)
+ return DescOrError.takeError();
+ Desc = *DescOrError;
+ break;
+ }
+ }
+ return Desc.validateContributionSize(DA);
+}
+
+Expected<Optional<StrOffsetsContributionDescriptor>>
+DWARFUnit::determineStringOffsetsTableContribution(DWARFDataExtractor &DA) {
+ assert(!IsDWO);
+ auto OptOffset = toSectionOffset(getUnitDIE().find(DW_AT_str_offsets_base));
+ if (!OptOffset)
+ return None;
+ auto DescOrError =
+ parseDWARFStringOffsetsTableHeader(DA, Header.getFormat(), *OptOffset);
+ if (!DescOrError)
+ return DescOrError.takeError();
+ return *DescOrError;
+}
+
+Expected<Optional<StrOffsetsContributionDescriptor>>
+DWARFUnit::determineStringOffsetsTableContributionDWO(DWARFDataExtractor & DA) {
+ assert(IsDWO);
+ uint64_t Offset = 0;
+ auto IndexEntry = Header.getIndexEntry();
+ const auto *C =
+ IndexEntry ? IndexEntry->getContribution(DW_SECT_STR_OFFSETS) : nullptr;
+ 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 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.
StrOffsetsContributionDescriptor Desc;
- if (C)
+ if (C)
Desc = StrOffsetsContributionDescriptor(C->Offset, C->Length, 4,
Header.getFormat());
else if (!IndexEntry && !StringOffsetSection.Data.empty())
@@ -944,8 +944,8 @@ Optional<uint64_t> DWARFUnit::getRnglistOffset(uint32_t Index) {
if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
RangesData, RangeSectionBase, getFormat(), Index))
return *Off + RangeSectionBase;
- return None;
-}
+ return None;
+}
Optional<uint64_t> DWARFUnit::getLoclistOffset(uint32_t Index) {
if (Optional<uint64_t> Off = llvm::DWARFListTableHeader::getOffsetEntry(
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
index d27fd08db1..216dbce721 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFUnitIndex.cpp
@@ -1,300 +1,300 @@
-//===- DWARFUnitIndex.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cinttypes>
-#include <cstdint>
-
-using namespace llvm;
-
-namespace {
-
-enum class DWARFSectionKindV2 {
- DW_SECT_INFO = 1,
- DW_SECT_TYPES = 2,
- DW_SECT_ABBREV = 3,
- DW_SECT_LINE = 4,
- DW_SECT_LOC = 5,
- DW_SECT_STR_OFFSETS = 6,
- DW_SECT_MACINFO = 7,
- DW_SECT_MACRO = 8,
-};
-
-} // namespace
-
-// Return true if the section identifier is defined in the DWARFv5 standard.
-constexpr bool isKnownV5SectionID(uint32_t ID) {
- return ID >= DW_SECT_INFO && ID <= DW_SECT_RNGLISTS &&
- ID != DW_SECT_EXT_TYPES;
-}
-
-uint32_t llvm::serializeSectionKind(DWARFSectionKind Kind,
- unsigned IndexVersion) {
- if (IndexVersion == 5) {
- assert(isKnownV5SectionID(Kind));
- return static_cast<uint32_t>(Kind);
- }
- assert(IndexVersion == 2);
- switch (Kind) {
-#define CASE(S,T) \
- case DW_SECT_##S: \
- return static_cast<uint32_t>(DWARFSectionKindV2::DW_SECT_##T)
- CASE(INFO, INFO);
- CASE(EXT_TYPES, TYPES);
- CASE(ABBREV, ABBREV);
- CASE(LINE, LINE);
- CASE(EXT_LOC, LOC);
- CASE(STR_OFFSETS, STR_OFFSETS);
- CASE(EXT_MACINFO, MACINFO);
- CASE(MACRO, MACRO);
-#undef CASE
- default:
- // All other section kinds have no corresponding values in v2 indexes.
- llvm_unreachable("Invalid DWARFSectionKind");
- }
-}
-
-DWARFSectionKind llvm::deserializeSectionKind(uint32_t Value,
- unsigned IndexVersion) {
- if (IndexVersion == 5)
- return isKnownV5SectionID(Value)
- ? static_cast<DWARFSectionKind>(Value)
- : DW_SECT_EXT_unknown;
- assert(IndexVersion == 2);
- switch (static_cast<DWARFSectionKindV2>(Value)) {
-#define CASE(S,T) \
- case DWARFSectionKindV2::DW_SECT_##S: \
- return DW_SECT_##T
- CASE(INFO, INFO);
- CASE(TYPES, EXT_TYPES);
- CASE(ABBREV, ABBREV);
- CASE(LINE, LINE);
- CASE(LOC, EXT_LOC);
- CASE(STR_OFFSETS, STR_OFFSETS);
- CASE(MACINFO, EXT_MACINFO);
- CASE(MACRO, MACRO);
-#undef CASE
- }
- return DW_SECT_EXT_unknown;
-}
-
-bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
- uint64_t *OffsetPtr) {
- const uint64_t BeginOffset = *OffsetPtr;
- if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
- return false;
- // GCC Debug Fission defines the version as an unsigned 32-bit field
- // with value of 2, https://gcc.gnu.org/wiki/DebugFissionDWP.
- // DWARFv5 defines the same space as an uhalf version field with value of 5
- // and a 2 bytes long padding, see Section 7.3.5.3.
- Version = IndexData.getU32(OffsetPtr);
- if (Version != 2) {
- *OffsetPtr = BeginOffset;
- Version = IndexData.getU16(OffsetPtr);
- if (Version != 5)
- return false;
- *OffsetPtr += 2; // Skip padding.
- }
- NumColumns = IndexData.getU32(OffsetPtr);
- NumUnits = IndexData.getU32(OffsetPtr);
- NumBuckets = IndexData.getU32(OffsetPtr);
- return true;
-}
-
-void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
- OS << format("version = %u, units = %u, slots = %u\n\n", Version, NumUnits, NumBuckets);
-}
-
-bool DWARFUnitIndex::parse(DataExtractor IndexData) {
- bool b = parseImpl(IndexData);
- if (!b) {
- // Make sure we don't try to dump anything
- Header.NumBuckets = 0;
- // Release any partially initialized data.
- ColumnKinds.reset();
- Rows.reset();
- }
- return b;
-}
-
-bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
- uint64_t Offset = 0;
- if (!Header.parse(IndexData, &Offset))
- return false;
-
- // Fix InfoColumnKind: in DWARFv5, type units are in .debug_info.dwo.
- if (Header.Version == 5)
- InfoColumnKind = DW_SECT_INFO;
-
- if (!IndexData.isValidOffsetForDataOfSize(
- Offset, Header.NumBuckets * (8 + 4) +
- (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
- return false;
-
- Rows = std::make_unique<Entry[]>(Header.NumBuckets);
- auto Contribs =
- std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
- ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns);
- RawSectionIds = std::make_unique<uint32_t[]>(Header.NumColumns);
-
- // Read Hash Table of Signatures
- for (unsigned i = 0; i != Header.NumBuckets; ++i)
- Rows[i].Signature = IndexData.getU64(&Offset);
-
- // Read Parallel Table of Indexes
- for (unsigned i = 0; i != Header.NumBuckets; ++i) {
- auto Index = IndexData.getU32(&Offset);
- if (!Index)
- continue;
- Rows[i].Index = this;
- Rows[i].Contributions =
- std::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
- Contribs[Index - 1] = Rows[i].Contributions.get();
- }
-
- // Read the Column Headers
- for (unsigned i = 0; i != Header.NumColumns; ++i) {
- RawSectionIds[i] = IndexData.getU32(&Offset);
- ColumnKinds[i] = deserializeSectionKind(RawSectionIds[i], Header.Version);
- if (ColumnKinds[i] == InfoColumnKind) {
- if (InfoColumn != -1)
- return false;
- InfoColumn = i;
- }
- }
-
- if (InfoColumn == -1)
- return false;
-
- // Read Table of Section Offsets
- for (unsigned i = 0; i != Header.NumUnits; ++i) {
- auto *Contrib = Contribs[i];
- for (unsigned i = 0; i != Header.NumColumns; ++i)
- Contrib[i].Offset = IndexData.getU32(&Offset);
- }
-
- // Read Table of Section Sizes
- for (unsigned i = 0; i != Header.NumUnits; ++i) {
- auto *Contrib = Contribs[i];
- for (unsigned i = 0; i != Header.NumColumns; ++i)
- Contrib[i].Length = IndexData.getU32(&Offset);
- }
-
- return true;
-}
-
-StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
- switch (DS) {
-#define HANDLE_DW_SECT(ID, NAME) \
- case DW_SECT_##NAME: \
- return #NAME;
-#include "llvm/BinaryFormat/Dwarf.def"
- case DW_SECT_EXT_TYPES:
- return "TYPES";
- case DW_SECT_EXT_LOC:
- return "LOC";
- case DW_SECT_EXT_MACINFO:
- return "MACINFO";
- case DW_SECT_EXT_unknown:
- return StringRef();
- }
- llvm_unreachable("Unknown DWARFSectionKind");
-}
-
-void DWARFUnitIndex::dump(raw_ostream &OS) const {
- if (!*this)
- return;
-
- Header.dump(OS);
- OS << "Index Signature ";
- for (unsigned i = 0; i != Header.NumColumns; ++i) {
- DWARFSectionKind Kind = ColumnKinds[i];
- StringRef Name = getColumnHeader(Kind);
- if (!Name.empty())
- OS << ' ' << left_justify(Name, 24);
- else
- OS << format(" Unknown: %-15" PRIu32, RawSectionIds[i]);
- }
- OS << "\n----- ------------------";
- for (unsigned i = 0; i != Header.NumColumns; ++i)
- OS << " ------------------------";
- OS << '\n';
- for (unsigned i = 0; i != Header.NumBuckets; ++i) {
- auto &Row = Rows[i];
- if (auto *Contribs = Row.Contributions.get()) {
- OS << format("%5u 0x%016" PRIx64 " ", i + 1, Row.Signature);
- for (unsigned i = 0; i != Header.NumColumns; ++i) {
- auto &Contrib = Contribs[i];
- OS << format("[0x%08x, 0x%08x) ", Contrib.Offset,
- Contrib.Offset + Contrib.Length);
- }
- OS << '\n';
- }
- }
-}
-
-const DWARFUnitIndex::Entry::SectionContribution *
-DWARFUnitIndex::Entry::getContribution(DWARFSectionKind Sec) const {
- uint32_t i = 0;
- for (; i != Index->Header.NumColumns; ++i)
- if (Index->ColumnKinds[i] == Sec)
- return &Contributions[i];
- return nullptr;
-}
-
-const DWARFUnitIndex::Entry::SectionContribution *
-DWARFUnitIndex::Entry::getContribution() const {
- return &Contributions[Index->InfoColumn];
-}
-
-const DWARFUnitIndex::Entry *
-DWARFUnitIndex::getFromOffset(uint32_t Offset) const {
- if (OffsetLookup.empty()) {
- for (uint32_t i = 0; i != Header.NumBuckets; ++i)
- if (Rows[i].Contributions)
- OffsetLookup.push_back(&Rows[i]);
- llvm::sort(OffsetLookup, [&](Entry *E1, Entry *E2) {
- return E1->Contributions[InfoColumn].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;
- const auto *E = *I;
- const auto &InfoContrib = E->Contributions[InfoColumn];
- if ((InfoContrib.Offset + InfoContrib.Length) <= Offset)
- return nullptr;
- return E;
-}
-
-const DWARFUnitIndex::Entry *DWARFUnitIndex::getFromHash(uint64_t S) const {
- uint64_t Mask = Header.NumBuckets - 1;
-
- auto H = S & Mask;
- auto HP = ((S >> 32) & Mask) | 1;
- // The spec says "while 0 is a valid hash value, the row index in a used slot
- // will always be non-zero". Loop until we find a match or an empty slot.
- while (Rows[H].getSignature() != S && Rows[H].Index != nullptr)
- H = (H + HP) & Mask;
-
- // If the slot is empty, we don't care whether the signature matches (it could
- // be zero and still match the zeros in the empty slot).
- if (Rows[H].Index == nullptr)
- return nullptr;
-
- return &Rows[H];
-}
+//===- DWARFUnitIndex.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cinttypes>
+#include <cstdint>
+
+using namespace llvm;
+
+namespace {
+
+enum class DWARFSectionKindV2 {
+ DW_SECT_INFO = 1,
+ DW_SECT_TYPES = 2,
+ DW_SECT_ABBREV = 3,
+ DW_SECT_LINE = 4,
+ DW_SECT_LOC = 5,
+ DW_SECT_STR_OFFSETS = 6,
+ DW_SECT_MACINFO = 7,
+ DW_SECT_MACRO = 8,
+};
+
+} // namespace
+
+// Return true if the section identifier is defined in the DWARFv5 standard.
+constexpr bool isKnownV5SectionID(uint32_t ID) {
+ return ID >= DW_SECT_INFO && ID <= DW_SECT_RNGLISTS &&
+ ID != DW_SECT_EXT_TYPES;
+}
+
+uint32_t llvm::serializeSectionKind(DWARFSectionKind Kind,
+ unsigned IndexVersion) {
+ if (IndexVersion == 5) {
+ assert(isKnownV5SectionID(Kind));
+ return static_cast<uint32_t>(Kind);
+ }
+ assert(IndexVersion == 2);
+ switch (Kind) {
+#define CASE(S,T) \
+ case DW_SECT_##S: \
+ return static_cast<uint32_t>(DWARFSectionKindV2::DW_SECT_##T)
+ CASE(INFO, INFO);
+ CASE(EXT_TYPES, TYPES);
+ CASE(ABBREV, ABBREV);
+ CASE(LINE, LINE);
+ CASE(EXT_LOC, LOC);
+ CASE(STR_OFFSETS, STR_OFFSETS);
+ CASE(EXT_MACINFO, MACINFO);
+ CASE(MACRO, MACRO);
+#undef CASE
+ default:
+ // All other section kinds have no corresponding values in v2 indexes.
+ llvm_unreachable("Invalid DWARFSectionKind");
+ }
+}
+
+DWARFSectionKind llvm::deserializeSectionKind(uint32_t Value,
+ unsigned IndexVersion) {
+ if (IndexVersion == 5)
+ return isKnownV5SectionID(Value)
+ ? static_cast<DWARFSectionKind>(Value)
+ : DW_SECT_EXT_unknown;
+ assert(IndexVersion == 2);
+ switch (static_cast<DWARFSectionKindV2>(Value)) {
+#define CASE(S,T) \
+ case DWARFSectionKindV2::DW_SECT_##S: \
+ return DW_SECT_##T
+ CASE(INFO, INFO);
+ CASE(TYPES, EXT_TYPES);
+ CASE(ABBREV, ABBREV);
+ CASE(LINE, LINE);
+ CASE(LOC, EXT_LOC);
+ CASE(STR_OFFSETS, STR_OFFSETS);
+ CASE(MACINFO, EXT_MACINFO);
+ CASE(MACRO, MACRO);
+#undef CASE
+ }
+ return DW_SECT_EXT_unknown;
+}
+
+bool DWARFUnitIndex::Header::parse(DataExtractor IndexData,
+ uint64_t *OffsetPtr) {
+ const uint64_t BeginOffset = *OffsetPtr;
+ if (!IndexData.isValidOffsetForDataOfSize(*OffsetPtr, 16))
+ return false;
+ // GCC Debug Fission defines the version as an unsigned 32-bit field
+ // with value of 2, https://gcc.gnu.org/wiki/DebugFissionDWP.
+ // DWARFv5 defines the same space as an uhalf version field with value of 5
+ // and a 2 bytes long padding, see Section 7.3.5.3.
+ Version = IndexData.getU32(OffsetPtr);
+ if (Version != 2) {
+ *OffsetPtr = BeginOffset;
+ Version = IndexData.getU16(OffsetPtr);
+ if (Version != 5)
+ return false;
+ *OffsetPtr += 2; // Skip padding.
+ }
+ NumColumns = IndexData.getU32(OffsetPtr);
+ NumUnits = IndexData.getU32(OffsetPtr);
+ NumBuckets = IndexData.getU32(OffsetPtr);
+ return true;
+}
+
+void DWARFUnitIndex::Header::dump(raw_ostream &OS) const {
+ OS << format("version = %u, units = %u, slots = %u\n\n", Version, NumUnits, NumBuckets);
+}
+
+bool DWARFUnitIndex::parse(DataExtractor IndexData) {
+ bool b = parseImpl(IndexData);
+ if (!b) {
+ // Make sure we don't try to dump anything
+ Header.NumBuckets = 0;
+ // Release any partially initialized data.
+ ColumnKinds.reset();
+ Rows.reset();
+ }
+ return b;
+}
+
+bool DWARFUnitIndex::parseImpl(DataExtractor IndexData) {
+ uint64_t Offset = 0;
+ if (!Header.parse(IndexData, &Offset))
+ return false;
+
+ // Fix InfoColumnKind: in DWARFv5, type units are in .debug_info.dwo.
+ if (Header.Version == 5)
+ InfoColumnKind = DW_SECT_INFO;
+
+ if (!IndexData.isValidOffsetForDataOfSize(
+ Offset, Header.NumBuckets * (8 + 4) +
+ (2 * Header.NumUnits + 1) * 4 * Header.NumColumns))
+ return false;
+
+ Rows = std::make_unique<Entry[]>(Header.NumBuckets);
+ auto Contribs =
+ std::make_unique<Entry::SectionContribution *[]>(Header.NumUnits);
+ ColumnKinds = std::make_unique<DWARFSectionKind[]>(Header.NumColumns);
+ RawSectionIds = std::make_unique<uint32_t[]>(Header.NumColumns);
+
+ // Read Hash Table of Signatures
+ for (unsigned i = 0; i != Header.NumBuckets; ++i)
+ Rows[i].Signature = IndexData.getU64(&Offset);
+
+ // Read Parallel Table of Indexes
+ for (unsigned i = 0; i != Header.NumBuckets; ++i) {
+ auto Index = IndexData.getU32(&Offset);
+ if (!Index)
+ continue;
+ Rows[i].Index = this;
+ Rows[i].Contributions =
+ std::make_unique<Entry::SectionContribution[]>(Header.NumColumns);
+ Contribs[Index - 1] = Rows[i].Contributions.get();
+ }
+
+ // Read the Column Headers
+ for (unsigned i = 0; i != Header.NumColumns; ++i) {
+ RawSectionIds[i] = IndexData.getU32(&Offset);
+ ColumnKinds[i] = deserializeSectionKind(RawSectionIds[i], Header.Version);
+ if (ColumnKinds[i] == InfoColumnKind) {
+ if (InfoColumn != -1)
+ return false;
+ InfoColumn = i;
+ }
+ }
+
+ if (InfoColumn == -1)
+ return false;
+
+ // Read Table of Section Offsets
+ for (unsigned i = 0; i != Header.NumUnits; ++i) {
+ auto *Contrib = Contribs[i];
+ for (unsigned i = 0; i != Header.NumColumns; ++i)
+ Contrib[i].Offset = IndexData.getU32(&Offset);
+ }
+
+ // Read Table of Section Sizes
+ for (unsigned i = 0; i != Header.NumUnits; ++i) {
+ auto *Contrib = Contribs[i];
+ for (unsigned i = 0; i != Header.NumColumns; ++i)
+ Contrib[i].Length = IndexData.getU32(&Offset);
+ }
+
+ return true;
+}
+
+StringRef DWARFUnitIndex::getColumnHeader(DWARFSectionKind DS) {
+ switch (DS) {
+#define HANDLE_DW_SECT(ID, NAME) \
+ case DW_SECT_##NAME: \
+ return #NAME;
+#include "llvm/BinaryFormat/Dwarf.def"
+ case DW_SECT_EXT_TYPES:
+ return "TYPES";
+ case DW_SECT_EXT_LOC:
+ return "LOC";
+ case DW_SECT_EXT_MACINFO:
+ return "MACINFO";
+ case DW_SECT_EXT_unknown:
+ return StringRef();
+ }
+ llvm_unreachable("Unknown DWARFSectionKind");
+}
+
+void DWARFUnitIndex::dump(raw_ostream &OS) const {
+ if (!*this)
+ return;
+
+ Header.dump(OS);
+ OS << "Index Signature ";
+ for (unsigned i = 0; i != Header.NumColumns; ++i) {
+ DWARFSectionKind Kind = ColumnKinds[i];
+ StringRef Name = getColumnHeader(Kind);
+ if (!Name.empty())
+ OS << ' ' << left_justify(Name, 24);
+ else
+ OS << format(" Unknown: %-15" PRIu32, RawSectionIds[i]);
+ }
+ OS << "\n----- ------------------";
+ for (unsigned i = 0; i != Header.NumColumns; ++i)
+ OS << " ------------------------";
+ OS << '\n';
+ for (unsigned i = 0; i != Header.NumBuckets; ++i) {
+ auto &Row = Rows[i];
+ if (auto *Contribs = Row.Contributions.get()) {
+ OS << format("%5u 0x%016" PRIx64 " ", i + 1, Row.Signature);
+ for (unsigned i = 0; i != Header.NumColumns; ++i) {
+ auto &Contrib = Contribs[i];
+ OS << format("[0x%08x, 0x%08x) ", Contrib.Offset,
+ Contrib.Offset + Contrib.Length);
+ }
+ OS << '\n';
+ }
+ }
+}
+
+const DWARFUnitIndex::Entry::SectionContribution *
+DWARFUnitIndex::Entry::getContribution(DWARFSectionKind Sec) const {
+ uint32_t i = 0;
+ for (; i != Index->Header.NumColumns; ++i)
+ if (Index->ColumnKinds[i] == Sec)
+ return &Contributions[i];
+ return nullptr;
+}
+
+const DWARFUnitIndex::Entry::SectionContribution *
+DWARFUnitIndex::Entry::getContribution() const {
+ return &Contributions[Index->InfoColumn];
+}
+
+const DWARFUnitIndex::Entry *
+DWARFUnitIndex::getFromOffset(uint32_t Offset) const {
+ if (OffsetLookup.empty()) {
+ for (uint32_t i = 0; i != Header.NumBuckets; ++i)
+ if (Rows[i].Contributions)
+ OffsetLookup.push_back(&Rows[i]);
+ llvm::sort(OffsetLookup, [&](Entry *E1, Entry *E2) {
+ return E1->Contributions[InfoColumn].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;
+ const auto *E = *I;
+ const auto &InfoContrib = E->Contributions[InfoColumn];
+ if ((InfoContrib.Offset + InfoContrib.Length) <= Offset)
+ return nullptr;
+ return E;
+}
+
+const DWARFUnitIndex::Entry *DWARFUnitIndex::getFromHash(uint64_t S) const {
+ uint64_t Mask = Header.NumBuckets - 1;
+
+ auto H = S & Mask;
+ auto HP = ((S >> 32) & Mask) | 1;
+ // The spec says "while 0 is a valid hash value, the row index in a used slot
+ // will always be non-zero". Loop until we find a match or an empty slot.
+ while (Rows[H].getSignature() != S && Rows[H].Index != nullptr)
+ H = (H + HP) & Mask;
+
+ // If the slot is empty, we don't care whether the signature matches (it could
+ // be zero and still match the zeros in the empty slot).
+ if (Rows[H].Index == nullptr)
+ return nullptr;
+
+ return &Rows[H];
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp
index ac624ec8b8..ece067244e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/DWARFVerifier.cpp
@@ -1,177 +1,177 @@
-//===- DWARFVerifier.cpp --------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
-#include "llvm/DebugInfo/DWARF/DWARFDie.h"
-#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
-#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
-#include "llvm/DebugInfo/DWARF/DWARFSection.h"
-#include "llvm/Support/DJB.h"
-#include "llvm/Support/FormatVariadic.h"
-#include "llvm/Support/WithColor.h"
-#include "llvm/Support/raw_ostream.h"
-#include <map>
-#include <set>
-#include <vector>
-
-using namespace llvm;
-using namespace dwarf;
-using namespace object;
-
-Optional<DWARFAddressRange>
-DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
- auto Begin = Ranges.begin();
- auto End = Ranges.end();
- auto Pos = std::lower_bound(Begin, End, R);
-
- if (Pos != End) {
- DWARFAddressRange Range(*Pos);
- if (Pos->merge(R))
- return Range;
- }
- if (Pos != Begin) {
- auto Iter = Pos - 1;
- DWARFAddressRange Range(*Iter);
- if (Iter->merge(R))
- return Range;
- }
-
- Ranges.insert(Pos, R);
- return None;
-}
-
-DWARFVerifier::DieRangeInfo::die_range_info_iterator
-DWARFVerifier::DieRangeInfo::insert(const DieRangeInfo &RI) {
- auto End = Children.end();
- auto Iter = Children.begin();
- while (Iter != End) {
- if (Iter->intersects(RI))
- return Iter;
- ++Iter;
- }
- Children.insert(RI);
- return Children.end();
-}
-
-bool DWARFVerifier::DieRangeInfo::contains(const DieRangeInfo &RHS) const {
- auto I1 = Ranges.begin(), E1 = Ranges.end();
- auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end();
- if (I2 == E2)
- return true;
-
- 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 (!Covered)
- return false;
- if (R.LowPC < I1->HighPC)
- R.LowPC = I1->HighPC;
- ++I1;
- }
- return false;
-}
-
-bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
- 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,
- uint64_t *Offset, unsigned UnitIndex,
- uint8_t &UnitType, bool &isUnitDWARF64) {
- uint64_t AbbrOffset, Length;
- uint8_t AddrSize = 0;
- uint16_t Version;
- bool Success = true;
-
- bool ValidLength = false;
- bool ValidVersion = false;
- bool ValidAddrSize = false;
- bool ValidType = true;
- bool ValidAbbrevOffset = true;
-
- uint64_t OffsetStart = *Offset;
- DwarfFormat Format;
- std::tie(Length, Format) = DebugInfoData.getInitialLength(Offset);
- isUnitDWARF64 = Format == DWARF64;
- Version = DebugInfoData.getU16(Offset);
-
- if (Version >= 5) {
- UnitType = DebugInfoData.getU8(Offset);
- AddrSize = DebugInfoData.getU8(Offset);
- AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
- ValidType = dwarf::isUnitType(UnitType);
- } else {
- UnitType = 0;
- AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
- AddrSize = DebugInfoData.getU8(Offset);
- }
-
- if (!DCtx.getDebugAbbrev()->getAbbreviationDeclarationSet(AbbrOffset))
- ValidAbbrevOffset = false;
-
- ValidLength = DebugInfoData.isValidOffset(OffsetStart + Length + 3);
- ValidVersion = DWARFContext::isSupportedVersion(Version);
- ValidAddrSize = DWARFContext::isAddressSizeSupported(AddrSize);
- if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
- !ValidType) {
- Success = false;
- error() << format("Units[%d] - start offset: 0x%08" PRIx64 " \n", UnitIndex,
- OffsetStart);
- if (!ValidLength)
- note() << "The length for this unit is too "
- "large for the .debug_info provided.\n";
- if (!ValidVersion)
- note() << "The 16 bit unit header version is not valid.\n";
- if (!ValidType)
- note() << "The unit type encoding is not valid.\n";
- if (!ValidAbbrevOffset)
- note() << "The offset into the .debug_abbrev section is "
- "not valid.\n";
- if (!ValidAddrSize)
- note() << "The address size is unsupported.\n";
- }
- *Offset = OffsetStart + Length + (isUnitDWARF64 ? 12 : 4);
- return Success;
-}
-
-unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
- unsigned NumUnitErrors = 0;
- unsigned NumDies = Unit.getNumDIEs();
- for (unsigned I = 0; I < NumDies; ++I) {
- auto Die = Unit.getDIEAtIndex(I);
-
- if (Die.getTag() == DW_TAG_null)
- continue;
-
- for (auto AttrValue : Die.attributes()) {
- NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
- NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
- }
-
+//===- DWARFVerifier.cpp --------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
+#include "llvm/ADT/SmallSet.h"
+#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
+#include "llvm/DebugInfo/DWARF/DWARFDie.h"
+#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/DebugInfo/DWARF/DWARFSection.h"
+#include "llvm/Support/DJB.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/WithColor.h"
+#include "llvm/Support/raw_ostream.h"
+#include <map>
+#include <set>
+#include <vector>
+
+using namespace llvm;
+using namespace dwarf;
+using namespace object;
+
+Optional<DWARFAddressRange>
+DWARFVerifier::DieRangeInfo::insert(const DWARFAddressRange &R) {
+ auto Begin = Ranges.begin();
+ auto End = Ranges.end();
+ auto Pos = std::lower_bound(Begin, End, R);
+
+ if (Pos != End) {
+ DWARFAddressRange Range(*Pos);
+ if (Pos->merge(R))
+ return Range;
+ }
+ if (Pos != Begin) {
+ auto Iter = Pos - 1;
+ DWARFAddressRange Range(*Iter);
+ if (Iter->merge(R))
+ return Range;
+ }
+
+ Ranges.insert(Pos, R);
+ return None;
+}
+
+DWARFVerifier::DieRangeInfo::die_range_info_iterator
+DWARFVerifier::DieRangeInfo::insert(const DieRangeInfo &RI) {
+ auto End = Children.end();
+ auto Iter = Children.begin();
+ while (Iter != End) {
+ if (Iter->intersects(RI))
+ return Iter;
+ ++Iter;
+ }
+ Children.insert(RI);
+ return Children.end();
+}
+
+bool DWARFVerifier::DieRangeInfo::contains(const DieRangeInfo &RHS) const {
+ auto I1 = Ranges.begin(), E1 = Ranges.end();
+ auto I2 = RHS.Ranges.begin(), E2 = RHS.Ranges.end();
+ if (I2 == E2)
+ return true;
+
+ 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 (!Covered)
+ return false;
+ if (R.LowPC < I1->HighPC)
+ R.LowPC = I1->HighPC;
+ ++I1;
+ }
+ return false;
+}
+
+bool DWARFVerifier::DieRangeInfo::intersects(const DieRangeInfo &RHS) const {
+ 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,
+ uint64_t *Offset, unsigned UnitIndex,
+ uint8_t &UnitType, bool &isUnitDWARF64) {
+ uint64_t AbbrOffset, Length;
+ uint8_t AddrSize = 0;
+ uint16_t Version;
+ bool Success = true;
+
+ bool ValidLength = false;
+ bool ValidVersion = false;
+ bool ValidAddrSize = false;
+ bool ValidType = true;
+ bool ValidAbbrevOffset = true;
+
+ uint64_t OffsetStart = *Offset;
+ DwarfFormat Format;
+ std::tie(Length, Format) = DebugInfoData.getInitialLength(Offset);
+ isUnitDWARF64 = Format == DWARF64;
+ Version = DebugInfoData.getU16(Offset);
+
+ if (Version >= 5) {
+ UnitType = DebugInfoData.getU8(Offset);
+ AddrSize = DebugInfoData.getU8(Offset);
+ AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
+ ValidType = dwarf::isUnitType(UnitType);
+ } else {
+ UnitType = 0;
+ AbbrOffset = isUnitDWARF64 ? DebugInfoData.getU64(Offset) : DebugInfoData.getU32(Offset);
+ AddrSize = DebugInfoData.getU8(Offset);
+ }
+
+ if (!DCtx.getDebugAbbrev()->getAbbreviationDeclarationSet(AbbrOffset))
+ ValidAbbrevOffset = false;
+
+ ValidLength = DebugInfoData.isValidOffset(OffsetStart + Length + 3);
+ ValidVersion = DWARFContext::isSupportedVersion(Version);
+ ValidAddrSize = DWARFContext::isAddressSizeSupported(AddrSize);
+ if (!ValidLength || !ValidVersion || !ValidAddrSize || !ValidAbbrevOffset ||
+ !ValidType) {
+ Success = false;
+ error() << format("Units[%d] - start offset: 0x%08" PRIx64 " \n", UnitIndex,
+ OffsetStart);
+ if (!ValidLength)
+ note() << "The length for this unit is too "
+ "large for the .debug_info provided.\n";
+ if (!ValidVersion)
+ note() << "The 16 bit unit header version is not valid.\n";
+ if (!ValidType)
+ note() << "The unit type encoding is not valid.\n";
+ if (!ValidAbbrevOffset)
+ note() << "The offset into the .debug_abbrev section is "
+ "not valid.\n";
+ if (!ValidAddrSize)
+ note() << "The address size is unsupported.\n";
+ }
+ *Offset = OffsetStart + Length + (isUnitDWARF64 ? 12 : 4);
+ return Success;
+}
+
+unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
+ unsigned NumUnitErrors = 0;
+ unsigned NumDies = Unit.getNumDIEs();
+ for (unsigned I = 0; I < NumDies; ++I) {
+ auto Die = Unit.getDIEAtIndex(I);
+
+ if (Die.getTag() == DW_TAG_null)
+ continue;
+
+ for (auto AttrValue : Die.attributes()) {
+ NumUnitErrors += verifyDebugInfoAttribute(Die, AttrValue);
+ NumUnitErrors += verifyDebugInfoForm(Die, AttrValue);
+ }
+
if (Die.hasChildren()) {
if (Die.getFirstChild().isValid() &&
Die.getFirstChild().getTag() == DW_TAG_null) {
@@ -181,372 +181,372 @@ unsigned DWARFVerifier::verifyUnitContents(DWARFUnit &Unit) {
}
}
- NumUnitErrors += verifyDebugInfoCallSite(Die);
- }
-
- DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
- if (!Die) {
- error() << "Compilation unit without DIE.\n";
- NumUnitErrors++;
- return NumUnitErrors;
- }
-
- if (!dwarf::isUnitType(Die.getTag())) {
- error() << "Compilation unit root DIE is not a unit DIE: "
- << dwarf::TagString(Die.getTag()) << ".\n";
- NumUnitErrors++;
- }
-
- uint8_t UnitType = Unit.getUnitType();
- if (!DWARFUnit::isMatchingUnitTypeAndTag(UnitType, Die.getTag())) {
- error() << "Compilation unit type (" << dwarf::UnitTypeString(UnitType)
- << ") and root DIE (" << dwarf::TagString(Die.getTag())
- << ") do not match.\n";
- NumUnitErrors++;
- }
-
- // According to DWARF Debugging Information Format Version 5,
- // 3.1.2 Skeleton Compilation Unit Entries:
- // "A skeleton compilation unit has no children."
- if (Die.getTag() == dwarf::DW_TAG_skeleton_unit && Die.hasChildren()) {
- error() << "Skeleton compilation unit has children.\n";
- NumUnitErrors++;
- }
-
- DieRangeInfo RI;
- NumUnitErrors += verifyDieRanges(Die, RI);
-
- return NumUnitErrors;
-}
-
-unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
- if (Die.getTag() != DW_TAG_call_site && Die.getTag() != DW_TAG_GNU_call_site)
- return 0;
-
- DWARFDie Curr = Die.getParent();
- for (; Curr.isValid() && !Curr.isSubprogramDIE(); Curr = Die.getParent()) {
- if (Curr.getTag() == DW_TAG_inlined_subroutine) {
- error() << "Call site entry nested within inlined subroutine:";
- Curr.dump(OS);
- return 1;
- }
- }
-
- if (!Curr.isValid()) {
- error() << "Call site entry not nested within a valid subprogram:";
- Die.dump(OS);
- return 1;
- }
-
- Optional<DWARFFormValue> CallAttr =
- Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_calls,
- DW_AT_call_all_tail_calls, DW_AT_GNU_all_call_sites,
- DW_AT_GNU_all_source_call_sites,
- DW_AT_GNU_all_tail_call_sites});
- if (!CallAttr) {
- error() << "Subprogram with call site entry has no DW_AT_call attribute:";
- Curr.dump(OS);
- Die.dump(OS, /*indent*/ 1);
- return 1;
- }
-
- return 0;
-}
-
-unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
- unsigned NumErrors = 0;
- if (Abbrev) {
- const DWARFAbbreviationDeclarationSet *AbbrDecls =
- Abbrev->getAbbreviationDeclarationSet(0);
- for (auto AbbrDecl : *AbbrDecls) {
- SmallDenseSet<uint16_t> AttributeSet;
- for (auto Attribute : AbbrDecl.attributes()) {
- auto Result = AttributeSet.insert(Attribute.Attr);
- if (!Result.second) {
- error() << "Abbreviation declaration contains multiple "
- << AttributeString(Attribute.Attr) << " attributes.\n";
- AbbrDecl.dump(OS);
- ++NumErrors;
- }
- }
- }
- }
- return NumErrors;
-}
-
-bool DWARFVerifier::handleDebugAbbrev() {
- OS << "Verifying .debug_abbrev...\n";
-
- const DWARFObject &DObj = DCtx.getDWARFObj();
- unsigned NumErrors = 0;
- if (!DObj.getAbbrevSection().empty())
- NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrev());
- if (!DObj.getAbbrevDWOSection().empty())
- NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrevDWO());
-
- return NumErrors == 0;
-}
-
-unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
- DWARFSectionKind SectionKind) {
- const DWARFObject &DObj = DCtx.getDWARFObj();
- DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
- unsigned NumDebugInfoErrors = 0;
- uint64_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
- uint8_t UnitType = 0;
- bool isUnitDWARF64 = false;
- bool isHeaderChainValid = true;
- bool hasDIE = DebugInfoData.isValidOffset(Offset);
- DWARFUnitVector TypeUnitVector;
- DWARFUnitVector CompileUnitVector;
- while (hasDIE) {
- OffsetStart = Offset;
- if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
- isUnitDWARF64)) {
- isHeaderChainValid = false;
- if (isUnitDWARF64)
- break;
- } else {
- DWARFUnitHeader Header;
- Header.extract(DCtx, DebugInfoData, &OffsetStart, SectionKind);
- DWARFUnit *Unit;
- switch (UnitType) {
- case dwarf::DW_UT_type:
- case dwarf::DW_UT_split_type: {
- Unit = TypeUnitVector.addUnit(std::make_unique<DWARFTypeUnit>(
- DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
- &DObj.getLocSection(), DObj.getStrSection(),
- DObj.getStrOffsetsSection(), &DObj.getAddrSection(),
- DObj.getLineSection(), DCtx.isLittleEndian(), false,
- TypeUnitVector));
- break;
- }
- case dwarf::DW_UT_skeleton:
- case dwarf::DW_UT_split_compile:
- case dwarf::DW_UT_compile:
- case dwarf::DW_UT_partial:
- // UnitType = 0 means that we are verifying a compile unit in DWARF v4.
- case 0: {
- Unit = CompileUnitVector.addUnit(std::make_unique<DWARFCompileUnit>(
- DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
- &DObj.getLocSection(), DObj.getStrSection(),
- DObj.getStrOffsetsSection(), &DObj.getAddrSection(),
- DObj.getLineSection(), DCtx.isLittleEndian(), false,
- CompileUnitVector));
- break;
- }
- default: { llvm_unreachable("Invalid UnitType."); }
- }
- NumDebugInfoErrors += verifyUnitContents(*Unit);
- }
- hasDIE = DebugInfoData.isValidOffset(Offset);
- ++UnitIdx;
- }
- if (UnitIdx == 0 && !hasDIE) {
- warn() << "Section is empty.\n";
- isHeaderChainValid = true;
- }
- if (!isHeaderChainValid)
- ++NumDebugInfoErrors;
- NumDebugInfoErrors += verifyDebugInfoReferences();
- return NumDebugInfoErrors;
-}
-
-bool DWARFVerifier::handleDebugInfo() {
- const DWARFObject &DObj = DCtx.getDWARFObj();
- unsigned NumErrors = 0;
-
- OS << "Verifying .debug_info Unit Header Chain...\n";
- DObj.forEachInfoSections([&](const DWARFSection &S) {
- NumErrors += verifyUnitSection(S, DW_SECT_INFO);
- });
-
- OS << "Verifying .debug_types Unit Header Chain...\n";
- DObj.forEachTypesSections([&](const DWARFSection &S) {
- NumErrors += verifyUnitSection(S, DW_SECT_EXT_TYPES);
- });
- return NumErrors == 0;
-}
-
-unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
- DieRangeInfo &ParentRI) {
- unsigned NumErrors = 0;
-
- if (!Die.isValid())
- return NumErrors;
-
- auto RangesOrError = Die.getAddressRanges();
- if (!RangesOrError) {
- // FIXME: Report the error.
- ++NumErrors;
- llvm::consumeError(RangesOrError.takeError());
- return NumErrors;
- }
-
- DWARFAddressRangesVector Ranges = RangesOrError.get();
- // Build RI for this DIE and check that ranges within this DIE do not
- // overlap.
- DieRangeInfo RI(Die);
-
- // TODO support object files better
- //
- // Some object file formats (i.e. non-MachO) support COMDAT. ELF in
- // particular does so by placing each function into a section. The DWARF data
- // for the function at that point uses a section relative DW_FORM_addrp for
- // the DW_AT_low_pc and a DW_FORM_data4 for the offset as the DW_AT_high_pc.
- // In such a case, when the Die is the CU, the ranges will overlap, and we
- // will flag valid conflicting ranges as invalid.
- //
- // For such targets, we should read the ranges from the CU and partition them
- // by the section id. The ranges within a particular section should be
- // disjoint, although the ranges across sections may overlap. We would map
- // the child die to the entity that it references and the section with which
- // it is associated. The child would then be checked against the range
- // information for the associated section.
- //
- // For now, simply elide the range verification for the CU DIEs if we are
- // processing an object file.
-
- if (!IsObjectFile || IsMachOObject || Die.getTag() != DW_TAG_compile_unit) {
- bool DumpDieAfterError = false;
- for (auto Range : Ranges) {
- if (!Range.valid()) {
- ++NumErrors;
- error() << "Invalid address range " << Range << "\n";
- DumpDieAfterError = true;
- continue;
- }
-
- // Verify that ranges don't intersect and also build up the DieRangeInfo
- // address ranges. Don't break out of the loop below early, or we will
- // think this DIE doesn't have all of the address ranges it is supposed
- // to have. Compile units often have DW_AT_ranges that can contain one or
- // more dead stripped address ranges which tend to all be at the same
- // address: 0 or -1.
- if (auto PrevRange = RI.insert(Range)) {
- ++NumErrors;
- error() << "DIE has overlapping ranges in DW_AT_ranges attribute: "
- << *PrevRange << " and " << Range << '\n';
- DumpDieAfterError = true;
- }
- }
- if (DumpDieAfterError)
- dump(Die, 2) << '\n';
- }
-
- // Verify that children don't intersect.
- const auto IntersectingChild = ParentRI.insert(RI);
- if (IntersectingChild != ParentRI.Children.end()) {
- ++NumErrors;
- error() << "DIEs have overlapping address ranges:";
- dump(Die);
- dump(IntersectingChild->Die) << '\n';
- }
-
- // Verify that ranges are contained within their parent.
- bool ShouldBeContained = !Ranges.empty() && !ParentRI.Ranges.empty() &&
- !(Die.getTag() == DW_TAG_subprogram &&
- ParentRI.Die.getTag() == DW_TAG_subprogram);
- if (ShouldBeContained && !ParentRI.contains(RI)) {
- ++NumErrors;
- error() << "DIE address ranges are not contained in its parent's ranges:";
- dump(ParentRI.Die);
- dump(Die, 2) << '\n';
- }
-
- // Recursively check children.
- for (DWARFDie Child : Die)
- NumErrors += verifyDieRanges(Child, RI);
-
- return NumErrors;
-}
-
-unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
- DWARFAttribute &AttrValue) {
- unsigned NumErrors = 0;
- auto ReportError = [&](const Twine &TitleMsg) {
- ++NumErrors;
- error() << TitleMsg << '\n';
- dump(Die) << '\n';
- };
-
- const DWARFObject &DObj = DCtx.getDWARFObj();
- const auto Attr = AttrValue.Attr;
- switch (Attr) {
- case DW_AT_ranges:
- // Make sure the offset in the DW_AT_ranges attribute is valid.
- if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
- unsigned DwarfVersion = Die.getDwarfUnit()->getVersion();
- const DWARFSection &RangeSection = DwarfVersion < 5
- ? DObj.getRangesSection()
- : DObj.getRnglistsSection();
- if (*SectionOffset >= RangeSection.Data.size())
- ReportError(
- "DW_AT_ranges offset is beyond " +
- StringRef(DwarfVersion < 5 ? ".debug_ranges" : ".debug_rnglists") +
- " bounds: " + llvm::formatv("{0:x8}", *SectionOffset));
- break;
- }
- ReportError("DIE has invalid DW_AT_ranges encoding:");
- break;
- case DW_AT_stmt_list:
- // Make sure the offset in the DW_AT_stmt_list attribute is valid.
- if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
- if (*SectionOffset >= DObj.getLineSection().Data.size())
- ReportError("DW_AT_stmt_list offset is beyond .debug_line bounds: " +
- llvm::formatv("{0:x8}", *SectionOffset));
- break;
- }
- ReportError("DIE has invalid DW_AT_stmt_list encoding:");
- break;
- case DW_AT_location: {
- if (Expected<std::vector<DWARFLocationExpression>> Loc =
- Die.getLocations(DW_AT_location)) {
- DWARFUnit *U = Die.getDwarfUnit();
- for (const auto &Entry : *Loc) {
- DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0);
- DWARFExpression Expression(Data, U->getAddressByteSize(),
- U->getFormParams().Format);
- bool Error = any_of(Expression, [](DWARFExpression::Operation &Op) {
- return Op.isError();
- });
- if (Error || !Expression.verify(U))
- ReportError("DIE contains invalid DWARF expression:");
- }
- } else
- ReportError(toString(Loc.takeError()));
- break;
- }
- case DW_AT_specification:
- case DW_AT_abstract_origin: {
- if (auto ReferencedDie = Die.getAttributeValueAsReferencedDie(Attr)) {
- auto DieTag = Die.getTag();
- auto RefTag = ReferencedDie.getTag();
- if (DieTag == RefTag)
- break;
- if (DieTag == DW_TAG_inlined_subroutine && RefTag == DW_TAG_subprogram)
- break;
- if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member)
- break;
- // This might be reference to a function declaration.
- if (DieTag == DW_TAG_GNU_call_site && RefTag == DW_TAG_subprogram)
- break;
- ReportError("DIE with tag " + TagString(DieTag) + " has " +
- AttributeString(Attr) +
- " that points to DIE with "
- "incompatible tag " +
- TagString(RefTag));
- }
- break;
- }
- case DW_AT_type: {
- DWARFDie TypeDie = Die.getAttributeValueAsReferencedDie(DW_AT_type);
- if (TypeDie && !isType(TypeDie.getTag())) {
- ReportError("DIE has " + AttributeString(Attr) +
- " with incompatible tag " + TagString(TypeDie.getTag()));
- }
- break;
- }
+ NumUnitErrors += verifyDebugInfoCallSite(Die);
+ }
+
+ DWARFDie Die = Unit.getUnitDIE(/* ExtractUnitDIEOnly = */ false);
+ if (!Die) {
+ error() << "Compilation unit without DIE.\n";
+ NumUnitErrors++;
+ return NumUnitErrors;
+ }
+
+ if (!dwarf::isUnitType(Die.getTag())) {
+ error() << "Compilation unit root DIE is not a unit DIE: "
+ << dwarf::TagString(Die.getTag()) << ".\n";
+ NumUnitErrors++;
+ }
+
+ uint8_t UnitType = Unit.getUnitType();
+ if (!DWARFUnit::isMatchingUnitTypeAndTag(UnitType, Die.getTag())) {
+ error() << "Compilation unit type (" << dwarf::UnitTypeString(UnitType)
+ << ") and root DIE (" << dwarf::TagString(Die.getTag())
+ << ") do not match.\n";
+ NumUnitErrors++;
+ }
+
+ // According to DWARF Debugging Information Format Version 5,
+ // 3.1.2 Skeleton Compilation Unit Entries:
+ // "A skeleton compilation unit has no children."
+ if (Die.getTag() == dwarf::DW_TAG_skeleton_unit && Die.hasChildren()) {
+ error() << "Skeleton compilation unit has children.\n";
+ NumUnitErrors++;
+ }
+
+ DieRangeInfo RI;
+ NumUnitErrors += verifyDieRanges(Die, RI);
+
+ return NumUnitErrors;
+}
+
+unsigned DWARFVerifier::verifyDebugInfoCallSite(const DWARFDie &Die) {
+ if (Die.getTag() != DW_TAG_call_site && Die.getTag() != DW_TAG_GNU_call_site)
+ return 0;
+
+ DWARFDie Curr = Die.getParent();
+ for (; Curr.isValid() && !Curr.isSubprogramDIE(); Curr = Die.getParent()) {
+ if (Curr.getTag() == DW_TAG_inlined_subroutine) {
+ error() << "Call site entry nested within inlined subroutine:";
+ Curr.dump(OS);
+ return 1;
+ }
+ }
+
+ if (!Curr.isValid()) {
+ error() << "Call site entry not nested within a valid subprogram:";
+ Die.dump(OS);
+ return 1;
+ }
+
+ Optional<DWARFFormValue> CallAttr =
+ Curr.find({DW_AT_call_all_calls, DW_AT_call_all_source_calls,
+ DW_AT_call_all_tail_calls, DW_AT_GNU_all_call_sites,
+ DW_AT_GNU_all_source_call_sites,
+ DW_AT_GNU_all_tail_call_sites});
+ if (!CallAttr) {
+ error() << "Subprogram with call site entry has no DW_AT_call attribute:";
+ Curr.dump(OS);
+ Die.dump(OS, /*indent*/ 1);
+ return 1;
+ }
+
+ return 0;
+}
+
+unsigned DWARFVerifier::verifyAbbrevSection(const DWARFDebugAbbrev *Abbrev) {
+ unsigned NumErrors = 0;
+ if (Abbrev) {
+ const DWARFAbbreviationDeclarationSet *AbbrDecls =
+ Abbrev->getAbbreviationDeclarationSet(0);
+ for (auto AbbrDecl : *AbbrDecls) {
+ SmallDenseSet<uint16_t> AttributeSet;
+ for (auto Attribute : AbbrDecl.attributes()) {
+ auto Result = AttributeSet.insert(Attribute.Attr);
+ if (!Result.second) {
+ error() << "Abbreviation declaration contains multiple "
+ << AttributeString(Attribute.Attr) << " attributes.\n";
+ AbbrDecl.dump(OS);
+ ++NumErrors;
+ }
+ }
+ }
+ }
+ return NumErrors;
+}
+
+bool DWARFVerifier::handleDebugAbbrev() {
+ OS << "Verifying .debug_abbrev...\n";
+
+ const DWARFObject &DObj = DCtx.getDWARFObj();
+ unsigned NumErrors = 0;
+ if (!DObj.getAbbrevSection().empty())
+ NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrev());
+ if (!DObj.getAbbrevDWOSection().empty())
+ NumErrors += verifyAbbrevSection(DCtx.getDebugAbbrevDWO());
+
+ return NumErrors == 0;
+}
+
+unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
+ DWARFSectionKind SectionKind) {
+ const DWARFObject &DObj = DCtx.getDWARFObj();
+ DWARFDataExtractor DebugInfoData(DObj, S, DCtx.isLittleEndian(), 0);
+ unsigned NumDebugInfoErrors = 0;
+ uint64_t OffsetStart = 0, Offset = 0, UnitIdx = 0;
+ uint8_t UnitType = 0;
+ bool isUnitDWARF64 = false;
+ bool isHeaderChainValid = true;
+ bool hasDIE = DebugInfoData.isValidOffset(Offset);
+ DWARFUnitVector TypeUnitVector;
+ DWARFUnitVector CompileUnitVector;
+ while (hasDIE) {
+ OffsetStart = Offset;
+ if (!verifyUnitHeader(DebugInfoData, &Offset, UnitIdx, UnitType,
+ isUnitDWARF64)) {
+ isHeaderChainValid = false;
+ if (isUnitDWARF64)
+ break;
+ } else {
+ DWARFUnitHeader Header;
+ Header.extract(DCtx, DebugInfoData, &OffsetStart, SectionKind);
+ DWARFUnit *Unit;
+ switch (UnitType) {
+ case dwarf::DW_UT_type:
+ case dwarf::DW_UT_split_type: {
+ Unit = TypeUnitVector.addUnit(std::make_unique<DWARFTypeUnit>(
+ DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
+ &DObj.getLocSection(), DObj.getStrSection(),
+ DObj.getStrOffsetsSection(), &DObj.getAddrSection(),
+ DObj.getLineSection(), DCtx.isLittleEndian(), false,
+ TypeUnitVector));
+ break;
+ }
+ case dwarf::DW_UT_skeleton:
+ case dwarf::DW_UT_split_compile:
+ case dwarf::DW_UT_compile:
+ case dwarf::DW_UT_partial:
+ // UnitType = 0 means that we are verifying a compile unit in DWARF v4.
+ case 0: {
+ Unit = CompileUnitVector.addUnit(std::make_unique<DWARFCompileUnit>(
+ DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangesSection(),
+ &DObj.getLocSection(), DObj.getStrSection(),
+ DObj.getStrOffsetsSection(), &DObj.getAddrSection(),
+ DObj.getLineSection(), DCtx.isLittleEndian(), false,
+ CompileUnitVector));
+ break;
+ }
+ default: { llvm_unreachable("Invalid UnitType."); }
+ }
+ NumDebugInfoErrors += verifyUnitContents(*Unit);
+ }
+ hasDIE = DebugInfoData.isValidOffset(Offset);
+ ++UnitIdx;
+ }
+ if (UnitIdx == 0 && !hasDIE) {
+ warn() << "Section is empty.\n";
+ isHeaderChainValid = true;
+ }
+ if (!isHeaderChainValid)
+ ++NumDebugInfoErrors;
+ NumDebugInfoErrors += verifyDebugInfoReferences();
+ return NumDebugInfoErrors;
+}
+
+bool DWARFVerifier::handleDebugInfo() {
+ const DWARFObject &DObj = DCtx.getDWARFObj();
+ unsigned NumErrors = 0;
+
+ OS << "Verifying .debug_info Unit Header Chain...\n";
+ DObj.forEachInfoSections([&](const DWARFSection &S) {
+ NumErrors += verifyUnitSection(S, DW_SECT_INFO);
+ });
+
+ OS << "Verifying .debug_types Unit Header Chain...\n";
+ DObj.forEachTypesSections([&](const DWARFSection &S) {
+ NumErrors += verifyUnitSection(S, DW_SECT_EXT_TYPES);
+ });
+ return NumErrors == 0;
+}
+
+unsigned DWARFVerifier::verifyDieRanges(const DWARFDie &Die,
+ DieRangeInfo &ParentRI) {
+ unsigned NumErrors = 0;
+
+ if (!Die.isValid())
+ return NumErrors;
+
+ auto RangesOrError = Die.getAddressRanges();
+ if (!RangesOrError) {
+ // FIXME: Report the error.
+ ++NumErrors;
+ llvm::consumeError(RangesOrError.takeError());
+ return NumErrors;
+ }
+
+ DWARFAddressRangesVector Ranges = RangesOrError.get();
+ // Build RI for this DIE and check that ranges within this DIE do not
+ // overlap.
+ DieRangeInfo RI(Die);
+
+ // TODO support object files better
+ //
+ // Some object file formats (i.e. non-MachO) support COMDAT. ELF in
+ // particular does so by placing each function into a section. The DWARF data
+ // for the function at that point uses a section relative DW_FORM_addrp for
+ // the DW_AT_low_pc and a DW_FORM_data4 for the offset as the DW_AT_high_pc.
+ // In such a case, when the Die is the CU, the ranges will overlap, and we
+ // will flag valid conflicting ranges as invalid.
+ //
+ // For such targets, we should read the ranges from the CU and partition them
+ // by the section id. The ranges within a particular section should be
+ // disjoint, although the ranges across sections may overlap. We would map
+ // the child die to the entity that it references and the section with which
+ // it is associated. The child would then be checked against the range
+ // information for the associated section.
+ //
+ // For now, simply elide the range verification for the CU DIEs if we are
+ // processing an object file.
+
+ if (!IsObjectFile || IsMachOObject || Die.getTag() != DW_TAG_compile_unit) {
+ bool DumpDieAfterError = false;
+ for (auto Range : Ranges) {
+ if (!Range.valid()) {
+ ++NumErrors;
+ error() << "Invalid address range " << Range << "\n";
+ DumpDieAfterError = true;
+ continue;
+ }
+
+ // Verify that ranges don't intersect and also build up the DieRangeInfo
+ // address ranges. Don't break out of the loop below early, or we will
+ // think this DIE doesn't have all of the address ranges it is supposed
+ // to have. Compile units often have DW_AT_ranges that can contain one or
+ // more dead stripped address ranges which tend to all be at the same
+ // address: 0 or -1.
+ if (auto PrevRange = RI.insert(Range)) {
+ ++NumErrors;
+ error() << "DIE has overlapping ranges in DW_AT_ranges attribute: "
+ << *PrevRange << " and " << Range << '\n';
+ DumpDieAfterError = true;
+ }
+ }
+ if (DumpDieAfterError)
+ dump(Die, 2) << '\n';
+ }
+
+ // Verify that children don't intersect.
+ const auto IntersectingChild = ParentRI.insert(RI);
+ if (IntersectingChild != ParentRI.Children.end()) {
+ ++NumErrors;
+ error() << "DIEs have overlapping address ranges:";
+ dump(Die);
+ dump(IntersectingChild->Die) << '\n';
+ }
+
+ // Verify that ranges are contained within their parent.
+ bool ShouldBeContained = !Ranges.empty() && !ParentRI.Ranges.empty() &&
+ !(Die.getTag() == DW_TAG_subprogram &&
+ ParentRI.Die.getTag() == DW_TAG_subprogram);
+ if (ShouldBeContained && !ParentRI.contains(RI)) {
+ ++NumErrors;
+ error() << "DIE address ranges are not contained in its parent's ranges:";
+ dump(ParentRI.Die);
+ dump(Die, 2) << '\n';
+ }
+
+ // Recursively check children.
+ for (DWARFDie Child : Die)
+ NumErrors += verifyDieRanges(Child, RI);
+
+ return NumErrors;
+}
+
+unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
+ DWARFAttribute &AttrValue) {
+ unsigned NumErrors = 0;
+ auto ReportError = [&](const Twine &TitleMsg) {
+ ++NumErrors;
+ error() << TitleMsg << '\n';
+ dump(Die) << '\n';
+ };
+
+ const DWARFObject &DObj = DCtx.getDWARFObj();
+ const auto Attr = AttrValue.Attr;
+ switch (Attr) {
+ case DW_AT_ranges:
+ // Make sure the offset in the DW_AT_ranges attribute is valid.
+ if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
+ unsigned DwarfVersion = Die.getDwarfUnit()->getVersion();
+ const DWARFSection &RangeSection = DwarfVersion < 5
+ ? DObj.getRangesSection()
+ : DObj.getRnglistsSection();
+ if (*SectionOffset >= RangeSection.Data.size())
+ ReportError(
+ "DW_AT_ranges offset is beyond " +
+ StringRef(DwarfVersion < 5 ? ".debug_ranges" : ".debug_rnglists") +
+ " bounds: " + llvm::formatv("{0:x8}", *SectionOffset));
+ break;
+ }
+ ReportError("DIE has invalid DW_AT_ranges encoding:");
+ break;
+ case DW_AT_stmt_list:
+ // Make sure the offset in the DW_AT_stmt_list attribute is valid.
+ if (auto SectionOffset = AttrValue.Value.getAsSectionOffset()) {
+ if (*SectionOffset >= DObj.getLineSection().Data.size())
+ ReportError("DW_AT_stmt_list offset is beyond .debug_line bounds: " +
+ llvm::formatv("{0:x8}", *SectionOffset));
+ break;
+ }
+ ReportError("DIE has invalid DW_AT_stmt_list encoding:");
+ break;
+ case DW_AT_location: {
+ if (Expected<std::vector<DWARFLocationExpression>> Loc =
+ Die.getLocations(DW_AT_location)) {
+ DWARFUnit *U = Die.getDwarfUnit();
+ for (const auto &Entry : *Loc) {
+ DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(), 0);
+ DWARFExpression Expression(Data, U->getAddressByteSize(),
+ U->getFormParams().Format);
+ bool Error = any_of(Expression, [](DWARFExpression::Operation &Op) {
+ return Op.isError();
+ });
+ if (Error || !Expression.verify(U))
+ ReportError("DIE contains invalid DWARF expression:");
+ }
+ } else
+ ReportError(toString(Loc.takeError()));
+ break;
+ }
+ case DW_AT_specification:
+ case DW_AT_abstract_origin: {
+ if (auto ReferencedDie = Die.getAttributeValueAsReferencedDie(Attr)) {
+ auto DieTag = Die.getTag();
+ auto RefTag = ReferencedDie.getTag();
+ if (DieTag == RefTag)
+ break;
+ if (DieTag == DW_TAG_inlined_subroutine && RefTag == DW_TAG_subprogram)
+ break;
+ if (DieTag == DW_TAG_variable && RefTag == DW_TAG_member)
+ break;
+ // This might be reference to a function declaration.
+ if (DieTag == DW_TAG_GNU_call_site && RefTag == DW_TAG_subprogram)
+ break;
+ ReportError("DIE with tag " + TagString(DieTag) + " has " +
+ AttributeString(Attr) +
+ " that points to DIE with "
+ "incompatible tag " +
+ TagString(RefTag));
+ }
+ break;
+ }
+ case DW_AT_type: {
+ DWARFDie TypeDie = Die.getAttributeValueAsReferencedDie(DW_AT_type);
+ if (TypeDie && !isType(TypeDie.getTag())) {
+ ReportError("DIE has " + AttributeString(Attr) +
+ " with incompatible tag " + TagString(TypeDie.getTag()));
+ }
+ break;
+ }
case DW_AT_call_file:
case DW_AT_decl_file: {
if (auto FileIdx = AttrValue.Value.getAsUnsignedConstant()) {
@@ -580,960 +580,960 @@ unsigned DWARFVerifier::verifyDebugInfoAttribute(const DWARFDie &Die,
}
break;
}
- default:
- break;
- }
- return NumErrors;
-}
-
-unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
- DWARFAttribute &AttrValue) {
- const DWARFObject &DObj = DCtx.getDWARFObj();
- auto DieCU = Die.getDwarfUnit();
- unsigned NumErrors = 0;
- const auto Form = AttrValue.Value.getForm();
- switch (Form) {
- case DW_FORM_ref1:
- case DW_FORM_ref2:
- case DW_FORM_ref4:
- case DW_FORM_ref8:
- case DW_FORM_ref_udata: {
- // Verify all CU relative references are valid CU offsets.
- Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
- assert(RefVal);
- if (RefVal) {
- auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
- auto CUOffset = AttrValue.Value.getRawUValue();
- if (CUOffset >= CUSize) {
- ++NumErrors;
- error() << FormEncodingString(Form) << " CU offset "
- << format("0x%08" PRIx64, CUOffset)
- << " is invalid (must be less than CU size of "
- << format("0x%08" PRIx64, CUSize) << "):\n";
- Die.dump(OS, 0, DumpOpts);
- dump(Die) << '\n';
- } else {
- // Valid reference, but we will verify it points to an actual
- // DIE later.
- ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
- }
- }
- break;
- }
- case DW_FORM_ref_addr: {
- // Verify all absolute DIE references have valid offsets in the
- // .debug_info section.
- Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
- assert(RefVal);
- if (RefVal) {
- if (*RefVal >= DieCU->getInfoSection().Data.size()) {
- ++NumErrors;
- error() << "DW_FORM_ref_addr offset beyond .debug_info "
- "bounds:\n";
- dump(Die) << '\n';
- } else {
- // Valid reference, but we will verify it points to an actual
- // DIE later.
- ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
- }
- }
- break;
- }
- case DW_FORM_strp: {
- auto SecOffset = AttrValue.Value.getAsSectionOffset();
- assert(SecOffset); // DW_FORM_strp is a section offset.
- if (SecOffset && *SecOffset >= DObj.getStrSection().size()) {
- ++NumErrors;
- error() << "DW_FORM_strp offset beyond .debug_str bounds:\n";
- dump(Die) << '\n';
- }
- break;
- }
- case DW_FORM_strx:
- case DW_FORM_strx1:
- case DW_FORM_strx2:
- case DW_FORM_strx3:
- case DW_FORM_strx4: {
- auto Index = AttrValue.Value.getRawUValue();
- auto DieCU = Die.getDwarfUnit();
- // Check that we have a valid DWARF v5 string offsets table.
- if (!DieCU->getStringOffsetsTableContribution()) {
- ++NumErrors;
- error() << FormEncodingString(Form)
- << " used without a valid string offsets table:\n";
- dump(Die) << '\n';
- break;
- }
- // 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 =
- (uint64_t)DieCU->getStringOffsetsBase() + Index * ItemSize;
- if (DObj.getStrOffsetsSection().Data.size() < Offset + ItemSize) {
- ++NumErrors;
- error() << FormEncodingString(Form) << " uses index "
- << format("%" PRIu64, Index) << ", which is too large:\n";
- dump(Die) << '\n';
- break;
- }
- // Check that the string offset is valid.
- uint64_t StringOffset = *DieCU->getStringOffsetSectionItem(Index);
- if (StringOffset >= DObj.getStrSection().size()) {
- ++NumErrors;
- error() << FormEncodingString(Form) << " uses index "
- << format("%" PRIu64, Index)
- << ", but the referenced string"
- " offset is beyond .debug_str bounds:\n";
- dump(Die) << '\n';
- }
- break;
- }
- default:
- break;
- }
- return NumErrors;
-}
-
-unsigned DWARFVerifier::verifyDebugInfoReferences() {
- // Take all references and make sure they point to an actual DIE by
- // getting the DIE by offset and emitting an error
- OS << "Verifying .debug_info references...\n";
- unsigned NumErrors = 0;
- for (const std::pair<const uint64_t, std::set<uint64_t>> &Pair :
- ReferenceToDIEOffsets) {
- if (DCtx.getDIEForOffset(Pair.first))
- continue;
- ++NumErrors;
- error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
- << ". Offset is in between DIEs:\n";
- for (auto Offset : Pair.second)
- dump(DCtx.getDIEForOffset(Offset)) << '\n';
- OS << "\n";
- }
- return NumErrors;
-}
-
-void DWARFVerifier::verifyDebugLineStmtOffsets() {
- std::map<uint64_t, DWARFDie> StmtListToDie;
- for (const auto &CU : DCtx.compile_units()) {
- auto Die = CU->getUnitDIE();
- // Get the attribute value as a section offset. No need to produce an
- // error here if the encoding isn't correct because we validate this in
- // the .debug_info verifier.
- auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
- if (!StmtSectionOffset)
- continue;
- const uint64_t LineTableOffset = *StmtSectionOffset;
- auto LineTable = DCtx.getLineTableForUnit(CU.get());
- if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
- if (!LineTable) {
- ++NumDebugLineErrors;
- error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset)
- << "] was not able to be parsed for CU:\n";
- dump(Die) << '\n';
- continue;
- }
- } else {
- // Make sure we don't get a valid line table back if the offset is wrong.
- assert(LineTable == nullptr);
- // Skip this line table as it isn't valid. No need to create an error
- // here because we validate this in the .debug_info verifier.
- continue;
- }
- auto Iter = StmtListToDie.find(LineTableOffset);
- if (Iter != StmtListToDie.end()) {
- ++NumDebugLineErrors;
- error() << "two compile unit DIEs, "
- << format("0x%08" PRIx64, Iter->second.getOffset()) << " and "
- << format("0x%08" PRIx64, Die.getOffset())
- << ", have the same DW_AT_stmt_list section offset:\n";
- dump(Iter->second);
- dump(Die) << '\n';
- // Already verified this line table before, no need to do it again.
- continue;
- }
- StmtListToDie[LineTableOffset] = Die;
- }
-}
-
-void DWARFVerifier::verifyDebugLineRows() {
- for (const auto &CU : DCtx.compile_units()) {
- auto Die = CU->getUnitDIE();
- auto LineTable = DCtx.getLineTableForUnit(CU.get());
- // If there is no line table we will have created an error in the
- // .debug_info verifier or in verifyDebugLineStmtOffsets().
- if (!LineTable)
- continue;
-
- // Verify prologue.
- uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
- uint32_t FileIndex = 1;
- StringMap<uint16_t> FullPathMap;
- for (const auto &FileName : LineTable->Prologue.FileNames) {
- // Verify directory index.
- if (FileName.DirIdx > MaxDirIndex) {
- ++NumDebugLineErrors;
- error() << ".debug_line["
- << format("0x%08" PRIx64,
- *toSectionOffset(Die.find(DW_AT_stmt_list)))
- << "].prologue.file_names[" << FileIndex
- << "].dir_idx contains an invalid index: " << FileName.DirIdx
- << "\n";
- }
-
- // Check file paths for duplicates.
- std::string FullPath;
- const bool HasFullPath = LineTable->getFileNameByIndex(
- FileIndex, CU->getCompilationDir(),
- DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FullPath);
- assert(HasFullPath && "Invalid index?");
- (void)HasFullPath;
- auto It = FullPathMap.find(FullPath);
- if (It == FullPathMap.end())
- FullPathMap[FullPath] = FileIndex;
- else if (It->second != FileIndex) {
- warn() << ".debug_line["
- << format("0x%08" PRIx64,
- *toSectionOffset(Die.find(DW_AT_stmt_list)))
- << "].prologue.file_names[" << FileIndex
- << "] is a duplicate of file_names[" << It->second << "]\n";
- }
-
- FileIndex++;
- }
-
- // Verify rows.
- uint64_t PrevAddress = 0;
- uint32_t RowIndex = 0;
- for (const auto &Row : LineTable->Rows) {
- // Verify row address.
- if (Row.Address.Address < PrevAddress) {
- ++NumDebugLineErrors;
- error() << ".debug_line["
- << format("0x%08" PRIx64,
- *toSectionOffset(Die.find(DW_AT_stmt_list)))
- << "] row[" << RowIndex
- << "] decreases in address from previous row:\n";
-
- DWARFDebugLine::Row::dumpTableHeader(OS, 0);
- if (RowIndex > 0)
- LineTable->Rows[RowIndex - 1].dump(OS);
- Row.dump(OS);
- OS << '\n';
- }
-
- // Verify file index.
- 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 [" << (isDWARF5 ? "0," : "1,")
- << LineTable->Prologue.FileNames.size()
- << (isDWARF5 ? ")" : "]") << "):\n";
- DWARFDebugLine::Row::dumpTableHeader(OS, 0);
- Row.dump(OS);
- OS << '\n';
- }
- if (Row.EndSequence)
- PrevAddress = 0;
- else
- PrevAddress = Row.Address.Address;
- ++RowIndex;
- }
- }
-}
-
-DWARFVerifier::DWARFVerifier(raw_ostream &S, DWARFContext &D,
- DIDumpOptions DumpOpts)
- : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)), IsObjectFile(false),
- IsMachOObject(false) {
- if (const auto *F = DCtx.getDWARFObj().getFile()) {
- IsObjectFile = F->isRelocatableObject();
- IsMachOObject = F->isMachO();
- }
-}
-
-bool DWARFVerifier::handleDebugLine() {
- NumDebugLineErrors = 0;
- OS << "Verifying .debug_line...\n";
- verifyDebugLineStmtOffsets();
- verifyDebugLineRows();
- return NumDebugLineErrors == 0;
-}
-
-unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
- DataExtractor *StrData,
- const char *SectionName) {
- unsigned NumErrors = 0;
- DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), *AccelSection,
- DCtx.isLittleEndian(), 0);
- AppleAcceleratorTable AccelTable(AccelSectionData, *StrData);
-
- OS << "Verifying " << SectionName << "...\n";
-
- // Verify that the fixed part of the header is not too short.
- if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
- error() << "Section is too small to fit a section header.\n";
- return 1;
- }
-
- // Verify that the section is not too short.
- if (Error E = AccelTable.extract()) {
- error() << toString(std::move(E)) << '\n';
- return 1;
- }
-
- // Verify that all buckets have a valid hash index or are empty.
- uint32_t NumBuckets = AccelTable.getNumBuckets();
- uint32_t NumHashes = AccelTable.getNumHashes();
-
- uint64_t BucketsOffset =
- AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
- uint64_t HashesBase = BucketsOffset + NumBuckets * 4;
- uint64_t OffsetsBase = HashesBase + NumHashes * 4;
- for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
- uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
- if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
- error() << format("Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
- HashIdx);
- ++NumErrors;
- }
- }
- uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
- if (NumAtoms == 0) {
- error() << "No atoms: failed to read HashData.\n";
- return 1;
- }
- if (!AccelTable.validateForms()) {
- error() << "Unsupported form: failed to read HashData.\n";
- return 1;
- }
-
- for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
- uint64_t HashOffset = HashesBase + 4 * HashIdx;
- uint64_t DataOffset = OffsetsBase + 4 * HashIdx;
- uint32_t Hash = AccelSectionData.getU32(&HashOffset);
- uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
- if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
- sizeof(uint64_t))) {
- error() << format("Hash[%d] has invalid HashData offset: "
- "0x%08" PRIx64 ".\n",
- HashIdx, HashDataOffset);
- ++NumErrors;
- }
-
- uint64_t StrpOffset;
- uint64_t StringOffset;
- uint32_t StringCount = 0;
- uint64_t Offset;
- unsigned Tag;
- while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
- const uint32_t NumHashDataObjects =
- AccelSectionData.getU32(&HashDataOffset);
- for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
- ++HashDataIdx) {
- std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset);
- auto Die = DCtx.getDIEForOffset(Offset);
- if (!Die) {
- const uint32_t BucketIdx =
- NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
- StringOffset = StrpOffset;
- const char *Name = StrData->getCStr(&StringOffset);
- if (!Name)
- Name = "<NULL>";
-
- error() << format(
- "%s Bucket[%d] Hash[%d] = 0x%08x "
- "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " "
- "is not a valid DIE offset for \"%s\".\n",
- SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
- HashDataIdx, Offset, Name);
-
- ++NumErrors;
- continue;
- }
- if ((Tag != dwarf::DW_TAG_null) && (Die.getTag() != Tag)) {
- error() << "Tag " << dwarf::TagString(Tag)
- << " in accelerator table does not match Tag "
- << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
- << "].\n";
- ++NumErrors;
- }
- }
- ++StringCount;
- }
- }
- return NumErrors;
-}
-
-unsigned
-DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
- // A map from CU offset to the (first) Name Index offset which claims to index
- // this CU.
- DenseMap<uint64_t, uint64_t> CUMap;
- const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max();
-
- CUMap.reserve(DCtx.getNumCompileUnits());
- for (const auto &CU : DCtx.compile_units())
- CUMap[CU->getOffset()] = NotIndexed;
-
- unsigned NumErrors = 0;
- for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
- if (NI.getCUCount() == 0) {
- error() << formatv("Name Index @ {0:x} does not index any CU\n",
- NI.getUnitOffset());
- ++NumErrors;
- continue;
- }
- for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
- uint64_t Offset = NI.getCUOffset(CU);
- auto Iter = CUMap.find(Offset);
-
- if (Iter == CUMap.end()) {
- error() << formatv(
- "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
- NI.getUnitOffset(), Offset);
- ++NumErrors;
- continue;
- }
-
- if (Iter->second != NotIndexed) {
- error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
- "this CU is already indexed by Name Index @ {2:x}\n",
- NI.getUnitOffset(), Offset, Iter->second);
- continue;
- }
- Iter->second = NI.getUnitOffset();
- }
- }
-
- for (const auto &KV : CUMap) {
- if (KV.second == NotIndexed)
- warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
- }
-
- return NumErrors;
-}
-
-unsigned
-DWARFVerifier::verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
- const DataExtractor &StrData) {
- struct BucketInfo {
- uint32_t Bucket;
- uint32_t Index;
-
- constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
- : Bucket(Bucket), Index(Index) {}
- bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; }
- };
-
- uint32_t NumErrors = 0;
- if (NI.getBucketCount() == 0) {
- warn() << formatv("Name Index @ {0:x} does not contain a hash table.\n",
- NI.getUnitOffset());
- return NumErrors;
- }
-
- // Build up a list of (Bucket, Index) pairs. We use this later to verify that
- // each Name is reachable from the appropriate bucket.
- std::vector<BucketInfo> BucketStarts;
- BucketStarts.reserve(NI.getBucketCount() + 1);
- for (uint32_t Bucket = 0, End = NI.getBucketCount(); Bucket < End; ++Bucket) {
- uint32_t Index = NI.getBucketArrayEntry(Bucket);
- if (Index > NI.getNameCount()) {
- error() << formatv("Bucket {0} of Name Index @ {1:x} contains invalid "
- "value {2}. Valid range is [0, {3}].\n",
- Bucket, NI.getUnitOffset(), Index, NI.getNameCount());
- ++NumErrors;
- continue;
- }
- if (Index > 0)
- BucketStarts.emplace_back(Bucket, Index);
- }
-
- // If there were any buckets with invalid values, skip further checks as they
- // will likely produce many errors which will only confuse the actual root
- // problem.
- if (NumErrors > 0)
- return NumErrors;
-
- // Sort the list in the order of increasing "Index" entries.
- array_pod_sort(BucketStarts.begin(), BucketStarts.end());
-
- // Insert a sentinel entry at the end, so we can check that the end of the
- // table is covered in the loop below.
- BucketStarts.emplace_back(NI.getBucketCount(), NI.getNameCount() + 1);
-
- // Loop invariant: NextUncovered is the (1-based) index of the first Name
- // which is not reachable by any of the buckets we processed so far (and
- // hasn't been reported as uncovered).
- uint32_t NextUncovered = 1;
- for (const BucketInfo &B : BucketStarts) {
- // Under normal circumstances B.Index be equal to NextUncovered, but it can
- // be less if a bucket points to names which are already known to be in some
- // bucket we processed earlier. In that case, we won't trigger this error,
- // but report the mismatched hash value error instead. (We know the hash
- // will not match because we have already verified that the name's hash
- // puts it into the previous bucket.)
- if (B.Index > NextUncovered) {
- error() << formatv("Name Index @ {0:x}: Name table entries [{1}, {2}] "
- "are not covered by the hash table.\n",
- NI.getUnitOffset(), NextUncovered, B.Index - 1);
- ++NumErrors;
- }
- uint32_t Idx = B.Index;
-
- // The rest of the checks apply only to non-sentinel entries.
- if (B.Bucket == NI.getBucketCount())
- break;
-
- // This triggers if a non-empty bucket points to a name with a mismatched
- // hash. Clients are likely to interpret this as an empty bucket, because a
- // mismatched hash signals the end of a bucket, but if this is indeed an
- // empty bucket, the producer should have signalled this by marking the
- // bucket as empty.
- uint32_t FirstHash = NI.getHashArrayEntry(Idx);
- if (FirstHash % NI.getBucketCount() != B.Bucket) {
- error() << formatv(
- "Name Index @ {0:x}: Bucket {1} is not empty but points to a "
- "mismatched hash value {2:x} (belonging to bucket {3}).\n",
- NI.getUnitOffset(), B.Bucket, FirstHash,
- FirstHash % NI.getBucketCount());
- ++NumErrors;
- }
-
- // This find the end of this bucket and also verifies that all the hashes in
- // this bucket are correct by comparing the stored hashes to the ones we
- // compute ourselves.
- while (Idx <= NI.getNameCount()) {
- uint32_t Hash = NI.getHashArrayEntry(Idx);
- if (Hash % NI.getBucketCount() != B.Bucket)
- break;
-
- const char *Str = NI.getNameTableEntry(Idx).getString();
- if (caseFoldingDjbHash(Str) != Hash) {
- error() << formatv("Name Index @ {0:x}: String ({1}) at index {2} "
- "hashes to {3:x}, but "
- "the Name Index hash is {4:x}\n",
- NI.getUnitOffset(), Str, Idx,
- caseFoldingDjbHash(Str), Hash);
- ++NumErrors;
- }
-
- ++Idx;
- }
- NextUncovered = std::max(NextUncovered, Idx);
- }
- return NumErrors;
-}
-
-unsigned DWARFVerifier::verifyNameIndexAttribute(
- const DWARFDebugNames::NameIndex &NI, const DWARFDebugNames::Abbrev &Abbr,
- DWARFDebugNames::AttributeEncoding AttrEnc) {
- StringRef FormName = dwarf::FormEncodingString(AttrEnc.Form);
- if (FormName.empty()) {
- error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
- "unknown form: {3}.\n",
- NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
- AttrEnc.Form);
- return 1;
- }
-
- if (AttrEnc.Index == DW_IDX_type_hash) {
- if (AttrEnc.Form != dwarf::DW_FORM_data8) {
- error() << formatv(
- "NameIndex @ {0:x}: Abbreviation {1:x}: DW_IDX_type_hash "
- "uses an unexpected form {2} (should be {3}).\n",
- NI.getUnitOffset(), Abbr.Code, AttrEnc.Form, dwarf::DW_FORM_data8);
- return 1;
- }
- }
-
- // A list of known index attributes and their expected form classes.
- // DW_IDX_type_hash is handled specially in the check above, as it has a
- // specific form (not just a form class) we should expect.
- struct FormClassTable {
- dwarf::Index Index;
- DWARFFormValue::FormClass Class;
- StringLiteral ClassName;
- };
- static constexpr FormClassTable Table[] = {
- {dwarf::DW_IDX_compile_unit, DWARFFormValue::FC_Constant, {"constant"}},
- {dwarf::DW_IDX_type_unit, DWARFFormValue::FC_Constant, {"constant"}},
- {dwarf::DW_IDX_die_offset, DWARFFormValue::FC_Reference, {"reference"}},
- {dwarf::DW_IDX_parent, DWARFFormValue::FC_Constant, {"constant"}},
- };
-
- ArrayRef<FormClassTable> TableRef(Table);
- auto Iter = find_if(TableRef, [AttrEnc](const FormClassTable &T) {
- return T.Index == AttrEnc.Index;
- });
- if (Iter == TableRef.end()) {
- warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains an "
- "unknown index attribute: {2}.\n",
- NI.getUnitOffset(), Abbr.Code, AttrEnc.Index);
- return 0;
- }
-
- if (!DWARFFormValue(AttrEnc.Form).isFormClass(Iter->Class)) {
- error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
- "unexpected form {3} (expected form class {4}).\n",
- NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
- AttrEnc.Form, Iter->ClassName);
- return 1;
- }
- return 0;
-}
-
-unsigned
-DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
- if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
- warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
- "not currently supported.\n",
- NI.getUnitOffset());
- return 0;
- }
-
- unsigned NumErrors = 0;
- for (const auto &Abbrev : NI.getAbbrevs()) {
- StringRef TagName = dwarf::TagString(Abbrev.Tag);
- if (TagName.empty()) {
- warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} references an "
- "unknown tag: {2}.\n",
- NI.getUnitOffset(), Abbrev.Code, Abbrev.Tag);
- }
- SmallSet<unsigned, 5> Attributes;
- for (const auto &AttrEnc : Abbrev.Attributes) {
- if (!Attributes.insert(AttrEnc.Index).second) {
- error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains "
- "multiple {2} attributes.\n",
- NI.getUnitOffset(), Abbrev.Code, AttrEnc.Index);
- ++NumErrors;
- continue;
- }
- NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
- }
-
- if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
- error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
- "and abbreviation {1:x} has no {2} attribute.\n",
- NI.getUnitOffset(), Abbrev.Code,
- dwarf::DW_IDX_compile_unit);
- ++NumErrors;
- }
- if (!Attributes.count(dwarf::DW_IDX_die_offset)) {
- error() << formatv(
- "NameIndex @ {0:x}: Abbreviation {1:x} has no {2} attribute.\n",
- NI.getUnitOffset(), Abbrev.Code, dwarf::DW_IDX_die_offset);
- ++NumErrors;
- }
- }
- return NumErrors;
-}
-
-static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE,
- bool IncludeLinkageName = true) {
- SmallVector<StringRef, 2> Result;
- if (const char *Str = DIE.getName(DINameKind::ShortName))
- Result.emplace_back(Str);
- else if (DIE.getTag() == dwarf::DW_TAG_namespace)
- Result.emplace_back("(anonymous namespace)");
-
- if (IncludeLinkageName) {
- if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
- if (Result.empty() || Result[0] != Str)
- Result.emplace_back(Str);
- }
- }
-
- return Result;
-}
-
-unsigned DWARFVerifier::verifyNameIndexEntries(
- const DWARFDebugNames::NameIndex &NI,
- const DWARFDebugNames::NameTableEntry &NTE) {
- // Verifying type unit indexes not supported.
- if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
- return 0;
-
- const char *CStr = NTE.getString();
- if (!CStr) {
- error() << formatv(
- "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
- NI.getUnitOffset(), NTE.getIndex());
- return 1;
- }
- StringRef Str(CStr);
-
- unsigned NumErrors = 0;
- unsigned NumEntries = 0;
- uint64_t EntryID = NTE.getEntryOffset();
- uint64_t NextEntryID = EntryID;
- Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
- for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
- EntryOr = NI.getEntry(&NextEntryID)) {
- uint32_t CUIndex = *EntryOr->getCUIndex();
- if (CUIndex > NI.getCUCount()) {
- error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
- "invalid CU index ({2}).\n",
- NI.getUnitOffset(), EntryID, CUIndex);
- ++NumErrors;
- continue;
- }
- uint64_t CUOffset = NI.getCUOffset(CUIndex);
- uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
- DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
- if (!DIE) {
- error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
- "non-existing DIE @ {2:x}.\n",
- NI.getUnitOffset(), EntryID, DIEOffset);
- ++NumErrors;
- continue;
- }
- if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
- error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
- "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
- NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
- DIE.getDwarfUnit()->getOffset());
- ++NumErrors;
- }
- if (DIE.getTag() != EntryOr->tag()) {
- error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
- "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
- NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
- DIE.getTag());
- ++NumErrors;
- }
-
- auto EntryNames = getNames(DIE);
- if (!is_contained(EntryNames, Str)) {
- error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
- "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
- NI.getUnitOffset(), EntryID, DIEOffset, Str,
- make_range(EntryNames.begin(), EntryNames.end()));
- ++NumErrors;
- }
- }
- handleAllErrors(EntryOr.takeError(),
- [&](const DWARFDebugNames::SentinelError &) {
- if (NumEntries > 0)
- return;
- error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
- "not associated with any entries.\n",
- NI.getUnitOffset(), NTE.getIndex(), Str);
- ++NumErrors;
- },
- [&](const ErrorInfoBase &Info) {
- error()
- << formatv("Name Index @ {0:x}: Name {1} ({2}): {3}\n",
- NI.getUnitOffset(), NTE.getIndex(), Str,
- Info.message());
- ++NumErrors;
- });
- return NumErrors;
-}
-
-static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
- Expected<std::vector<DWARFLocationExpression>> Loc =
- Die.getLocations(DW_AT_location);
- if (!Loc) {
- consumeError(Loc.takeError());
- return false;
- }
- DWARFUnit *U = Die.getDwarfUnit();
- for (const auto &Entry : *Loc) {
- DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
- U->getAddressByteSize());
- DWARFExpression Expression(Data, U->getAddressByteSize(),
- U->getFormParams().Format);
- bool IsInteresting = any_of(Expression, [](DWARFExpression::Operation &Op) {
- return !Op.isError() && (Op.getCode() == DW_OP_addr ||
- Op.getCode() == DW_OP_form_tls_address ||
- Op.getCode() == DW_OP_GNU_push_tls_address);
- });
- if (IsInteresting)
- return true;
- }
- return false;
-}
-
-unsigned DWARFVerifier::verifyNameIndexCompleteness(
- const DWARFDie &Die, const DWARFDebugNames::NameIndex &NI) {
-
- // First check, if the Die should be indexed. The code follows the DWARF v5
- // wording as closely as possible.
-
- // "All non-defining declarations (that is, debugging information entries
- // with a DW_AT_declaration attribute) are excluded."
- if (Die.find(DW_AT_declaration))
- return 0;
-
- // "DW_TAG_namespace debugging information entries without a DW_AT_name
- // attribute are included with the name “(anonymous namespace)”.
- // All other debugging information entries without a DW_AT_name attribute
- // are excluded."
- // "If a subprogram or inlined subroutine is included, and has a
- // DW_AT_linkage_name attribute, there will be an additional index entry for
- // the linkage name."
- auto IncludeLinkageName = Die.getTag() == DW_TAG_subprogram ||
- Die.getTag() == DW_TAG_inlined_subroutine;
- auto EntryNames = getNames(Die, IncludeLinkageName);
- if (EntryNames.empty())
- return 0;
-
- // We deviate from the specification here, which says:
- // "The name index must contain an entry for each debugging information entry
- // that defines a named subprogram, label, variable, type, or namespace,
- // subject to ..."
- // Explicitly exclude all TAGs that we know shouldn't be indexed.
- switch (Die.getTag()) {
- // Compile units and modules have names but shouldn't be indexed.
- case DW_TAG_compile_unit:
- case DW_TAG_module:
- return 0;
-
- // Function and template parameters are not globally visible, so we shouldn't
- // index them.
- case DW_TAG_formal_parameter:
- case DW_TAG_template_value_parameter:
- case DW_TAG_template_type_parameter:
- case DW_TAG_GNU_template_parameter_pack:
- case DW_TAG_GNU_template_template_param:
- return 0;
-
- // Object members aren't globally visible.
- case DW_TAG_member:
- return 0;
-
- // According to a strict reading of the specification, enumerators should not
- // be indexed (and LLVM currently does not do that). However, this causes
- // problems for the debuggers, so we may need to reconsider this.
- case DW_TAG_enumerator:
- return 0;
-
- // Imported declarations should not be indexed according to the specification
- // and LLVM currently does not do that.
- case DW_TAG_imported_declaration:
- return 0;
-
- // "DW_TAG_subprogram, DW_TAG_inlined_subroutine, and DW_TAG_label debugging
- // information entries without an address attribute (DW_AT_low_pc,
- // DW_AT_high_pc, DW_AT_ranges, or DW_AT_entry_pc) are excluded."
- case DW_TAG_subprogram:
- case DW_TAG_inlined_subroutine:
- case DW_TAG_label:
- if (Die.findRecursively(
- {DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_entry_pc}))
- break;
- return 0;
-
- // "DW_TAG_variable debugging information entries with a DW_AT_location
- // attribute that includes a DW_OP_addr or DW_OP_form_tls_address operator are
- // included; otherwise, they are excluded."
- //
- // LLVM extension: We also add DW_OP_GNU_push_tls_address to this list.
- case DW_TAG_variable:
- if (isVariableIndexable(Die, DCtx))
- break;
- return 0;
-
- default:
- break;
- }
-
- // Now we know that our Die should be present in the Index. Let's check if
- // that's the case.
- unsigned NumErrors = 0;
- uint64_t DieUnitOffset = Die.getOffset() - Die.getDwarfUnit()->getOffset();
- for (StringRef Name : EntryNames) {
- if (none_of(NI.equal_range(Name), [&](const DWARFDebugNames::Entry &E) {
- return E.getDIEUnitOffset() == DieUnitOffset;
- })) {
- error() << formatv("Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with "
- "name {3} missing.\n",
- NI.getUnitOffset(), Die.getOffset(), Die.getTag(),
- Name);
- ++NumErrors;
- }
- }
- return NumErrors;
-}
-
-unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
- const DataExtractor &StrData) {
- unsigned NumErrors = 0;
- DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), AccelSection,
- DCtx.isLittleEndian(), 0);
- DWARFDebugNames AccelTable(AccelSectionData, StrData);
-
- OS << "Verifying .debug_names...\n";
-
- // This verifies that we can read individual name indices and their
- // abbreviation tables.
- if (Error E = AccelTable.extract()) {
- error() << toString(std::move(E)) << '\n';
- return 1;
- }
-
- NumErrors += verifyDebugNamesCULists(AccelTable);
- for (const auto &NI : AccelTable)
- NumErrors += verifyNameIndexBuckets(NI, StrData);
- for (const auto &NI : AccelTable)
- NumErrors += verifyNameIndexAbbrevs(NI);
-
- // Don't attempt Entry validation if any of the previous checks found errors
- if (NumErrors > 0)
- return NumErrors;
- for (const auto &NI : AccelTable)
- for (DWARFDebugNames::NameTableEntry NTE : NI)
- NumErrors += verifyNameIndexEntries(NI, NTE);
-
- if (NumErrors > 0)
- return NumErrors;
-
- for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
- if (const DWARFDebugNames::NameIndex *NI =
- AccelTable.getCUNameIndex(U->getOffset())) {
- auto *CU = cast<DWARFCompileUnit>(U.get());
- for (const DWARFDebugInfoEntry &Die : CU->dies())
- NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
- }
- }
- return NumErrors;
-}
-
-bool DWARFVerifier::handleAccelTables() {
- const DWARFObject &D = DCtx.getDWARFObj();
- DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0);
- unsigned NumErrors = 0;
- if (!D.getAppleNamesSection().Data.empty())
- NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
- ".apple_names");
- if (!D.getAppleTypesSection().Data.empty())
- NumErrors += verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData,
- ".apple_types");
- if (!D.getAppleNamespacesSection().Data.empty())
- NumErrors += verifyAppleAccelTable(&D.getAppleNamespacesSection(), &StrData,
- ".apple_namespaces");
- if (!D.getAppleObjCSection().Data.empty())
- NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
- ".apple_objc");
-
- if (!D.getNamesSection().Data.empty())
- NumErrors += verifyDebugNames(D.getNamesSection(), StrData);
- return NumErrors == 0;
-}
-
-raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
-
-raw_ostream &DWARFVerifier::warn() const { return WithColor::warning(OS); }
-
-raw_ostream &DWARFVerifier::note() const { return WithColor::note(OS); }
-
-raw_ostream &DWARFVerifier::dump(const DWARFDie &Die, unsigned indent) const {
- Die.dump(OS, indent, DumpOpts);
- return OS;
-}
+ default:
+ break;
+ }
+ return NumErrors;
+}
+
+unsigned DWARFVerifier::verifyDebugInfoForm(const DWARFDie &Die,
+ DWARFAttribute &AttrValue) {
+ const DWARFObject &DObj = DCtx.getDWARFObj();
+ auto DieCU = Die.getDwarfUnit();
+ unsigned NumErrors = 0;
+ const auto Form = AttrValue.Value.getForm();
+ switch (Form) {
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_udata: {
+ // Verify all CU relative references are valid CU offsets.
+ Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
+ assert(RefVal);
+ if (RefVal) {
+ auto CUSize = DieCU->getNextUnitOffset() - DieCU->getOffset();
+ auto CUOffset = AttrValue.Value.getRawUValue();
+ if (CUOffset >= CUSize) {
+ ++NumErrors;
+ error() << FormEncodingString(Form) << " CU offset "
+ << format("0x%08" PRIx64, CUOffset)
+ << " is invalid (must be less than CU size of "
+ << format("0x%08" PRIx64, CUSize) << "):\n";
+ Die.dump(OS, 0, DumpOpts);
+ dump(Die) << '\n';
+ } else {
+ // Valid reference, but we will verify it points to an actual
+ // DIE later.
+ ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
+ }
+ }
+ break;
+ }
+ case DW_FORM_ref_addr: {
+ // Verify all absolute DIE references have valid offsets in the
+ // .debug_info section.
+ Optional<uint64_t> RefVal = AttrValue.Value.getAsReference();
+ assert(RefVal);
+ if (RefVal) {
+ if (*RefVal >= DieCU->getInfoSection().Data.size()) {
+ ++NumErrors;
+ error() << "DW_FORM_ref_addr offset beyond .debug_info "
+ "bounds:\n";
+ dump(Die) << '\n';
+ } else {
+ // Valid reference, but we will verify it points to an actual
+ // DIE later.
+ ReferenceToDIEOffsets[*RefVal].insert(Die.getOffset());
+ }
+ }
+ break;
+ }
+ case DW_FORM_strp: {
+ auto SecOffset = AttrValue.Value.getAsSectionOffset();
+ assert(SecOffset); // DW_FORM_strp is a section offset.
+ if (SecOffset && *SecOffset >= DObj.getStrSection().size()) {
+ ++NumErrors;
+ error() << "DW_FORM_strp offset beyond .debug_str bounds:\n";
+ dump(Die) << '\n';
+ }
+ break;
+ }
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4: {
+ auto Index = AttrValue.Value.getRawUValue();
+ auto DieCU = Die.getDwarfUnit();
+ // Check that we have a valid DWARF v5 string offsets table.
+ if (!DieCU->getStringOffsetsTableContribution()) {
+ ++NumErrors;
+ error() << FormEncodingString(Form)
+ << " used without a valid string offsets table:\n";
+ dump(Die) << '\n';
+ break;
+ }
+ // 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 =
+ (uint64_t)DieCU->getStringOffsetsBase() + Index * ItemSize;
+ if (DObj.getStrOffsetsSection().Data.size() < Offset + ItemSize) {
+ ++NumErrors;
+ error() << FormEncodingString(Form) << " uses index "
+ << format("%" PRIu64, Index) << ", which is too large:\n";
+ dump(Die) << '\n';
+ break;
+ }
+ // Check that the string offset is valid.
+ uint64_t StringOffset = *DieCU->getStringOffsetSectionItem(Index);
+ if (StringOffset >= DObj.getStrSection().size()) {
+ ++NumErrors;
+ error() << FormEncodingString(Form) << " uses index "
+ << format("%" PRIu64, Index)
+ << ", but the referenced string"
+ " offset is beyond .debug_str bounds:\n";
+ dump(Die) << '\n';
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return NumErrors;
+}
+
+unsigned DWARFVerifier::verifyDebugInfoReferences() {
+ // Take all references and make sure they point to an actual DIE by
+ // getting the DIE by offset and emitting an error
+ OS << "Verifying .debug_info references...\n";
+ unsigned NumErrors = 0;
+ for (const std::pair<const uint64_t, std::set<uint64_t>> &Pair :
+ ReferenceToDIEOffsets) {
+ if (DCtx.getDIEForOffset(Pair.first))
+ continue;
+ ++NumErrors;
+ error() << "invalid DIE reference " << format("0x%08" PRIx64, Pair.first)
+ << ". Offset is in between DIEs:\n";
+ for (auto Offset : Pair.second)
+ dump(DCtx.getDIEForOffset(Offset)) << '\n';
+ OS << "\n";
+ }
+ return NumErrors;
+}
+
+void DWARFVerifier::verifyDebugLineStmtOffsets() {
+ std::map<uint64_t, DWARFDie> StmtListToDie;
+ for (const auto &CU : DCtx.compile_units()) {
+ auto Die = CU->getUnitDIE();
+ // Get the attribute value as a section offset. No need to produce an
+ // error here if the encoding isn't correct because we validate this in
+ // the .debug_info verifier.
+ auto StmtSectionOffset = toSectionOffset(Die.find(DW_AT_stmt_list));
+ if (!StmtSectionOffset)
+ continue;
+ const uint64_t LineTableOffset = *StmtSectionOffset;
+ auto LineTable = DCtx.getLineTableForUnit(CU.get());
+ if (LineTableOffset < DCtx.getDWARFObj().getLineSection().Data.size()) {
+ if (!LineTable) {
+ ++NumDebugLineErrors;
+ error() << ".debug_line[" << format("0x%08" PRIx64, LineTableOffset)
+ << "] was not able to be parsed for CU:\n";
+ dump(Die) << '\n';
+ continue;
+ }
+ } else {
+ // Make sure we don't get a valid line table back if the offset is wrong.
+ assert(LineTable == nullptr);
+ // Skip this line table as it isn't valid. No need to create an error
+ // here because we validate this in the .debug_info verifier.
+ continue;
+ }
+ auto Iter = StmtListToDie.find(LineTableOffset);
+ if (Iter != StmtListToDie.end()) {
+ ++NumDebugLineErrors;
+ error() << "two compile unit DIEs, "
+ << format("0x%08" PRIx64, Iter->second.getOffset()) << " and "
+ << format("0x%08" PRIx64, Die.getOffset())
+ << ", have the same DW_AT_stmt_list section offset:\n";
+ dump(Iter->second);
+ dump(Die) << '\n';
+ // Already verified this line table before, no need to do it again.
+ continue;
+ }
+ StmtListToDie[LineTableOffset] = Die;
+ }
+}
+
+void DWARFVerifier::verifyDebugLineRows() {
+ for (const auto &CU : DCtx.compile_units()) {
+ auto Die = CU->getUnitDIE();
+ auto LineTable = DCtx.getLineTableForUnit(CU.get());
+ // If there is no line table we will have created an error in the
+ // .debug_info verifier or in verifyDebugLineStmtOffsets().
+ if (!LineTable)
+ continue;
+
+ // Verify prologue.
+ uint32_t MaxDirIndex = LineTable->Prologue.IncludeDirectories.size();
+ uint32_t FileIndex = 1;
+ StringMap<uint16_t> FullPathMap;
+ for (const auto &FileName : LineTable->Prologue.FileNames) {
+ // Verify directory index.
+ if (FileName.DirIdx > MaxDirIndex) {
+ ++NumDebugLineErrors;
+ error() << ".debug_line["
+ << format("0x%08" PRIx64,
+ *toSectionOffset(Die.find(DW_AT_stmt_list)))
+ << "].prologue.file_names[" << FileIndex
+ << "].dir_idx contains an invalid index: " << FileName.DirIdx
+ << "\n";
+ }
+
+ // Check file paths for duplicates.
+ std::string FullPath;
+ const bool HasFullPath = LineTable->getFileNameByIndex(
+ FileIndex, CU->getCompilationDir(),
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, FullPath);
+ assert(HasFullPath && "Invalid index?");
+ (void)HasFullPath;
+ auto It = FullPathMap.find(FullPath);
+ if (It == FullPathMap.end())
+ FullPathMap[FullPath] = FileIndex;
+ else if (It->second != FileIndex) {
+ warn() << ".debug_line["
+ << format("0x%08" PRIx64,
+ *toSectionOffset(Die.find(DW_AT_stmt_list)))
+ << "].prologue.file_names[" << FileIndex
+ << "] is a duplicate of file_names[" << It->second << "]\n";
+ }
+
+ FileIndex++;
+ }
+
+ // Verify rows.
+ uint64_t PrevAddress = 0;
+ uint32_t RowIndex = 0;
+ for (const auto &Row : LineTable->Rows) {
+ // Verify row address.
+ if (Row.Address.Address < PrevAddress) {
+ ++NumDebugLineErrors;
+ error() << ".debug_line["
+ << format("0x%08" PRIx64,
+ *toSectionOffset(Die.find(DW_AT_stmt_list)))
+ << "] row[" << RowIndex
+ << "] decreases in address from previous row:\n";
+
+ DWARFDebugLine::Row::dumpTableHeader(OS, 0);
+ if (RowIndex > 0)
+ LineTable->Rows[RowIndex - 1].dump(OS);
+ Row.dump(OS);
+ OS << '\n';
+ }
+
+ // Verify file index.
+ 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 [" << (isDWARF5 ? "0," : "1,")
+ << LineTable->Prologue.FileNames.size()
+ << (isDWARF5 ? ")" : "]") << "):\n";
+ DWARFDebugLine::Row::dumpTableHeader(OS, 0);
+ Row.dump(OS);
+ OS << '\n';
+ }
+ if (Row.EndSequence)
+ PrevAddress = 0;
+ else
+ PrevAddress = Row.Address.Address;
+ ++RowIndex;
+ }
+ }
+}
+
+DWARFVerifier::DWARFVerifier(raw_ostream &S, DWARFContext &D,
+ DIDumpOptions DumpOpts)
+ : OS(S), DCtx(D), DumpOpts(std::move(DumpOpts)), IsObjectFile(false),
+ IsMachOObject(false) {
+ if (const auto *F = DCtx.getDWARFObj().getFile()) {
+ IsObjectFile = F->isRelocatableObject();
+ IsMachOObject = F->isMachO();
+ }
+}
+
+bool DWARFVerifier::handleDebugLine() {
+ NumDebugLineErrors = 0;
+ OS << "Verifying .debug_line...\n";
+ verifyDebugLineStmtOffsets();
+ verifyDebugLineRows();
+ return NumDebugLineErrors == 0;
+}
+
+unsigned DWARFVerifier::verifyAppleAccelTable(const DWARFSection *AccelSection,
+ DataExtractor *StrData,
+ const char *SectionName) {
+ unsigned NumErrors = 0;
+ DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), *AccelSection,
+ DCtx.isLittleEndian(), 0);
+ AppleAcceleratorTable AccelTable(AccelSectionData, *StrData);
+
+ OS << "Verifying " << SectionName << "...\n";
+
+ // Verify that the fixed part of the header is not too short.
+ if (!AccelSectionData.isValidOffset(AccelTable.getSizeHdr())) {
+ error() << "Section is too small to fit a section header.\n";
+ return 1;
+ }
+
+ // Verify that the section is not too short.
+ if (Error E = AccelTable.extract()) {
+ error() << toString(std::move(E)) << '\n';
+ return 1;
+ }
+
+ // Verify that all buckets have a valid hash index or are empty.
+ uint32_t NumBuckets = AccelTable.getNumBuckets();
+ uint32_t NumHashes = AccelTable.getNumHashes();
+
+ uint64_t BucketsOffset =
+ AccelTable.getSizeHdr() + AccelTable.getHeaderDataLength();
+ uint64_t HashesBase = BucketsOffset + NumBuckets * 4;
+ uint64_t OffsetsBase = HashesBase + NumHashes * 4;
+ for (uint32_t BucketIdx = 0; BucketIdx < NumBuckets; ++BucketIdx) {
+ uint32_t HashIdx = AccelSectionData.getU32(&BucketsOffset);
+ if (HashIdx >= NumHashes && HashIdx != UINT32_MAX) {
+ error() << format("Bucket[%d] has invalid hash index: %u.\n", BucketIdx,
+ HashIdx);
+ ++NumErrors;
+ }
+ }
+ uint32_t NumAtoms = AccelTable.getAtomsDesc().size();
+ if (NumAtoms == 0) {
+ error() << "No atoms: failed to read HashData.\n";
+ return 1;
+ }
+ if (!AccelTable.validateForms()) {
+ error() << "Unsupported form: failed to read HashData.\n";
+ return 1;
+ }
+
+ for (uint32_t HashIdx = 0; HashIdx < NumHashes; ++HashIdx) {
+ uint64_t HashOffset = HashesBase + 4 * HashIdx;
+ uint64_t DataOffset = OffsetsBase + 4 * HashIdx;
+ uint32_t Hash = AccelSectionData.getU32(&HashOffset);
+ uint64_t HashDataOffset = AccelSectionData.getU32(&DataOffset);
+ if (!AccelSectionData.isValidOffsetForDataOfSize(HashDataOffset,
+ sizeof(uint64_t))) {
+ error() << format("Hash[%d] has invalid HashData offset: "
+ "0x%08" PRIx64 ".\n",
+ HashIdx, HashDataOffset);
+ ++NumErrors;
+ }
+
+ uint64_t StrpOffset;
+ uint64_t StringOffset;
+ uint32_t StringCount = 0;
+ uint64_t Offset;
+ unsigned Tag;
+ while ((StrpOffset = AccelSectionData.getU32(&HashDataOffset)) != 0) {
+ const uint32_t NumHashDataObjects =
+ AccelSectionData.getU32(&HashDataOffset);
+ for (uint32_t HashDataIdx = 0; HashDataIdx < NumHashDataObjects;
+ ++HashDataIdx) {
+ std::tie(Offset, Tag) = AccelTable.readAtoms(&HashDataOffset);
+ auto Die = DCtx.getDIEForOffset(Offset);
+ if (!Die) {
+ const uint32_t BucketIdx =
+ NumBuckets ? (Hash % NumBuckets) : UINT32_MAX;
+ StringOffset = StrpOffset;
+ const char *Name = StrData->getCStr(&StringOffset);
+ if (!Name)
+ Name = "<NULL>";
+
+ error() << format(
+ "%s Bucket[%d] Hash[%d] = 0x%08x "
+ "Str[%u] = 0x%08" PRIx64 " DIE[%d] = 0x%08" PRIx64 " "
+ "is not a valid DIE offset for \"%s\".\n",
+ SectionName, BucketIdx, HashIdx, Hash, StringCount, StrpOffset,
+ HashDataIdx, Offset, Name);
+
+ ++NumErrors;
+ continue;
+ }
+ if ((Tag != dwarf::DW_TAG_null) && (Die.getTag() != Tag)) {
+ error() << "Tag " << dwarf::TagString(Tag)
+ << " in accelerator table does not match Tag "
+ << dwarf::TagString(Die.getTag()) << " of DIE[" << HashDataIdx
+ << "].\n";
+ ++NumErrors;
+ }
+ }
+ ++StringCount;
+ }
+ }
+ return NumErrors;
+}
+
+unsigned
+DWARFVerifier::verifyDebugNamesCULists(const DWARFDebugNames &AccelTable) {
+ // A map from CU offset to the (first) Name Index offset which claims to index
+ // this CU.
+ DenseMap<uint64_t, uint64_t> CUMap;
+ const uint64_t NotIndexed = std::numeric_limits<uint64_t>::max();
+
+ CUMap.reserve(DCtx.getNumCompileUnits());
+ for (const auto &CU : DCtx.compile_units())
+ CUMap[CU->getOffset()] = NotIndexed;
+
+ unsigned NumErrors = 0;
+ for (const DWARFDebugNames::NameIndex &NI : AccelTable) {
+ if (NI.getCUCount() == 0) {
+ error() << formatv("Name Index @ {0:x} does not index any CU\n",
+ NI.getUnitOffset());
+ ++NumErrors;
+ continue;
+ }
+ for (uint32_t CU = 0, End = NI.getCUCount(); CU < End; ++CU) {
+ uint64_t Offset = NI.getCUOffset(CU);
+ auto Iter = CUMap.find(Offset);
+
+ if (Iter == CUMap.end()) {
+ error() << formatv(
+ "Name Index @ {0:x} references a non-existing CU @ {1:x}\n",
+ NI.getUnitOffset(), Offset);
+ ++NumErrors;
+ continue;
+ }
+
+ if (Iter->second != NotIndexed) {
+ error() << formatv("Name Index @ {0:x} references a CU @ {1:x}, but "
+ "this CU is already indexed by Name Index @ {2:x}\n",
+ NI.getUnitOffset(), Offset, Iter->second);
+ continue;
+ }
+ Iter->second = NI.getUnitOffset();
+ }
+ }
+
+ for (const auto &KV : CUMap) {
+ if (KV.second == NotIndexed)
+ warn() << formatv("CU @ {0:x} not covered by any Name Index\n", KV.first);
+ }
+
+ return NumErrors;
+}
+
+unsigned
+DWARFVerifier::verifyNameIndexBuckets(const DWARFDebugNames::NameIndex &NI,
+ const DataExtractor &StrData) {
+ struct BucketInfo {
+ uint32_t Bucket;
+ uint32_t Index;
+
+ constexpr BucketInfo(uint32_t Bucket, uint32_t Index)
+ : Bucket(Bucket), Index(Index) {}
+ bool operator<(const BucketInfo &RHS) const { return Index < RHS.Index; }
+ };
+
+ uint32_t NumErrors = 0;
+ if (NI.getBucketCount() == 0) {
+ warn() << formatv("Name Index @ {0:x} does not contain a hash table.\n",
+ NI.getUnitOffset());
+ return NumErrors;
+ }
+
+ // Build up a list of (Bucket, Index) pairs. We use this later to verify that
+ // each Name is reachable from the appropriate bucket.
+ std::vector<BucketInfo> BucketStarts;
+ BucketStarts.reserve(NI.getBucketCount() + 1);
+ for (uint32_t Bucket = 0, End = NI.getBucketCount(); Bucket < End; ++Bucket) {
+ uint32_t Index = NI.getBucketArrayEntry(Bucket);
+ if (Index > NI.getNameCount()) {
+ error() << formatv("Bucket {0} of Name Index @ {1:x} contains invalid "
+ "value {2}. Valid range is [0, {3}].\n",
+ Bucket, NI.getUnitOffset(), Index, NI.getNameCount());
+ ++NumErrors;
+ continue;
+ }
+ if (Index > 0)
+ BucketStarts.emplace_back(Bucket, Index);
+ }
+
+ // If there were any buckets with invalid values, skip further checks as they
+ // will likely produce many errors which will only confuse the actual root
+ // problem.
+ if (NumErrors > 0)
+ return NumErrors;
+
+ // Sort the list in the order of increasing "Index" entries.
+ array_pod_sort(BucketStarts.begin(), BucketStarts.end());
+
+ // Insert a sentinel entry at the end, so we can check that the end of the
+ // table is covered in the loop below.
+ BucketStarts.emplace_back(NI.getBucketCount(), NI.getNameCount() + 1);
+
+ // Loop invariant: NextUncovered is the (1-based) index of the first Name
+ // which is not reachable by any of the buckets we processed so far (and
+ // hasn't been reported as uncovered).
+ uint32_t NextUncovered = 1;
+ for (const BucketInfo &B : BucketStarts) {
+ // Under normal circumstances B.Index be equal to NextUncovered, but it can
+ // be less if a bucket points to names which are already known to be in some
+ // bucket we processed earlier. In that case, we won't trigger this error,
+ // but report the mismatched hash value error instead. (We know the hash
+ // will not match because we have already verified that the name's hash
+ // puts it into the previous bucket.)
+ if (B.Index > NextUncovered) {
+ error() << formatv("Name Index @ {0:x}: Name table entries [{1}, {2}] "
+ "are not covered by the hash table.\n",
+ NI.getUnitOffset(), NextUncovered, B.Index - 1);
+ ++NumErrors;
+ }
+ uint32_t Idx = B.Index;
+
+ // The rest of the checks apply only to non-sentinel entries.
+ if (B.Bucket == NI.getBucketCount())
+ break;
+
+ // This triggers if a non-empty bucket points to a name with a mismatched
+ // hash. Clients are likely to interpret this as an empty bucket, because a
+ // mismatched hash signals the end of a bucket, but if this is indeed an
+ // empty bucket, the producer should have signalled this by marking the
+ // bucket as empty.
+ uint32_t FirstHash = NI.getHashArrayEntry(Idx);
+ if (FirstHash % NI.getBucketCount() != B.Bucket) {
+ error() << formatv(
+ "Name Index @ {0:x}: Bucket {1} is not empty but points to a "
+ "mismatched hash value {2:x} (belonging to bucket {3}).\n",
+ NI.getUnitOffset(), B.Bucket, FirstHash,
+ FirstHash % NI.getBucketCount());
+ ++NumErrors;
+ }
+
+ // This find the end of this bucket and also verifies that all the hashes in
+ // this bucket are correct by comparing the stored hashes to the ones we
+ // compute ourselves.
+ while (Idx <= NI.getNameCount()) {
+ uint32_t Hash = NI.getHashArrayEntry(Idx);
+ if (Hash % NI.getBucketCount() != B.Bucket)
+ break;
+
+ const char *Str = NI.getNameTableEntry(Idx).getString();
+ if (caseFoldingDjbHash(Str) != Hash) {
+ error() << formatv("Name Index @ {0:x}: String ({1}) at index {2} "
+ "hashes to {3:x}, but "
+ "the Name Index hash is {4:x}\n",
+ NI.getUnitOffset(), Str, Idx,
+ caseFoldingDjbHash(Str), Hash);
+ ++NumErrors;
+ }
+
+ ++Idx;
+ }
+ NextUncovered = std::max(NextUncovered, Idx);
+ }
+ return NumErrors;
+}
+
+unsigned DWARFVerifier::verifyNameIndexAttribute(
+ const DWARFDebugNames::NameIndex &NI, const DWARFDebugNames::Abbrev &Abbr,
+ DWARFDebugNames::AttributeEncoding AttrEnc) {
+ StringRef FormName = dwarf::FormEncodingString(AttrEnc.Form);
+ if (FormName.empty()) {
+ error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
+ "unknown form: {3}.\n",
+ NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
+ AttrEnc.Form);
+ return 1;
+ }
+
+ if (AttrEnc.Index == DW_IDX_type_hash) {
+ if (AttrEnc.Form != dwarf::DW_FORM_data8) {
+ error() << formatv(
+ "NameIndex @ {0:x}: Abbreviation {1:x}: DW_IDX_type_hash "
+ "uses an unexpected form {2} (should be {3}).\n",
+ NI.getUnitOffset(), Abbr.Code, AttrEnc.Form, dwarf::DW_FORM_data8);
+ return 1;
+ }
+ }
+
+ // A list of known index attributes and their expected form classes.
+ // DW_IDX_type_hash is handled specially in the check above, as it has a
+ // specific form (not just a form class) we should expect.
+ struct FormClassTable {
+ dwarf::Index Index;
+ DWARFFormValue::FormClass Class;
+ StringLiteral ClassName;
+ };
+ static constexpr FormClassTable Table[] = {
+ {dwarf::DW_IDX_compile_unit, DWARFFormValue::FC_Constant, {"constant"}},
+ {dwarf::DW_IDX_type_unit, DWARFFormValue::FC_Constant, {"constant"}},
+ {dwarf::DW_IDX_die_offset, DWARFFormValue::FC_Reference, {"reference"}},
+ {dwarf::DW_IDX_parent, DWARFFormValue::FC_Constant, {"constant"}},
+ };
+
+ ArrayRef<FormClassTable> TableRef(Table);
+ auto Iter = find_if(TableRef, [AttrEnc](const FormClassTable &T) {
+ return T.Index == AttrEnc.Index;
+ });
+ if (Iter == TableRef.end()) {
+ warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains an "
+ "unknown index attribute: {2}.\n",
+ NI.getUnitOffset(), Abbr.Code, AttrEnc.Index);
+ return 0;
+ }
+
+ if (!DWARFFormValue(AttrEnc.Form).isFormClass(Iter->Class)) {
+ error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x}: {2} uses an "
+ "unexpected form {3} (expected form class {4}).\n",
+ NI.getUnitOffset(), Abbr.Code, AttrEnc.Index,
+ AttrEnc.Form, Iter->ClassName);
+ return 1;
+ }
+ return 0;
+}
+
+unsigned
+DWARFVerifier::verifyNameIndexAbbrevs(const DWARFDebugNames::NameIndex &NI) {
+ if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0) {
+ warn() << formatv("Name Index @ {0:x}: Verifying indexes of type units is "
+ "not currently supported.\n",
+ NI.getUnitOffset());
+ return 0;
+ }
+
+ unsigned NumErrors = 0;
+ for (const auto &Abbrev : NI.getAbbrevs()) {
+ StringRef TagName = dwarf::TagString(Abbrev.Tag);
+ if (TagName.empty()) {
+ warn() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} references an "
+ "unknown tag: {2}.\n",
+ NI.getUnitOffset(), Abbrev.Code, Abbrev.Tag);
+ }
+ SmallSet<unsigned, 5> Attributes;
+ for (const auto &AttrEnc : Abbrev.Attributes) {
+ if (!Attributes.insert(AttrEnc.Index).second) {
+ error() << formatv("NameIndex @ {0:x}: Abbreviation {1:x} contains "
+ "multiple {2} attributes.\n",
+ NI.getUnitOffset(), Abbrev.Code, AttrEnc.Index);
+ ++NumErrors;
+ continue;
+ }
+ NumErrors += verifyNameIndexAttribute(NI, Abbrev, AttrEnc);
+ }
+
+ if (NI.getCUCount() > 1 && !Attributes.count(dwarf::DW_IDX_compile_unit)) {
+ error() << formatv("NameIndex @ {0:x}: Indexing multiple compile units "
+ "and abbreviation {1:x} has no {2} attribute.\n",
+ NI.getUnitOffset(), Abbrev.Code,
+ dwarf::DW_IDX_compile_unit);
+ ++NumErrors;
+ }
+ if (!Attributes.count(dwarf::DW_IDX_die_offset)) {
+ error() << formatv(
+ "NameIndex @ {0:x}: Abbreviation {1:x} has no {2} attribute.\n",
+ NI.getUnitOffset(), Abbrev.Code, dwarf::DW_IDX_die_offset);
+ ++NumErrors;
+ }
+ }
+ return NumErrors;
+}
+
+static SmallVector<StringRef, 2> getNames(const DWARFDie &DIE,
+ bool IncludeLinkageName = true) {
+ SmallVector<StringRef, 2> Result;
+ if (const char *Str = DIE.getName(DINameKind::ShortName))
+ Result.emplace_back(Str);
+ else if (DIE.getTag() == dwarf::DW_TAG_namespace)
+ Result.emplace_back("(anonymous namespace)");
+
+ if (IncludeLinkageName) {
+ if (const char *Str = DIE.getName(DINameKind::LinkageName)) {
+ if (Result.empty() || Result[0] != Str)
+ Result.emplace_back(Str);
+ }
+ }
+
+ return Result;
+}
+
+unsigned DWARFVerifier::verifyNameIndexEntries(
+ const DWARFDebugNames::NameIndex &NI,
+ const DWARFDebugNames::NameTableEntry &NTE) {
+ // Verifying type unit indexes not supported.
+ if (NI.getLocalTUCount() + NI.getForeignTUCount() > 0)
+ return 0;
+
+ const char *CStr = NTE.getString();
+ if (!CStr) {
+ error() << formatv(
+ "Name Index @ {0:x}: Unable to get string associated with name {1}.\n",
+ NI.getUnitOffset(), NTE.getIndex());
+ return 1;
+ }
+ StringRef Str(CStr);
+
+ unsigned NumErrors = 0;
+ unsigned NumEntries = 0;
+ uint64_t EntryID = NTE.getEntryOffset();
+ uint64_t NextEntryID = EntryID;
+ Expected<DWARFDebugNames::Entry> EntryOr = NI.getEntry(&NextEntryID);
+ for (; EntryOr; ++NumEntries, EntryID = NextEntryID,
+ EntryOr = NI.getEntry(&NextEntryID)) {
+ uint32_t CUIndex = *EntryOr->getCUIndex();
+ if (CUIndex > NI.getCUCount()) {
+ error() << formatv("Name Index @ {0:x}: Entry @ {1:x} contains an "
+ "invalid CU index ({2}).\n",
+ NI.getUnitOffset(), EntryID, CUIndex);
+ ++NumErrors;
+ continue;
+ }
+ uint64_t CUOffset = NI.getCUOffset(CUIndex);
+ uint64_t DIEOffset = CUOffset + *EntryOr->getDIEUnitOffset();
+ DWARFDie DIE = DCtx.getDIEForOffset(DIEOffset);
+ if (!DIE) {
+ error() << formatv("Name Index @ {0:x}: Entry @ {1:x} references a "
+ "non-existing DIE @ {2:x}.\n",
+ NI.getUnitOffset(), EntryID, DIEOffset);
+ ++NumErrors;
+ continue;
+ }
+ if (DIE.getDwarfUnit()->getOffset() != CUOffset) {
+ error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched CU of "
+ "DIE @ {2:x}: index - {3:x}; debug_info - {4:x}.\n",
+ NI.getUnitOffset(), EntryID, DIEOffset, CUOffset,
+ DIE.getDwarfUnit()->getOffset());
+ ++NumErrors;
+ }
+ if (DIE.getTag() != EntryOr->tag()) {
+ error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Tag of "
+ "DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
+ NI.getUnitOffset(), EntryID, DIEOffset, EntryOr->tag(),
+ DIE.getTag());
+ ++NumErrors;
+ }
+
+ auto EntryNames = getNames(DIE);
+ if (!is_contained(EntryNames, Str)) {
+ error() << formatv("Name Index @ {0:x}: Entry @ {1:x}: mismatched Name "
+ "of DIE @ {2:x}: index - {3}; debug_info - {4}.\n",
+ NI.getUnitOffset(), EntryID, DIEOffset, Str,
+ make_range(EntryNames.begin(), EntryNames.end()));
+ ++NumErrors;
+ }
+ }
+ handleAllErrors(EntryOr.takeError(),
+ [&](const DWARFDebugNames::SentinelError &) {
+ if (NumEntries > 0)
+ return;
+ error() << formatv("Name Index @ {0:x}: Name {1} ({2}) is "
+ "not associated with any entries.\n",
+ NI.getUnitOffset(), NTE.getIndex(), Str);
+ ++NumErrors;
+ },
+ [&](const ErrorInfoBase &Info) {
+ error()
+ << formatv("Name Index @ {0:x}: Name {1} ({2}): {3}\n",
+ NI.getUnitOffset(), NTE.getIndex(), Str,
+ Info.message());
+ ++NumErrors;
+ });
+ return NumErrors;
+}
+
+static bool isVariableIndexable(const DWARFDie &Die, DWARFContext &DCtx) {
+ Expected<std::vector<DWARFLocationExpression>> Loc =
+ Die.getLocations(DW_AT_location);
+ if (!Loc) {
+ consumeError(Loc.takeError());
+ return false;
+ }
+ DWARFUnit *U = Die.getDwarfUnit();
+ for (const auto &Entry : *Loc) {
+ DataExtractor Data(toStringRef(Entry.Expr), DCtx.isLittleEndian(),
+ U->getAddressByteSize());
+ DWARFExpression Expression(Data, U->getAddressByteSize(),
+ U->getFormParams().Format);
+ bool IsInteresting = any_of(Expression, [](DWARFExpression::Operation &Op) {
+ return !Op.isError() && (Op.getCode() == DW_OP_addr ||
+ Op.getCode() == DW_OP_form_tls_address ||
+ Op.getCode() == DW_OP_GNU_push_tls_address);
+ });
+ if (IsInteresting)
+ return true;
+ }
+ return false;
+}
+
+unsigned DWARFVerifier::verifyNameIndexCompleteness(
+ const DWARFDie &Die, const DWARFDebugNames::NameIndex &NI) {
+
+ // First check, if the Die should be indexed. The code follows the DWARF v5
+ // wording as closely as possible.
+
+ // "All non-defining declarations (that is, debugging information entries
+ // with a DW_AT_declaration attribute) are excluded."
+ if (Die.find(DW_AT_declaration))
+ return 0;
+
+ // "DW_TAG_namespace debugging information entries without a DW_AT_name
+ // attribute are included with the name “(anonymous namespace)”.
+ // All other debugging information entries without a DW_AT_name attribute
+ // are excluded."
+ // "If a subprogram or inlined subroutine is included, and has a
+ // DW_AT_linkage_name attribute, there will be an additional index entry for
+ // the linkage name."
+ auto IncludeLinkageName = Die.getTag() == DW_TAG_subprogram ||
+ Die.getTag() == DW_TAG_inlined_subroutine;
+ auto EntryNames = getNames(Die, IncludeLinkageName);
+ if (EntryNames.empty())
+ return 0;
+
+ // We deviate from the specification here, which says:
+ // "The name index must contain an entry for each debugging information entry
+ // that defines a named subprogram, label, variable, type, or namespace,
+ // subject to ..."
+ // Explicitly exclude all TAGs that we know shouldn't be indexed.
+ switch (Die.getTag()) {
+ // Compile units and modules have names but shouldn't be indexed.
+ case DW_TAG_compile_unit:
+ case DW_TAG_module:
+ return 0;
+
+ // Function and template parameters are not globally visible, so we shouldn't
+ // index them.
+ case DW_TAG_formal_parameter:
+ case DW_TAG_template_value_parameter:
+ case DW_TAG_template_type_parameter:
+ case DW_TAG_GNU_template_parameter_pack:
+ case DW_TAG_GNU_template_template_param:
+ return 0;
+
+ // Object members aren't globally visible.
+ case DW_TAG_member:
+ return 0;
+
+ // According to a strict reading of the specification, enumerators should not
+ // be indexed (and LLVM currently does not do that). However, this causes
+ // problems for the debuggers, so we may need to reconsider this.
+ case DW_TAG_enumerator:
+ return 0;
+
+ // Imported declarations should not be indexed according to the specification
+ // and LLVM currently does not do that.
+ case DW_TAG_imported_declaration:
+ return 0;
+
+ // "DW_TAG_subprogram, DW_TAG_inlined_subroutine, and DW_TAG_label debugging
+ // information entries without an address attribute (DW_AT_low_pc,
+ // DW_AT_high_pc, DW_AT_ranges, or DW_AT_entry_pc) are excluded."
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ case DW_TAG_label:
+ if (Die.findRecursively(
+ {DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_entry_pc}))
+ break;
+ return 0;
+
+ // "DW_TAG_variable debugging information entries with a DW_AT_location
+ // attribute that includes a DW_OP_addr or DW_OP_form_tls_address operator are
+ // included; otherwise, they are excluded."
+ //
+ // LLVM extension: We also add DW_OP_GNU_push_tls_address to this list.
+ case DW_TAG_variable:
+ if (isVariableIndexable(Die, DCtx))
+ break;
+ return 0;
+
+ default:
+ break;
+ }
+
+ // Now we know that our Die should be present in the Index. Let's check if
+ // that's the case.
+ unsigned NumErrors = 0;
+ uint64_t DieUnitOffset = Die.getOffset() - Die.getDwarfUnit()->getOffset();
+ for (StringRef Name : EntryNames) {
+ if (none_of(NI.equal_range(Name), [&](const DWARFDebugNames::Entry &E) {
+ return E.getDIEUnitOffset() == DieUnitOffset;
+ })) {
+ error() << formatv("Name Index @ {0:x}: Entry for DIE @ {1:x} ({2}) with "
+ "name {3} missing.\n",
+ NI.getUnitOffset(), Die.getOffset(), Die.getTag(),
+ Name);
+ ++NumErrors;
+ }
+ }
+ return NumErrors;
+}
+
+unsigned DWARFVerifier::verifyDebugNames(const DWARFSection &AccelSection,
+ const DataExtractor &StrData) {
+ unsigned NumErrors = 0;
+ DWARFDataExtractor AccelSectionData(DCtx.getDWARFObj(), AccelSection,
+ DCtx.isLittleEndian(), 0);
+ DWARFDebugNames AccelTable(AccelSectionData, StrData);
+
+ OS << "Verifying .debug_names...\n";
+
+ // This verifies that we can read individual name indices and their
+ // abbreviation tables.
+ if (Error E = AccelTable.extract()) {
+ error() << toString(std::move(E)) << '\n';
+ return 1;
+ }
+
+ NumErrors += verifyDebugNamesCULists(AccelTable);
+ for (const auto &NI : AccelTable)
+ NumErrors += verifyNameIndexBuckets(NI, StrData);
+ for (const auto &NI : AccelTable)
+ NumErrors += verifyNameIndexAbbrevs(NI);
+
+ // Don't attempt Entry validation if any of the previous checks found errors
+ if (NumErrors > 0)
+ return NumErrors;
+ for (const auto &NI : AccelTable)
+ for (DWARFDebugNames::NameTableEntry NTE : NI)
+ NumErrors += verifyNameIndexEntries(NI, NTE);
+
+ if (NumErrors > 0)
+ return NumErrors;
+
+ for (const std::unique_ptr<DWARFUnit> &U : DCtx.compile_units()) {
+ if (const DWARFDebugNames::NameIndex *NI =
+ AccelTable.getCUNameIndex(U->getOffset())) {
+ auto *CU = cast<DWARFCompileUnit>(U.get());
+ for (const DWARFDebugInfoEntry &Die : CU->dies())
+ NumErrors += verifyNameIndexCompleteness(DWARFDie(CU, &Die), *NI);
+ }
+ }
+ return NumErrors;
+}
+
+bool DWARFVerifier::handleAccelTables() {
+ const DWARFObject &D = DCtx.getDWARFObj();
+ DataExtractor StrData(D.getStrSection(), DCtx.isLittleEndian(), 0);
+ unsigned NumErrors = 0;
+ if (!D.getAppleNamesSection().Data.empty())
+ NumErrors += verifyAppleAccelTable(&D.getAppleNamesSection(), &StrData,
+ ".apple_names");
+ if (!D.getAppleTypesSection().Data.empty())
+ NumErrors += verifyAppleAccelTable(&D.getAppleTypesSection(), &StrData,
+ ".apple_types");
+ if (!D.getAppleNamespacesSection().Data.empty())
+ NumErrors += verifyAppleAccelTable(&D.getAppleNamespacesSection(), &StrData,
+ ".apple_namespaces");
+ if (!D.getAppleObjCSection().Data.empty())
+ NumErrors += verifyAppleAccelTable(&D.getAppleObjCSection(), &StrData,
+ ".apple_objc");
+
+ if (!D.getNamesSection().Data.empty())
+ NumErrors += verifyDebugNames(D.getNamesSection(), StrData);
+ return NumErrors == 0;
+}
+
+raw_ostream &DWARFVerifier::error() const { return WithColor::error(OS); }
+
+raw_ostream &DWARFVerifier::warn() const { return WithColor::warning(OS); }
+
+raw_ostream &DWARFVerifier::note() const { return WithColor::note(OS); }
+
+raw_ostream &DWARFVerifier::dump(const DWARFDie &Die, unsigned indent) const {
+ Die.dump(OS, indent, DumpOpts);
+ return OS;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make b/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make
index 5cb9397828..1b82e134b3 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/DWARF/ya.make
@@ -1,61 +1,61 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
OWNER(
orivej
g:cpp-contrib
)
-
+
LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-PEERDIR(
+PEERDIR(
contrib/libs/llvm12
contrib/libs/llvm12/lib/BinaryFormat
contrib/libs/llvm12/lib/MC
contrib/libs/llvm12/lib/Object
contrib/libs/llvm12/lib/Support
-)
-
+)
+
ADDINCL(
contrib/libs/llvm12/lib/DebugInfo/DWARF
)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
-SRCS(
- DWARFAbbreviationDeclaration.cpp
- DWARFAcceleratorTable.cpp
- DWARFAddressRange.cpp
- DWARFCompileUnit.cpp
- DWARFContext.cpp
- DWARFDataExtractor.cpp
- DWARFDebugAbbrev.cpp
- DWARFDebugAddr.cpp
- DWARFDebugArangeSet.cpp
- DWARFDebugAranges.cpp
- DWARFDebugFrame.cpp
- DWARFDebugInfoEntry.cpp
- DWARFDebugLine.cpp
- DWARFDebugLoc.cpp
- DWARFDebugMacro.cpp
- DWARFDebugPubTable.cpp
- DWARFDebugRangeList.cpp
- DWARFDebugRnglists.cpp
- DWARFDie.cpp
- DWARFExpression.cpp
- DWARFFormValue.cpp
- DWARFGdbIndex.cpp
- DWARFListTable.cpp
- DWARFLocationExpression.cpp
- DWARFTypeUnit.cpp
- DWARFUnit.cpp
- DWARFUnitIndex.cpp
- DWARFVerifier.cpp
-)
-
-END()
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+SRCS(
+ DWARFAbbreviationDeclaration.cpp
+ DWARFAcceleratorTable.cpp
+ DWARFAddressRange.cpp
+ DWARFCompileUnit.cpp
+ DWARFContext.cpp
+ DWARFDataExtractor.cpp
+ DWARFDebugAbbrev.cpp
+ DWARFDebugAddr.cpp
+ DWARFDebugArangeSet.cpp
+ DWARFDebugAranges.cpp
+ DWARFDebugFrame.cpp
+ DWARFDebugInfoEntry.cpp
+ DWARFDebugLine.cpp
+ DWARFDebugLoc.cpp
+ DWARFDebugMacro.cpp
+ DWARFDebugPubTable.cpp
+ DWARFDebugRangeList.cpp
+ DWARFDebugRnglists.cpp
+ DWARFDie.cpp
+ DWARFExpression.cpp
+ DWARFFormValue.cpp
+ DWARFGdbIndex.cpp
+ DWARFListTable.cpp
+ DWARFLocationExpression.cpp
+ DWARFTypeUnit.cpp
+ DWARFUnit.cpp
+ DWARFUnitIndex.cpp
+ DWARFVerifier.cpp
+)
+
+END()
diff --git a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp
index f946dd4860..c9d70d77ce 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFBuilder.cpp
@@ -1,379 +1,379 @@
-//===- MSFBuilder.cpp -----------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/FileOutputBuffer.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <utility>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::support;
-
-static const uint32_t kSuperBlockBlock = 0;
-static const uint32_t kFreePageMap0Block = 1;
-static const uint32_t kFreePageMap1Block = 2;
-static const uint32_t kNumReservedPages = 3;
-
-static const uint32_t kDefaultFreePageMap = kFreePageMap1Block;
-static const uint32_t kDefaultBlockMapAddr = kNumReservedPages;
-
-MSFBuilder::MSFBuilder(uint32_t BlockSize, uint32_t MinBlockCount, bool CanGrow,
- BumpPtrAllocator &Allocator)
- : Allocator(Allocator), IsGrowable(CanGrow),
- FreePageMap(kDefaultFreePageMap), BlockSize(BlockSize),
- BlockMapAddr(kDefaultBlockMapAddr), FreeBlocks(MinBlockCount, true) {
- FreeBlocks[kSuperBlockBlock] = false;
- FreeBlocks[kFreePageMap0Block] = false;
- FreeBlocks[kFreePageMap1Block] = false;
- FreeBlocks[BlockMapAddr] = false;
-}
-
-Expected<MSFBuilder> MSFBuilder::create(BumpPtrAllocator &Allocator,
- uint32_t BlockSize,
- uint32_t MinBlockCount, bool CanGrow) {
- if (!isValidBlockSize(BlockSize))
- return make_error<MSFError>(msf_error_code::invalid_format,
- "The requested block size is unsupported");
-
- return MSFBuilder(BlockSize,
- std::max(MinBlockCount, msf::getMinimumBlockCount()),
- CanGrow, Allocator);
-}
-
-Error MSFBuilder::setBlockMapAddr(uint32_t Addr) {
- if (Addr == BlockMapAddr)
- return Error::success();
-
- if (Addr >= FreeBlocks.size()) {
- if (!IsGrowable)
- return make_error<MSFError>(msf_error_code::insufficient_buffer,
- "Cannot grow the number of blocks");
- FreeBlocks.resize(Addr + 1, true);
- }
-
- if (!isBlockFree(Addr))
- return make_error<MSFError>(
- msf_error_code::block_in_use,
- "Requested block map address is already in use");
- FreeBlocks[BlockMapAddr] = true;
- FreeBlocks[Addr] = false;
- BlockMapAddr = Addr;
- return Error::success();
-}
-
-void MSFBuilder::setFreePageMap(uint32_t Fpm) { FreePageMap = Fpm; }
-
-void MSFBuilder::setUnknown1(uint32_t Unk1) { Unknown1 = Unk1; }
-
-Error MSFBuilder::setDirectoryBlocksHint(ArrayRef<uint32_t> DirBlocks) {
- for (auto B : DirectoryBlocks)
- FreeBlocks[B] = true;
- for (auto B : DirBlocks) {
- if (!isBlockFree(B)) {
- return make_error<MSFError>(msf_error_code::unspecified,
- "Attempt to reuse an allocated block");
- }
- FreeBlocks[B] = false;
- }
-
- DirectoryBlocks = DirBlocks;
- return Error::success();
-}
-
-Error MSFBuilder::allocateBlocks(uint32_t NumBlocks,
- MutableArrayRef<uint32_t> Blocks) {
- if (NumBlocks == 0)
- return Error::success();
-
- uint32_t NumFreeBlocks = FreeBlocks.count();
- if (NumFreeBlocks < NumBlocks) {
- if (!IsGrowable)
- return make_error<MSFError>(msf_error_code::insufficient_buffer,
- "There are no free Blocks in the file");
- uint32_t AllocBlocks = NumBlocks - NumFreeBlocks;
- uint32_t OldBlockCount = FreeBlocks.size();
- uint32_t NewBlockCount = AllocBlocks + OldBlockCount;
- uint32_t NextFpmBlock = alignTo(OldBlockCount, BlockSize) + 1;
- FreeBlocks.resize(NewBlockCount, true);
- // If we crossed over an fpm page, we actually need to allocate 2 extra
- // blocks for each FPM group crossed and mark both blocks from the group as
- // used. FPM blocks are marked as allocated regardless of whether or not
- // they ultimately describe the status of blocks in the file. This means
- // that not only are extraneous blocks at the end of the main FPM marked as
- // allocated, but also blocks from the alternate FPM are always marked as
- // allocated.
- while (NextFpmBlock < NewBlockCount) {
- NewBlockCount += 2;
- FreeBlocks.resize(NewBlockCount, true);
- FreeBlocks.reset(NextFpmBlock, NextFpmBlock + 2);
- NextFpmBlock += BlockSize;
- }
- }
-
- int I = 0;
- int Block = FreeBlocks.find_first();
- do {
- assert(Block != -1 && "We ran out of Blocks!");
-
- uint32_t NextBlock = static_cast<uint32_t>(Block);
- Blocks[I++] = NextBlock;
- FreeBlocks.reset(NextBlock);
- Block = FreeBlocks.find_next(Block);
- } while (--NumBlocks > 0);
- return Error::success();
-}
-
-uint32_t MSFBuilder::getNumUsedBlocks() const {
- return getTotalBlockCount() - getNumFreeBlocks();
-}
-
-uint32_t MSFBuilder::getNumFreeBlocks() const { return FreeBlocks.count(); }
-
-uint32_t MSFBuilder::getTotalBlockCount() const { return FreeBlocks.size(); }
-
-bool MSFBuilder::isBlockFree(uint32_t Idx) const { return FreeBlocks[Idx]; }
-
-Expected<uint32_t> MSFBuilder::addStream(uint32_t Size,
- ArrayRef<uint32_t> Blocks) {
- // Add a new stream mapped to the specified blocks. Verify that the specified
- // blocks are both necessary and sufficient for holding the requested number
- // of bytes, and verify that all requested blocks are free.
- uint32_t ReqBlocks = bytesToBlocks(Size, BlockSize);
- if (ReqBlocks != Blocks.size())
- return make_error<MSFError>(
- msf_error_code::invalid_format,
- "Incorrect number of blocks for requested stream size");
- for (auto Block : Blocks) {
- if (Block >= FreeBlocks.size())
- FreeBlocks.resize(Block + 1, true);
-
- if (!FreeBlocks.test(Block))
- return make_error<MSFError>(
- msf_error_code::unspecified,
- "Attempt to re-use an already allocated block");
- }
- // Mark all the blocks occupied by the new stream as not free.
- for (auto Block : Blocks) {
- FreeBlocks.reset(Block);
- }
- StreamData.push_back(std::make_pair(Size, Blocks));
- return StreamData.size() - 1;
-}
-
-Expected<uint32_t> MSFBuilder::addStream(uint32_t Size) {
- uint32_t ReqBlocks = bytesToBlocks(Size, BlockSize);
- std::vector<uint32_t> NewBlocks;
- NewBlocks.resize(ReqBlocks);
- if (auto EC = allocateBlocks(ReqBlocks, NewBlocks))
- return std::move(EC);
- StreamData.push_back(std::make_pair(Size, NewBlocks));
- return StreamData.size() - 1;
-}
-
-Error MSFBuilder::setStreamSize(uint32_t Idx, uint32_t Size) {
- uint32_t OldSize = getStreamSize(Idx);
- if (OldSize == Size)
- return Error::success();
-
- uint32_t NewBlocks = bytesToBlocks(Size, BlockSize);
- uint32_t OldBlocks = bytesToBlocks(OldSize, BlockSize);
-
- if (NewBlocks > OldBlocks) {
- uint32_t AddedBlocks = NewBlocks - OldBlocks;
- // If we're growing, we have to allocate new Blocks.
- std::vector<uint32_t> AddedBlockList;
- AddedBlockList.resize(AddedBlocks);
- if (auto EC = allocateBlocks(AddedBlocks, AddedBlockList))
- return EC;
- auto &CurrentBlocks = StreamData[Idx].second;
+//===- MSFBuilder.cpp -----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/MSF/MSFError.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileOutputBuffer.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <memory>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::support;
+
+static const uint32_t kSuperBlockBlock = 0;
+static const uint32_t kFreePageMap0Block = 1;
+static const uint32_t kFreePageMap1Block = 2;
+static const uint32_t kNumReservedPages = 3;
+
+static const uint32_t kDefaultFreePageMap = kFreePageMap1Block;
+static const uint32_t kDefaultBlockMapAddr = kNumReservedPages;
+
+MSFBuilder::MSFBuilder(uint32_t BlockSize, uint32_t MinBlockCount, bool CanGrow,
+ BumpPtrAllocator &Allocator)
+ : Allocator(Allocator), IsGrowable(CanGrow),
+ FreePageMap(kDefaultFreePageMap), BlockSize(BlockSize),
+ BlockMapAddr(kDefaultBlockMapAddr), FreeBlocks(MinBlockCount, true) {
+ FreeBlocks[kSuperBlockBlock] = false;
+ FreeBlocks[kFreePageMap0Block] = false;
+ FreeBlocks[kFreePageMap1Block] = false;
+ FreeBlocks[BlockMapAddr] = false;
+}
+
+Expected<MSFBuilder> MSFBuilder::create(BumpPtrAllocator &Allocator,
+ uint32_t BlockSize,
+ uint32_t MinBlockCount, bool CanGrow) {
+ if (!isValidBlockSize(BlockSize))
+ return make_error<MSFError>(msf_error_code::invalid_format,
+ "The requested block size is unsupported");
+
+ return MSFBuilder(BlockSize,
+ std::max(MinBlockCount, msf::getMinimumBlockCount()),
+ CanGrow, Allocator);
+}
+
+Error MSFBuilder::setBlockMapAddr(uint32_t Addr) {
+ if (Addr == BlockMapAddr)
+ return Error::success();
+
+ if (Addr >= FreeBlocks.size()) {
+ if (!IsGrowable)
+ return make_error<MSFError>(msf_error_code::insufficient_buffer,
+ "Cannot grow the number of blocks");
+ FreeBlocks.resize(Addr + 1, true);
+ }
+
+ if (!isBlockFree(Addr))
+ return make_error<MSFError>(
+ msf_error_code::block_in_use,
+ "Requested block map address is already in use");
+ FreeBlocks[BlockMapAddr] = true;
+ FreeBlocks[Addr] = false;
+ BlockMapAddr = Addr;
+ return Error::success();
+}
+
+void MSFBuilder::setFreePageMap(uint32_t Fpm) { FreePageMap = Fpm; }
+
+void MSFBuilder::setUnknown1(uint32_t Unk1) { Unknown1 = Unk1; }
+
+Error MSFBuilder::setDirectoryBlocksHint(ArrayRef<uint32_t> DirBlocks) {
+ for (auto B : DirectoryBlocks)
+ FreeBlocks[B] = true;
+ for (auto B : DirBlocks) {
+ if (!isBlockFree(B)) {
+ return make_error<MSFError>(msf_error_code::unspecified,
+ "Attempt to reuse an allocated block");
+ }
+ FreeBlocks[B] = false;
+ }
+
+ DirectoryBlocks = DirBlocks;
+ return Error::success();
+}
+
+Error MSFBuilder::allocateBlocks(uint32_t NumBlocks,
+ MutableArrayRef<uint32_t> Blocks) {
+ if (NumBlocks == 0)
+ return Error::success();
+
+ uint32_t NumFreeBlocks = FreeBlocks.count();
+ if (NumFreeBlocks < NumBlocks) {
+ if (!IsGrowable)
+ return make_error<MSFError>(msf_error_code::insufficient_buffer,
+ "There are no free Blocks in the file");
+ uint32_t AllocBlocks = NumBlocks - NumFreeBlocks;
+ uint32_t OldBlockCount = FreeBlocks.size();
+ uint32_t NewBlockCount = AllocBlocks + OldBlockCount;
+ uint32_t NextFpmBlock = alignTo(OldBlockCount, BlockSize) + 1;
+ FreeBlocks.resize(NewBlockCount, true);
+ // If we crossed over an fpm page, we actually need to allocate 2 extra
+ // blocks for each FPM group crossed and mark both blocks from the group as
+ // used. FPM blocks are marked as allocated regardless of whether or not
+ // they ultimately describe the status of blocks in the file. This means
+ // that not only are extraneous blocks at the end of the main FPM marked as
+ // allocated, but also blocks from the alternate FPM are always marked as
+ // allocated.
+ while (NextFpmBlock < NewBlockCount) {
+ NewBlockCount += 2;
+ FreeBlocks.resize(NewBlockCount, true);
+ FreeBlocks.reset(NextFpmBlock, NextFpmBlock + 2);
+ NextFpmBlock += BlockSize;
+ }
+ }
+
+ int I = 0;
+ int Block = FreeBlocks.find_first();
+ do {
+ assert(Block != -1 && "We ran out of Blocks!");
+
+ uint32_t NextBlock = static_cast<uint32_t>(Block);
+ Blocks[I++] = NextBlock;
+ FreeBlocks.reset(NextBlock);
+ Block = FreeBlocks.find_next(Block);
+ } while (--NumBlocks > 0);
+ return Error::success();
+}
+
+uint32_t MSFBuilder::getNumUsedBlocks() const {
+ return getTotalBlockCount() - getNumFreeBlocks();
+}
+
+uint32_t MSFBuilder::getNumFreeBlocks() const { return FreeBlocks.count(); }
+
+uint32_t MSFBuilder::getTotalBlockCount() const { return FreeBlocks.size(); }
+
+bool MSFBuilder::isBlockFree(uint32_t Idx) const { return FreeBlocks[Idx]; }
+
+Expected<uint32_t> MSFBuilder::addStream(uint32_t Size,
+ ArrayRef<uint32_t> Blocks) {
+ // Add a new stream mapped to the specified blocks. Verify that the specified
+ // blocks are both necessary and sufficient for holding the requested number
+ // of bytes, and verify that all requested blocks are free.
+ uint32_t ReqBlocks = bytesToBlocks(Size, BlockSize);
+ if (ReqBlocks != Blocks.size())
+ return make_error<MSFError>(
+ msf_error_code::invalid_format,
+ "Incorrect number of blocks for requested stream size");
+ for (auto Block : Blocks) {
+ if (Block >= FreeBlocks.size())
+ FreeBlocks.resize(Block + 1, true);
+
+ if (!FreeBlocks.test(Block))
+ return make_error<MSFError>(
+ msf_error_code::unspecified,
+ "Attempt to re-use an already allocated block");
+ }
+ // Mark all the blocks occupied by the new stream as not free.
+ for (auto Block : Blocks) {
+ FreeBlocks.reset(Block);
+ }
+ StreamData.push_back(std::make_pair(Size, Blocks));
+ return StreamData.size() - 1;
+}
+
+Expected<uint32_t> MSFBuilder::addStream(uint32_t Size) {
+ uint32_t ReqBlocks = bytesToBlocks(Size, BlockSize);
+ std::vector<uint32_t> NewBlocks;
+ NewBlocks.resize(ReqBlocks);
+ if (auto EC = allocateBlocks(ReqBlocks, NewBlocks))
+ return std::move(EC);
+ StreamData.push_back(std::make_pair(Size, NewBlocks));
+ return StreamData.size() - 1;
+}
+
+Error MSFBuilder::setStreamSize(uint32_t Idx, uint32_t Size) {
+ uint32_t OldSize = getStreamSize(Idx);
+ if (OldSize == Size)
+ return Error::success();
+
+ uint32_t NewBlocks = bytesToBlocks(Size, BlockSize);
+ uint32_t OldBlocks = bytesToBlocks(OldSize, BlockSize);
+
+ if (NewBlocks > OldBlocks) {
+ uint32_t AddedBlocks = NewBlocks - OldBlocks;
+ // If we're growing, we have to allocate new Blocks.
+ std::vector<uint32_t> AddedBlockList;
+ AddedBlockList.resize(AddedBlocks);
+ if (auto EC = allocateBlocks(AddedBlocks, AddedBlockList))
+ return EC;
+ auto &CurrentBlocks = StreamData[Idx].second;
llvm::append_range(CurrentBlocks, AddedBlockList);
- } else if (OldBlocks > NewBlocks) {
- // For shrinking, free all the Blocks in the Block map, update the stream
- // data, then shrink the directory.
- uint32_t RemovedBlocks = OldBlocks - NewBlocks;
- auto CurrentBlocks = ArrayRef<uint32_t>(StreamData[Idx].second);
- auto RemovedBlockList = CurrentBlocks.drop_front(NewBlocks);
- for (auto P : RemovedBlockList)
- FreeBlocks[P] = true;
- StreamData[Idx].second = CurrentBlocks.drop_back(RemovedBlocks);
- }
-
- StreamData[Idx].first = Size;
- return Error::success();
-}
-
-uint32_t MSFBuilder::getNumStreams() const { return StreamData.size(); }
-
-uint32_t MSFBuilder::getStreamSize(uint32_t StreamIdx) const {
- return StreamData[StreamIdx].first;
-}
-
-ArrayRef<uint32_t> MSFBuilder::getStreamBlocks(uint32_t StreamIdx) const {
- return StreamData[StreamIdx].second;
-}
-
-uint32_t MSFBuilder::computeDirectoryByteSize() const {
- // The directory has the following layout, where each item is a ulittle32_t:
- // NumStreams
- // StreamSizes[NumStreams]
- // StreamBlocks[NumStreams][]
- uint32_t Size = sizeof(ulittle32_t); // NumStreams
- Size += StreamData.size() * sizeof(ulittle32_t); // StreamSizes
- for (const auto &D : StreamData) {
- uint32_t ExpectedNumBlocks = bytesToBlocks(D.first, BlockSize);
- assert(ExpectedNumBlocks == D.second.size() &&
- "Unexpected number of blocks");
- Size += ExpectedNumBlocks * sizeof(ulittle32_t);
- }
- return Size;
-}
-
-Expected<MSFLayout> MSFBuilder::generateLayout() {
- SuperBlock *SB = Allocator.Allocate<SuperBlock>();
- MSFLayout L;
- L.SB = SB;
-
- std::memcpy(SB->MagicBytes, Magic, sizeof(Magic));
- SB->BlockMapAddr = BlockMapAddr;
- SB->BlockSize = BlockSize;
- SB->NumDirectoryBytes = computeDirectoryByteSize();
- SB->FreeBlockMapBlock = FreePageMap;
- SB->Unknown1 = Unknown1;
-
- uint32_t NumDirectoryBlocks = bytesToBlocks(SB->NumDirectoryBytes, BlockSize);
- if (NumDirectoryBlocks > DirectoryBlocks.size()) {
- // Our hint wasn't enough to satisfy the entire directory. Allocate
- // remaining pages.
- std::vector<uint32_t> ExtraBlocks;
- uint32_t NumExtraBlocks = NumDirectoryBlocks - DirectoryBlocks.size();
- ExtraBlocks.resize(NumExtraBlocks);
- if (auto EC = allocateBlocks(NumExtraBlocks, ExtraBlocks))
- return std::move(EC);
+ } else if (OldBlocks > NewBlocks) {
+ // For shrinking, free all the Blocks in the Block map, update the stream
+ // data, then shrink the directory.
+ uint32_t RemovedBlocks = OldBlocks - NewBlocks;
+ auto CurrentBlocks = ArrayRef<uint32_t>(StreamData[Idx].second);
+ auto RemovedBlockList = CurrentBlocks.drop_front(NewBlocks);
+ for (auto P : RemovedBlockList)
+ FreeBlocks[P] = true;
+ StreamData[Idx].second = CurrentBlocks.drop_back(RemovedBlocks);
+ }
+
+ StreamData[Idx].first = Size;
+ return Error::success();
+}
+
+uint32_t MSFBuilder::getNumStreams() const { return StreamData.size(); }
+
+uint32_t MSFBuilder::getStreamSize(uint32_t StreamIdx) const {
+ return StreamData[StreamIdx].first;
+}
+
+ArrayRef<uint32_t> MSFBuilder::getStreamBlocks(uint32_t StreamIdx) const {
+ return StreamData[StreamIdx].second;
+}
+
+uint32_t MSFBuilder::computeDirectoryByteSize() const {
+ // The directory has the following layout, where each item is a ulittle32_t:
+ // NumStreams
+ // StreamSizes[NumStreams]
+ // StreamBlocks[NumStreams][]
+ uint32_t Size = sizeof(ulittle32_t); // NumStreams
+ Size += StreamData.size() * sizeof(ulittle32_t); // StreamSizes
+ for (const auto &D : StreamData) {
+ uint32_t ExpectedNumBlocks = bytesToBlocks(D.first, BlockSize);
+ assert(ExpectedNumBlocks == D.second.size() &&
+ "Unexpected number of blocks");
+ Size += ExpectedNumBlocks * sizeof(ulittle32_t);
+ }
+ return Size;
+}
+
+Expected<MSFLayout> MSFBuilder::generateLayout() {
+ SuperBlock *SB = Allocator.Allocate<SuperBlock>();
+ MSFLayout L;
+ L.SB = SB;
+
+ std::memcpy(SB->MagicBytes, Magic, sizeof(Magic));
+ SB->BlockMapAddr = BlockMapAddr;
+ SB->BlockSize = BlockSize;
+ SB->NumDirectoryBytes = computeDirectoryByteSize();
+ SB->FreeBlockMapBlock = FreePageMap;
+ SB->Unknown1 = Unknown1;
+
+ uint32_t NumDirectoryBlocks = bytesToBlocks(SB->NumDirectoryBytes, BlockSize);
+ if (NumDirectoryBlocks > DirectoryBlocks.size()) {
+ // Our hint wasn't enough to satisfy the entire directory. Allocate
+ // remaining pages.
+ std::vector<uint32_t> ExtraBlocks;
+ uint32_t NumExtraBlocks = NumDirectoryBlocks - DirectoryBlocks.size();
+ ExtraBlocks.resize(NumExtraBlocks);
+ if (auto EC = allocateBlocks(NumExtraBlocks, ExtraBlocks))
+ return std::move(EC);
llvm::append_range(DirectoryBlocks, ExtraBlocks);
- } else if (NumDirectoryBlocks < DirectoryBlocks.size()) {
- uint32_t NumUnnecessaryBlocks = DirectoryBlocks.size() - NumDirectoryBlocks;
- for (auto B :
- ArrayRef<uint32_t>(DirectoryBlocks).drop_back(NumUnnecessaryBlocks))
- FreeBlocks[B] = true;
- DirectoryBlocks.resize(NumDirectoryBlocks);
- }
-
- // Don't set the number of blocks in the file until after allocating Blocks
- // for the directory, since the allocation might cause the file to need to
- // grow.
- SB->NumBlocks = FreeBlocks.size();
-
- ulittle32_t *DirBlocks = Allocator.Allocate<ulittle32_t>(NumDirectoryBlocks);
- std::uninitialized_copy_n(DirectoryBlocks.begin(), NumDirectoryBlocks,
- DirBlocks);
- L.DirectoryBlocks = ArrayRef<ulittle32_t>(DirBlocks, NumDirectoryBlocks);
-
- // The stream sizes should be re-allocated as a stable pointer and the stream
- // map should have each of its entries allocated as a separate stable pointer.
- if (!StreamData.empty()) {
- ulittle32_t *Sizes = Allocator.Allocate<ulittle32_t>(StreamData.size());
- L.StreamSizes = ArrayRef<ulittle32_t>(Sizes, StreamData.size());
- L.StreamMap.resize(StreamData.size());
- for (uint32_t I = 0; I < StreamData.size(); ++I) {
- Sizes[I] = StreamData[I].first;
- ulittle32_t *BlockList =
- Allocator.Allocate<ulittle32_t>(StreamData[I].second.size());
- std::uninitialized_copy_n(StreamData[I].second.begin(),
- StreamData[I].second.size(), BlockList);
- L.StreamMap[I] =
- ArrayRef<ulittle32_t>(BlockList, StreamData[I].second.size());
- }
- }
-
- L.FreePageMap = FreeBlocks;
-
- return L;
-}
-
-static void commitFpm(WritableBinaryStream &MsfBuffer, const MSFLayout &Layout,
- BumpPtrAllocator &Allocator) {
- auto FpmStream =
- WritableMappedBlockStream::createFpmStream(Layout, MsfBuffer, Allocator);
-
- // We only need to create the alt fpm stream so that it gets initialized.
- WritableMappedBlockStream::createFpmStream(Layout, MsfBuffer, Allocator,
- true);
-
- uint32_t BI = 0;
- BinaryStreamWriter FpmWriter(*FpmStream);
- while (BI < Layout.SB->NumBlocks) {
- uint8_t ThisByte = 0;
- for (uint32_t I = 0; I < 8; ++I) {
- bool IsFree =
- (BI < Layout.SB->NumBlocks) ? Layout.FreePageMap.test(BI) : true;
- uint8_t Mask = uint8_t(IsFree) << I;
- ThisByte |= Mask;
- ++BI;
- }
- cantFail(FpmWriter.writeObject(ThisByte));
- }
- assert(FpmWriter.bytesRemaining() == 0);
-}
-
-Expected<FileBufferByteStream> MSFBuilder::commit(StringRef Path,
- MSFLayout &Layout) {
- Expected<MSFLayout> L = generateLayout();
- if (!L)
- return L.takeError();
-
- Layout = std::move(*L);
-
- uint64_t FileSize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
- auto OutFileOrError = FileOutputBuffer::create(Path, FileSize);
- if (auto EC = OutFileOrError.takeError())
- return std::move(EC);
-
- FileBufferByteStream Buffer(std::move(*OutFileOrError),
- llvm::support::little);
- BinaryStreamWriter Writer(Buffer);
-
- if (auto EC = Writer.writeObject(*Layout.SB))
- return std::move(EC);
-
- commitFpm(Buffer, Layout, Allocator);
-
- uint32_t BlockMapOffset =
- msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
- Writer.setOffset(BlockMapOffset);
- if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
- return std::move(EC);
-
- auto DirStream = WritableMappedBlockStream::createDirectoryStream(
- Layout, Buffer, Allocator);
- BinaryStreamWriter DW(*DirStream);
- if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size()))
- return std::move(EC);
-
- if (auto EC = DW.writeArray(Layout.StreamSizes))
- return std::move(EC);
-
- for (const auto &Blocks : Layout.StreamMap) {
- if (auto EC = DW.writeArray(Blocks))
- return std::move(EC);
- }
-
- return std::move(Buffer);
-}
+ } else if (NumDirectoryBlocks < DirectoryBlocks.size()) {
+ uint32_t NumUnnecessaryBlocks = DirectoryBlocks.size() - NumDirectoryBlocks;
+ for (auto B :
+ ArrayRef<uint32_t>(DirectoryBlocks).drop_back(NumUnnecessaryBlocks))
+ FreeBlocks[B] = true;
+ DirectoryBlocks.resize(NumDirectoryBlocks);
+ }
+
+ // Don't set the number of blocks in the file until after allocating Blocks
+ // for the directory, since the allocation might cause the file to need to
+ // grow.
+ SB->NumBlocks = FreeBlocks.size();
+
+ ulittle32_t *DirBlocks = Allocator.Allocate<ulittle32_t>(NumDirectoryBlocks);
+ std::uninitialized_copy_n(DirectoryBlocks.begin(), NumDirectoryBlocks,
+ DirBlocks);
+ L.DirectoryBlocks = ArrayRef<ulittle32_t>(DirBlocks, NumDirectoryBlocks);
+
+ // The stream sizes should be re-allocated as a stable pointer and the stream
+ // map should have each of its entries allocated as a separate stable pointer.
+ if (!StreamData.empty()) {
+ ulittle32_t *Sizes = Allocator.Allocate<ulittle32_t>(StreamData.size());
+ L.StreamSizes = ArrayRef<ulittle32_t>(Sizes, StreamData.size());
+ L.StreamMap.resize(StreamData.size());
+ for (uint32_t I = 0; I < StreamData.size(); ++I) {
+ Sizes[I] = StreamData[I].first;
+ ulittle32_t *BlockList =
+ Allocator.Allocate<ulittle32_t>(StreamData[I].second.size());
+ std::uninitialized_copy_n(StreamData[I].second.begin(),
+ StreamData[I].second.size(), BlockList);
+ L.StreamMap[I] =
+ ArrayRef<ulittle32_t>(BlockList, StreamData[I].second.size());
+ }
+ }
+
+ L.FreePageMap = FreeBlocks;
+
+ return L;
+}
+
+static void commitFpm(WritableBinaryStream &MsfBuffer, const MSFLayout &Layout,
+ BumpPtrAllocator &Allocator) {
+ auto FpmStream =
+ WritableMappedBlockStream::createFpmStream(Layout, MsfBuffer, Allocator);
+
+ // We only need to create the alt fpm stream so that it gets initialized.
+ WritableMappedBlockStream::createFpmStream(Layout, MsfBuffer, Allocator,
+ true);
+
+ uint32_t BI = 0;
+ BinaryStreamWriter FpmWriter(*FpmStream);
+ while (BI < Layout.SB->NumBlocks) {
+ uint8_t ThisByte = 0;
+ for (uint32_t I = 0; I < 8; ++I) {
+ bool IsFree =
+ (BI < Layout.SB->NumBlocks) ? Layout.FreePageMap.test(BI) : true;
+ uint8_t Mask = uint8_t(IsFree) << I;
+ ThisByte |= Mask;
+ ++BI;
+ }
+ cantFail(FpmWriter.writeObject(ThisByte));
+ }
+ assert(FpmWriter.bytesRemaining() == 0);
+}
+
+Expected<FileBufferByteStream> MSFBuilder::commit(StringRef Path,
+ MSFLayout &Layout) {
+ Expected<MSFLayout> L = generateLayout();
+ if (!L)
+ return L.takeError();
+
+ Layout = std::move(*L);
+
+ uint64_t FileSize = Layout.SB->BlockSize * Layout.SB->NumBlocks;
+ auto OutFileOrError = FileOutputBuffer::create(Path, FileSize);
+ if (auto EC = OutFileOrError.takeError())
+ return std::move(EC);
+
+ FileBufferByteStream Buffer(std::move(*OutFileOrError),
+ llvm::support::little);
+ BinaryStreamWriter Writer(Buffer);
+
+ if (auto EC = Writer.writeObject(*Layout.SB))
+ return std::move(EC);
+
+ commitFpm(Buffer, Layout, Allocator);
+
+ uint32_t BlockMapOffset =
+ msf::blockToOffset(Layout.SB->BlockMapAddr, Layout.SB->BlockSize);
+ Writer.setOffset(BlockMapOffset);
+ if (auto EC = Writer.writeArray(Layout.DirectoryBlocks))
+ return std::move(EC);
+
+ auto DirStream = WritableMappedBlockStream::createDirectoryStream(
+ Layout, Buffer, Allocator);
+ BinaryStreamWriter DW(*DirStream);
+ if (auto EC = DW.writeInteger<uint32_t>(Layout.StreamSizes.size()))
+ return std::move(EC);
+
+ if (auto EC = DW.writeArray(Layout.StreamSizes))
+ return std::move(EC);
+
+ for (const auto &Blocks : Layout.StreamMap) {
+ if (auto EC = DW.writeArray(Blocks))
+ return std::move(EC);
+ }
+
+ return std::move(Buffer);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFCommon.cpp b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFCommon.cpp
index fb4f070005..52b6bdc320 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFCommon.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFCommon.cpp
@@ -1,82 +1,82 @@
-//===- MSFCommon.cpp - Common types and functions for MSF files -----------===//
-//
-// 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/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <cstring>
-
-using namespace llvm;
-using namespace llvm::msf;
-
-Error llvm::msf::validateSuperBlock(const SuperBlock &SB) {
- // Check the magic bytes.
- if (std::memcmp(SB.MagicBytes, Magic, sizeof(Magic)) != 0)
- return make_error<MSFError>(msf_error_code::invalid_format,
- "MSF magic header doesn't match");
-
- if (!isValidBlockSize(SB.BlockSize))
- return make_error<MSFError>(msf_error_code::invalid_format,
- "Unsupported block size.");
-
- // We don't support directories whose sizes aren't a multiple of four bytes.
- if (SB.NumDirectoryBytes % sizeof(support::ulittle32_t) != 0)
- return make_error<MSFError>(msf_error_code::invalid_format,
- "Directory size is not multiple of 4.");
-
- // The number of blocks which comprise the directory is a simple function of
- // the number of bytes it contains.
- uint64_t NumDirectoryBlocks =
- bytesToBlocks(SB.NumDirectoryBytes, SB.BlockSize);
-
- // The directory, as we understand it, is a block which consists of a list of
- // block numbers. It is unclear what would happen if the number of blocks
- // couldn't fit on a single block.
- if (NumDirectoryBlocks > SB.BlockSize / sizeof(support::ulittle32_t))
- return make_error<MSFError>(msf_error_code::invalid_format,
- "Too many directory blocks.");
-
- if (SB.BlockMapAddr == 0)
- return make_error<MSFError>(msf_error_code::invalid_format,
- "Block 0 is reserved");
-
- if (SB.BlockMapAddr >= SB.NumBlocks)
- return make_error<MSFError>(msf_error_code::invalid_format,
- "Block map address is invalid.");
-
- if (SB.FreeBlockMapBlock != 1 && SB.FreeBlockMapBlock != 2)
- return make_error<MSFError>(
- msf_error_code::invalid_format,
- "The free block map isn't at block 1 or block 2.");
-
- return Error::success();
-}
-
-MSFStreamLayout llvm::msf::getFpmStreamLayout(const MSFLayout &Msf,
- bool IncludeUnusedFpmData,
- bool AltFpm) {
- MSFStreamLayout FL;
- uint32_t NumFpmIntervals =
- getNumFpmIntervals(Msf, IncludeUnusedFpmData, AltFpm);
-
- uint32_t FpmBlock = AltFpm ? Msf.alternateFpmBlock() : Msf.mainFpmBlock();
-
- for (uint32_t I = 0; I < NumFpmIntervals; ++I) {
- FL.Blocks.push_back(support::ulittle32_t(FpmBlock));
- FpmBlock += msf::getFpmIntervalLength(Msf);
- }
-
- if (IncludeUnusedFpmData)
- FL.Length = NumFpmIntervals * Msf.SB->BlockSize;
- else
- FL.Length = divideCeil(Msf.SB->NumBlocks, 8);
-
- return FL;
-}
+//===- MSFCommon.cpp - Common types and functions for MSF files -----------===//
+//
+// 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/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MSFError.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <cstring>
+
+using namespace llvm;
+using namespace llvm::msf;
+
+Error llvm::msf::validateSuperBlock(const SuperBlock &SB) {
+ // Check the magic bytes.
+ if (std::memcmp(SB.MagicBytes, Magic, sizeof(Magic)) != 0)
+ return make_error<MSFError>(msf_error_code::invalid_format,
+ "MSF magic header doesn't match");
+
+ if (!isValidBlockSize(SB.BlockSize))
+ return make_error<MSFError>(msf_error_code::invalid_format,
+ "Unsupported block size.");
+
+ // We don't support directories whose sizes aren't a multiple of four bytes.
+ if (SB.NumDirectoryBytes % sizeof(support::ulittle32_t) != 0)
+ return make_error<MSFError>(msf_error_code::invalid_format,
+ "Directory size is not multiple of 4.");
+
+ // The number of blocks which comprise the directory is a simple function of
+ // the number of bytes it contains.
+ uint64_t NumDirectoryBlocks =
+ bytesToBlocks(SB.NumDirectoryBytes, SB.BlockSize);
+
+ // The directory, as we understand it, is a block which consists of a list of
+ // block numbers. It is unclear what would happen if the number of blocks
+ // couldn't fit on a single block.
+ if (NumDirectoryBlocks > SB.BlockSize / sizeof(support::ulittle32_t))
+ return make_error<MSFError>(msf_error_code::invalid_format,
+ "Too many directory blocks.");
+
+ if (SB.BlockMapAddr == 0)
+ return make_error<MSFError>(msf_error_code::invalid_format,
+ "Block 0 is reserved");
+
+ if (SB.BlockMapAddr >= SB.NumBlocks)
+ return make_error<MSFError>(msf_error_code::invalid_format,
+ "Block map address is invalid.");
+
+ if (SB.FreeBlockMapBlock != 1 && SB.FreeBlockMapBlock != 2)
+ return make_error<MSFError>(
+ msf_error_code::invalid_format,
+ "The free block map isn't at block 1 or block 2.");
+
+ return Error::success();
+}
+
+MSFStreamLayout llvm::msf::getFpmStreamLayout(const MSFLayout &Msf,
+ bool IncludeUnusedFpmData,
+ bool AltFpm) {
+ MSFStreamLayout FL;
+ uint32_t NumFpmIntervals =
+ getNumFpmIntervals(Msf, IncludeUnusedFpmData, AltFpm);
+
+ uint32_t FpmBlock = AltFpm ? Msf.alternateFpmBlock() : Msf.mainFpmBlock();
+
+ for (uint32_t I = 0; I < NumFpmIntervals; ++I) {
+ FL.Blocks.push_back(support::ulittle32_t(FpmBlock));
+ FpmBlock += msf::getFpmIntervalLength(Msf);
+ }
+
+ if (IncludeUnusedFpmData)
+ FL.Length = NumFpmIntervals * Msf.SB->BlockSize;
+ else
+ FL.Length = divideCeil(Msf.SB->NumBlocks, 8);
+
+ return FL;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFError.cpp b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFError.cpp
index b368b802c5..d58721110f 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFError.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/MSF/MSFError.cpp
@@ -1,47 +1,47 @@
-//===- MSFError.cpp - Error extensions for MSF files ------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/MSF/MSFError.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
-
-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.
-class MSFErrorCategory : public std::error_category {
-public:
- const char *name() const noexcept override { return "llvm.msf"; }
- std::string message(int Condition) const override {
- switch (static_cast<msf_error_code>(Condition)) {
- case msf_error_code::unspecified:
- return "An unknown error has occurred.";
- case msf_error_code::insufficient_buffer:
- return "The buffer is not large enough to read the requested number of "
- "bytes.";
- case msf_error_code::not_writable:
- return "The specified stream is not writable.";
- case msf_error_code::no_stream:
- return "The specified stream does not exist.";
- case msf_error_code::invalid_format:
- return "The data is in an unexpected format.";
- case msf_error_code::block_in_use:
- return "The block is already in use.";
- }
- llvm_unreachable("Unrecognized msf_error_code");
- }
-};
-} // namespace
-
-static llvm::ManagedStatic<MSFErrorCategory> MSFCategory;
-const std::error_category &llvm::msf::MSFErrCategory() { return *MSFCategory; }
-
-char MSFError::ID;
+//===- MSFError.cpp - Error extensions for MSF files ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/MSF/MSFError.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+
+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.
+class MSFErrorCategory : public std::error_category {
+public:
+ const char *name() const noexcept override { return "llvm.msf"; }
+ std::string message(int Condition) const override {
+ switch (static_cast<msf_error_code>(Condition)) {
+ case msf_error_code::unspecified:
+ return "An unknown error has occurred.";
+ case msf_error_code::insufficient_buffer:
+ return "The buffer is not large enough to read the requested number of "
+ "bytes.";
+ case msf_error_code::not_writable:
+ return "The specified stream is not writable.";
+ case msf_error_code::no_stream:
+ return "The specified stream does not exist.";
+ case msf_error_code::invalid_format:
+ return "The data is in an unexpected format.";
+ case msf_error_code::block_in_use:
+ return "The block is already in use.";
+ }
+ llvm_unreachable("Unrecognized msf_error_code");
+ }
+};
+} // namespace
+
+static llvm::ManagedStatic<MSFErrorCategory> MSFCategory;
+const std::error_category &llvm::msf::MSFErrCategory() { return *MSFCategory; }
+
+char MSFError::ID;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/MSF/MappedBlockStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/MSF/MappedBlockStream.cpp
index 5dc9c86b34..aa831ce327 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/MSF/MappedBlockStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/MSF/MappedBlockStream.cpp
@@ -1,421 +1,421 @@
-//===- MappedBlockStream.cpp - Reads stream data from an MSF file ---------===//
-//
-// 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/MSF/MappedBlockStream.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-#include <utility>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::msf;
-
-namespace {
-
-template <typename Base> class MappedBlockStreamImpl : public Base {
-public:
- template <typename... Args>
- MappedBlockStreamImpl(Args &&... Params)
- : Base(std::forward<Args>(Params)...) {}
-};
-
-} // end anonymous namespace
-
-using Interval = std::pair<uint32_t, uint32_t>;
-
-static Interval intersect(const Interval &I1, const Interval &I2) {
- return std::make_pair(std::max(I1.first, I2.first),
- std::min(I1.second, I2.second));
-}
-
-MappedBlockStream::MappedBlockStream(uint32_t BlockSize,
- const MSFStreamLayout &Layout,
- BinaryStreamRef MsfData,
- BumpPtrAllocator &Allocator)
- : BlockSize(BlockSize), StreamLayout(Layout), MsfData(MsfData),
- Allocator(Allocator) {}
-
-std::unique_ptr<MappedBlockStream> MappedBlockStream::createStream(
- uint32_t BlockSize, const MSFStreamLayout &Layout, BinaryStreamRef MsfData,
- BumpPtrAllocator &Allocator) {
- return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
- BlockSize, Layout, MsfData, Allocator);
-}
-
-std::unique_ptr<MappedBlockStream> MappedBlockStream::createIndexedStream(
- const MSFLayout &Layout, BinaryStreamRef MsfData, uint32_t StreamIndex,
- BumpPtrAllocator &Allocator) {
- assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
- MSFStreamLayout SL;
- SL.Blocks = Layout.StreamMap[StreamIndex];
- SL.Length = Layout.StreamSizes[StreamIndex];
- return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
- Layout.SB->BlockSize, SL, MsfData, Allocator);
-}
-
-std::unique_ptr<MappedBlockStream>
-MappedBlockStream::createDirectoryStream(const MSFLayout &Layout,
- BinaryStreamRef MsfData,
- BumpPtrAllocator &Allocator) {
- MSFStreamLayout SL;
- SL.Blocks = Layout.DirectoryBlocks;
- SL.Length = Layout.SB->NumDirectoryBytes;
- return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
-}
-
-std::unique_ptr<MappedBlockStream>
-MappedBlockStream::createFpmStream(const MSFLayout &Layout,
- BinaryStreamRef MsfData,
- BumpPtrAllocator &Allocator) {
- MSFStreamLayout SL(getFpmStreamLayout(Layout));
- return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
-}
-
-Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) {
- // Make sure we aren't trying to read beyond the end of the stream.
- if (auto EC = checkOffsetForRead(Offset, Size))
- return EC;
-
- if (tryReadContiguously(Offset, Size, Buffer))
- return Error::success();
-
- auto CacheIter = CacheMap.find(Offset);
- if (CacheIter != CacheMap.end()) {
- // Try to find an alloc that was large enough for this request.
- for (auto &Entry : CacheIter->second) {
- if (Entry.size() >= Size) {
- Buffer = Entry.slice(0, Size);
- return Error::success();
- }
- }
- }
-
- // We couldn't find a buffer that started at the correct offset (the most
- // common scenario). Try to see if there is a buffer that starts at some
- // other offset but overlaps the desired range.
- for (auto &CacheItem : CacheMap) {
- Interval RequestExtent = std::make_pair(Offset, Offset + Size);
-
- // We already checked this one on the fast path above.
- if (CacheItem.first == Offset)
- continue;
- // If the initial extent of the cached item is beyond the ending extent
- // of the request, there is no overlap.
- if (CacheItem.first >= Offset + Size)
- continue;
-
- // We really only have to check the last item in the list, since we append
- // in order of increasing length.
- if (CacheItem.second.empty())
- continue;
-
- auto CachedAlloc = CacheItem.second.back();
- // If the initial extent of the request is beyond the ending extent of
- // the cached item, there is no overlap.
- Interval CachedExtent =
- std::make_pair(CacheItem.first, CacheItem.first + CachedAlloc.size());
- if (RequestExtent.first >= CachedExtent.first + CachedExtent.second)
- continue;
-
- Interval Intersection = intersect(CachedExtent, RequestExtent);
- // Only use this if the entire request extent is contained in the cached
- // extent.
- if (Intersection != RequestExtent)
- continue;
-
- uint32_t CacheRangeOffset =
- AbsoluteDifference(CachedExtent.first, Intersection.first);
- Buffer = CachedAlloc.slice(CacheRangeOffset, Size);
- return Error::success();
- }
-
- // Otherwise allocate a large enough buffer in the pool, memcpy the data
- // into it, and return an ArrayRef to that. Do not touch existing pool
- // allocations, as existing clients may be holding a pointer which must
- // not be invalidated.
- uint8_t *WriteBuffer = static_cast<uint8_t *>(Allocator.Allocate(Size, 8));
- if (auto EC = readBytes(Offset, MutableArrayRef<uint8_t>(WriteBuffer, Size)))
- return EC;
-
- if (CacheIter != CacheMap.end()) {
- CacheIter->second.emplace_back(WriteBuffer, Size);
- } else {
- std::vector<CacheEntry> List;
- List.emplace_back(WriteBuffer, Size);
- CacheMap.insert(std::make_pair(Offset, List));
- }
- Buffer = ArrayRef<uint8_t>(WriteBuffer, Size);
- return Error::success();
-}
-
-Error MappedBlockStream::readLongestContiguousChunk(uint32_t Offset,
- ArrayRef<uint8_t> &Buffer) {
- // Make sure we aren't trying to read beyond the end of the stream.
- if (auto EC = checkOffsetForRead(Offset, 1))
- return EC;
-
- uint32_t First = Offset / BlockSize;
- uint32_t Last = First;
-
- while (Last < getNumBlocks() - 1) {
- if (StreamLayout.Blocks[Last] != StreamLayout.Blocks[Last + 1] - 1)
- break;
- ++Last;
- }
-
- uint32_t OffsetInFirstBlock = Offset % BlockSize;
- uint32_t BytesFromFirstBlock = BlockSize - OffsetInFirstBlock;
- uint32_t BlockSpan = Last - First + 1;
- uint32_t ByteSpan = BytesFromFirstBlock + (BlockSpan - 1) * BlockSize;
-
- ArrayRef<uint8_t> BlockData;
- uint32_t MsfOffset = blockToOffset(StreamLayout.Blocks[First], BlockSize);
- if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData))
- return EC;
-
- BlockData = BlockData.drop_front(OffsetInFirstBlock);
- Buffer = ArrayRef<uint8_t>(BlockData.data(), ByteSpan);
- return Error::success();
-}
-
-uint32_t MappedBlockStream::getLength() { return StreamLayout.Length; }
-
-bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) {
- if (Size == 0) {
- Buffer = ArrayRef<uint8_t>();
- return true;
- }
- // Attempt to fulfill the request with a reference directly into the stream.
- // This can work even if the request crosses a block boundary, provided that
- // all subsequent blocks are contiguous. For example, a 10k read with a 4k
- // block size can be filled with a reference if, from the starting offset,
- // 3 blocks in a row are contiguous.
- uint32_t BlockNum = Offset / BlockSize;
- uint32_t OffsetInBlock = Offset % BlockSize;
- uint32_t BytesFromFirstBlock = std::min(Size, BlockSize - OffsetInBlock);
- uint32_t NumAdditionalBlocks =
- alignTo(Size - BytesFromFirstBlock, BlockSize) / BlockSize;
-
- uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
- uint32_t E = StreamLayout.Blocks[BlockNum];
- for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
- if (StreamLayout.Blocks[I + BlockNum] != E)
- return false;
- }
-
- // Read out the entire block where the requested offset starts. Then drop
- // bytes from the beginning so that the actual starting byte lines up with
- // the requested starting byte. Then, since we know this is a contiguous
- // cross-block span, explicitly resize the ArrayRef to cover the entire
- // request length.
- ArrayRef<uint8_t> BlockData;
- uint32_t FirstBlockAddr = StreamLayout.Blocks[BlockNum];
- uint32_t MsfOffset = blockToOffset(FirstBlockAddr, BlockSize);
- if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData)) {
- consumeError(std::move(EC));
- return false;
- }
- BlockData = BlockData.drop_front(OffsetInBlock);
- Buffer = ArrayRef<uint8_t>(BlockData.data(), Size);
- return true;
-}
-
-Error MappedBlockStream::readBytes(uint32_t Offset,
- MutableArrayRef<uint8_t> Buffer) {
- uint32_t BlockNum = Offset / BlockSize;
- uint32_t OffsetInBlock = Offset % BlockSize;
-
- // Make sure we aren't trying to read beyond the end of the stream.
- if (auto EC = checkOffsetForRead(Offset, Buffer.size()))
- return EC;
-
- uint32_t BytesLeft = Buffer.size();
- uint32_t BytesWritten = 0;
- uint8_t *WriteBuffer = Buffer.data();
- while (BytesLeft > 0) {
- uint32_t StreamBlockAddr = StreamLayout.Blocks[BlockNum];
-
- ArrayRef<uint8_t> BlockData;
- uint32_t Offset = blockToOffset(StreamBlockAddr, BlockSize);
- if (auto EC = MsfData.readBytes(Offset, BlockSize, BlockData))
- return EC;
-
- const uint8_t *ChunkStart = BlockData.data() + OffsetInBlock;
- uint32_t BytesInChunk = std::min(BytesLeft, BlockSize - OffsetInBlock);
- ::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);
-
- BytesWritten += BytesInChunk;
- BytesLeft -= BytesInChunk;
- ++BlockNum;
- OffsetInBlock = 0;
- }
-
- return Error::success();
-}
-
-void MappedBlockStream::invalidateCache() { CacheMap.shrink_and_clear(); }
-
-void MappedBlockStream::fixCacheAfterWrite(uint32_t Offset,
- ArrayRef<uint8_t> Data) const {
- // If this write overlapped a read which previously came from the pool,
- // someone may still be holding a pointer to that alloc which is now invalid.
- // Compute the overlapping range and update the cache entry, so any
- // outstanding buffers are automatically updated.
- for (const auto &MapEntry : CacheMap) {
- // If the end of the written extent precedes the beginning of the cached
- // extent, ignore this map entry.
- if (Offset + Data.size() < MapEntry.first)
- continue;
- for (const auto &Alloc : MapEntry.second) {
- // If the end of the cached extent precedes the beginning of the written
- // extent, ignore this alloc.
- if (MapEntry.first + Alloc.size() < Offset)
- continue;
-
- // If we get here, they are guaranteed to overlap.
- Interval WriteInterval = std::make_pair(Offset, Offset + Data.size());
- Interval CachedInterval =
- std::make_pair(MapEntry.first, MapEntry.first + Alloc.size());
- // If they overlap, we need to write the new data into the overlapping
- // range.
- auto Intersection = intersect(WriteInterval, CachedInterval);
- assert(Intersection.first <= Intersection.second);
-
- uint32_t Length = Intersection.second - Intersection.first;
- uint32_t SrcOffset =
- AbsoluteDifference(WriteInterval.first, Intersection.first);
- uint32_t DestOffset =
- AbsoluteDifference(CachedInterval.first, Intersection.first);
- ::memcpy(Alloc.data() + DestOffset, Data.data() + SrcOffset, Length);
- }
- }
-}
-
-WritableMappedBlockStream::WritableMappedBlockStream(
- uint32_t BlockSize, const MSFStreamLayout &Layout,
- WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
- : ReadInterface(BlockSize, Layout, MsfData, Allocator),
- WriteInterface(MsfData) {}
-
-std::unique_ptr<WritableMappedBlockStream>
-WritableMappedBlockStream::createStream(uint32_t BlockSize,
- const MSFStreamLayout &Layout,
- WritableBinaryStreamRef MsfData,
- BumpPtrAllocator &Allocator) {
- return std::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
- BlockSize, Layout, MsfData, Allocator);
-}
-
-std::unique_ptr<WritableMappedBlockStream>
-WritableMappedBlockStream::createIndexedStream(const MSFLayout &Layout,
- WritableBinaryStreamRef MsfData,
- uint32_t StreamIndex,
- BumpPtrAllocator &Allocator) {
- assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
- MSFStreamLayout SL;
- SL.Blocks = Layout.StreamMap[StreamIndex];
- SL.Length = Layout.StreamSizes[StreamIndex];
- return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
-}
-
-std::unique_ptr<WritableMappedBlockStream>
-WritableMappedBlockStream::createDirectoryStream(
- const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
- BumpPtrAllocator &Allocator) {
- MSFStreamLayout SL;
- SL.Blocks = Layout.DirectoryBlocks;
- SL.Length = Layout.SB->NumDirectoryBytes;
- return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
-}
-
-std::unique_ptr<WritableMappedBlockStream>
-WritableMappedBlockStream::createFpmStream(const MSFLayout &Layout,
- WritableBinaryStreamRef MsfData,
- BumpPtrAllocator &Allocator,
- bool AltFpm) {
- // We only want to give the user a stream containing the bytes of the FPM that
- // are actually valid, but we want to initialize all of the bytes, even those
- // that come from reserved FPM blocks where the entire block is unused. To do
- // this, we first create the full layout, which gives us a stream with all
- // bytes and all blocks, and initialize everything to 0xFF (all blocks in the
- // file are unused). Then we create the minimal layout (which contains only a
- // subset of the bytes previously initialized), and return that to the user.
- MSFStreamLayout MinLayout(getFpmStreamLayout(Layout, false, AltFpm));
-
- MSFStreamLayout FullLayout(getFpmStreamLayout(Layout, true, AltFpm));
- auto Result =
- createStream(Layout.SB->BlockSize, FullLayout, MsfData, Allocator);
- if (!Result)
- return Result;
- std::vector<uint8_t> InitData(Layout.SB->BlockSize, 0xFF);
- BinaryStreamWriter Initializer(*Result);
- while (Initializer.bytesRemaining() > 0)
- cantFail(Initializer.writeBytes(InitData));
- return createStream(Layout.SB->BlockSize, MinLayout, MsfData, Allocator);
-}
-
-Error WritableMappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
- ArrayRef<uint8_t> &Buffer) {
- return ReadInterface.readBytes(Offset, Size, Buffer);
-}
-
-Error WritableMappedBlockStream::readLongestContiguousChunk(
- uint32_t Offset, ArrayRef<uint8_t> &Buffer) {
- return ReadInterface.readLongestContiguousChunk(Offset, Buffer);
-}
-
-uint32_t WritableMappedBlockStream::getLength() {
- return ReadInterface.getLength();
-}
-
-Error WritableMappedBlockStream::writeBytes(uint32_t Offset,
- ArrayRef<uint8_t> Buffer) {
- // Make sure we aren't trying to write beyond the end of the stream.
- if (auto EC = checkOffsetForWrite(Offset, Buffer.size()))
- return EC;
-
- uint32_t BlockNum = Offset / getBlockSize();
- uint32_t OffsetInBlock = Offset % getBlockSize();
-
- uint32_t BytesLeft = Buffer.size();
- uint32_t BytesWritten = 0;
- while (BytesLeft > 0) {
- uint32_t StreamBlockAddr = getStreamLayout().Blocks[BlockNum];
- uint32_t BytesToWriteInChunk =
- std::min(BytesLeft, getBlockSize() - OffsetInBlock);
-
- const uint8_t *Chunk = Buffer.data() + BytesWritten;
- ArrayRef<uint8_t> ChunkData(Chunk, BytesToWriteInChunk);
- uint32_t MsfOffset = blockToOffset(StreamBlockAddr, getBlockSize());
- MsfOffset += OffsetInBlock;
- if (auto EC = WriteInterface.writeBytes(MsfOffset, ChunkData))
- return EC;
-
- BytesLeft -= BytesToWriteInChunk;
- BytesWritten += BytesToWriteInChunk;
- ++BlockNum;
- OffsetInBlock = 0;
- }
-
- ReadInterface.fixCacheAfterWrite(Offset, Buffer);
-
- return Error::success();
-}
-
-Error WritableMappedBlockStream::commit() { return WriteInterface.commit(); }
+//===- MappedBlockStream.cpp - Reads stream data from an MSF file ---------===//
+//
+// 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/MSF/MappedBlockStream.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::msf;
+
+namespace {
+
+template <typename Base> class MappedBlockStreamImpl : public Base {
+public:
+ template <typename... Args>
+ MappedBlockStreamImpl(Args &&... Params)
+ : Base(std::forward<Args>(Params)...) {}
+};
+
+} // end anonymous namespace
+
+using Interval = std::pair<uint32_t, uint32_t>;
+
+static Interval intersect(const Interval &I1, const Interval &I2) {
+ return std::make_pair(std::max(I1.first, I2.first),
+ std::min(I1.second, I2.second));
+}
+
+MappedBlockStream::MappedBlockStream(uint32_t BlockSize,
+ const MSFStreamLayout &Layout,
+ BinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator)
+ : BlockSize(BlockSize), StreamLayout(Layout), MsfData(MsfData),
+ Allocator(Allocator) {}
+
+std::unique_ptr<MappedBlockStream> MappedBlockStream::createStream(
+ uint32_t BlockSize, const MSFStreamLayout &Layout, BinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator) {
+ return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+ BlockSize, Layout, MsfData, Allocator);
+}
+
+std::unique_ptr<MappedBlockStream> MappedBlockStream::createIndexedStream(
+ const MSFLayout &Layout, BinaryStreamRef MsfData, uint32_t StreamIndex,
+ BumpPtrAllocator &Allocator) {
+ assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
+ MSFStreamLayout SL;
+ SL.Blocks = Layout.StreamMap[StreamIndex];
+ SL.Length = Layout.StreamSizes[StreamIndex];
+ return std::make_unique<MappedBlockStreamImpl<MappedBlockStream>>(
+ Layout.SB->BlockSize, SL, MsfData, Allocator);
+}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createDirectoryStream(const MSFLayout &Layout,
+ BinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator) {
+ MSFStreamLayout SL;
+ SL.Blocks = Layout.DirectoryBlocks;
+ SL.Length = Layout.SB->NumDirectoryBytes;
+ return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
+}
+
+std::unique_ptr<MappedBlockStream>
+MappedBlockStream::createFpmStream(const MSFLayout &Layout,
+ BinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator) {
+ MSFStreamLayout SL(getFpmStreamLayout(Layout));
+ return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
+}
+
+Error MappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) {
+ // Make sure we aren't trying to read beyond the end of the stream.
+ if (auto EC = checkOffsetForRead(Offset, Size))
+ return EC;
+
+ if (tryReadContiguously(Offset, Size, Buffer))
+ return Error::success();
+
+ auto CacheIter = CacheMap.find(Offset);
+ if (CacheIter != CacheMap.end()) {
+ // Try to find an alloc that was large enough for this request.
+ for (auto &Entry : CacheIter->second) {
+ if (Entry.size() >= Size) {
+ Buffer = Entry.slice(0, Size);
+ return Error::success();
+ }
+ }
+ }
+
+ // We couldn't find a buffer that started at the correct offset (the most
+ // common scenario). Try to see if there is a buffer that starts at some
+ // other offset but overlaps the desired range.
+ for (auto &CacheItem : CacheMap) {
+ Interval RequestExtent = std::make_pair(Offset, Offset + Size);
+
+ // We already checked this one on the fast path above.
+ if (CacheItem.first == Offset)
+ continue;
+ // If the initial extent of the cached item is beyond the ending extent
+ // of the request, there is no overlap.
+ if (CacheItem.first >= Offset + Size)
+ continue;
+
+ // We really only have to check the last item in the list, since we append
+ // in order of increasing length.
+ if (CacheItem.second.empty())
+ continue;
+
+ auto CachedAlloc = CacheItem.second.back();
+ // If the initial extent of the request is beyond the ending extent of
+ // the cached item, there is no overlap.
+ Interval CachedExtent =
+ std::make_pair(CacheItem.first, CacheItem.first + CachedAlloc.size());
+ if (RequestExtent.first >= CachedExtent.first + CachedExtent.second)
+ continue;
+
+ Interval Intersection = intersect(CachedExtent, RequestExtent);
+ // Only use this if the entire request extent is contained in the cached
+ // extent.
+ if (Intersection != RequestExtent)
+ continue;
+
+ uint32_t CacheRangeOffset =
+ AbsoluteDifference(CachedExtent.first, Intersection.first);
+ Buffer = CachedAlloc.slice(CacheRangeOffset, Size);
+ return Error::success();
+ }
+
+ // Otherwise allocate a large enough buffer in the pool, memcpy the data
+ // into it, and return an ArrayRef to that. Do not touch existing pool
+ // allocations, as existing clients may be holding a pointer which must
+ // not be invalidated.
+ uint8_t *WriteBuffer = static_cast<uint8_t *>(Allocator.Allocate(Size, 8));
+ if (auto EC = readBytes(Offset, MutableArrayRef<uint8_t>(WriteBuffer, Size)))
+ return EC;
+
+ if (CacheIter != CacheMap.end()) {
+ CacheIter->second.emplace_back(WriteBuffer, Size);
+ } else {
+ std::vector<CacheEntry> List;
+ List.emplace_back(WriteBuffer, Size);
+ CacheMap.insert(std::make_pair(Offset, List));
+ }
+ Buffer = ArrayRef<uint8_t>(WriteBuffer, Size);
+ return Error::success();
+}
+
+Error MappedBlockStream::readLongestContiguousChunk(uint32_t Offset,
+ ArrayRef<uint8_t> &Buffer) {
+ // Make sure we aren't trying to read beyond the end of the stream.
+ if (auto EC = checkOffsetForRead(Offset, 1))
+ return EC;
+
+ uint32_t First = Offset / BlockSize;
+ uint32_t Last = First;
+
+ while (Last < getNumBlocks() - 1) {
+ if (StreamLayout.Blocks[Last] != StreamLayout.Blocks[Last + 1] - 1)
+ break;
+ ++Last;
+ }
+
+ uint32_t OffsetInFirstBlock = Offset % BlockSize;
+ uint32_t BytesFromFirstBlock = BlockSize - OffsetInFirstBlock;
+ uint32_t BlockSpan = Last - First + 1;
+ uint32_t ByteSpan = BytesFromFirstBlock + (BlockSpan - 1) * BlockSize;
+
+ ArrayRef<uint8_t> BlockData;
+ uint32_t MsfOffset = blockToOffset(StreamLayout.Blocks[First], BlockSize);
+ if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData))
+ return EC;
+
+ BlockData = BlockData.drop_front(OffsetInFirstBlock);
+ Buffer = ArrayRef<uint8_t>(BlockData.data(), ByteSpan);
+ return Error::success();
+}
+
+uint32_t MappedBlockStream::getLength() { return StreamLayout.Length; }
+
+bool MappedBlockStream::tryReadContiguously(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) {
+ if (Size == 0) {
+ Buffer = ArrayRef<uint8_t>();
+ return true;
+ }
+ // Attempt to fulfill the request with a reference directly into the stream.
+ // This can work even if the request crosses a block boundary, provided that
+ // all subsequent blocks are contiguous. For example, a 10k read with a 4k
+ // block size can be filled with a reference if, from the starting offset,
+ // 3 blocks in a row are contiguous.
+ uint32_t BlockNum = Offset / BlockSize;
+ uint32_t OffsetInBlock = Offset % BlockSize;
+ uint32_t BytesFromFirstBlock = std::min(Size, BlockSize - OffsetInBlock);
+ uint32_t NumAdditionalBlocks =
+ alignTo(Size - BytesFromFirstBlock, BlockSize) / BlockSize;
+
+ uint32_t RequiredContiguousBlocks = NumAdditionalBlocks + 1;
+ uint32_t E = StreamLayout.Blocks[BlockNum];
+ for (uint32_t I = 0; I < RequiredContiguousBlocks; ++I, ++E) {
+ if (StreamLayout.Blocks[I + BlockNum] != E)
+ return false;
+ }
+
+ // Read out the entire block where the requested offset starts. Then drop
+ // bytes from the beginning so that the actual starting byte lines up with
+ // the requested starting byte. Then, since we know this is a contiguous
+ // cross-block span, explicitly resize the ArrayRef to cover the entire
+ // request length.
+ ArrayRef<uint8_t> BlockData;
+ uint32_t FirstBlockAddr = StreamLayout.Blocks[BlockNum];
+ uint32_t MsfOffset = blockToOffset(FirstBlockAddr, BlockSize);
+ if (auto EC = MsfData.readBytes(MsfOffset, BlockSize, BlockData)) {
+ consumeError(std::move(EC));
+ return false;
+ }
+ BlockData = BlockData.drop_front(OffsetInBlock);
+ Buffer = ArrayRef<uint8_t>(BlockData.data(), Size);
+ return true;
+}
+
+Error MappedBlockStream::readBytes(uint32_t Offset,
+ MutableArrayRef<uint8_t> Buffer) {
+ uint32_t BlockNum = Offset / BlockSize;
+ uint32_t OffsetInBlock = Offset % BlockSize;
+
+ // Make sure we aren't trying to read beyond the end of the stream.
+ if (auto EC = checkOffsetForRead(Offset, Buffer.size()))
+ return EC;
+
+ uint32_t BytesLeft = Buffer.size();
+ uint32_t BytesWritten = 0;
+ uint8_t *WriteBuffer = Buffer.data();
+ while (BytesLeft > 0) {
+ uint32_t StreamBlockAddr = StreamLayout.Blocks[BlockNum];
+
+ ArrayRef<uint8_t> BlockData;
+ uint32_t Offset = blockToOffset(StreamBlockAddr, BlockSize);
+ if (auto EC = MsfData.readBytes(Offset, BlockSize, BlockData))
+ return EC;
+
+ const uint8_t *ChunkStart = BlockData.data() + OffsetInBlock;
+ uint32_t BytesInChunk = std::min(BytesLeft, BlockSize - OffsetInBlock);
+ ::memcpy(WriteBuffer + BytesWritten, ChunkStart, BytesInChunk);
+
+ BytesWritten += BytesInChunk;
+ BytesLeft -= BytesInChunk;
+ ++BlockNum;
+ OffsetInBlock = 0;
+ }
+
+ return Error::success();
+}
+
+void MappedBlockStream::invalidateCache() { CacheMap.shrink_and_clear(); }
+
+void MappedBlockStream::fixCacheAfterWrite(uint32_t Offset,
+ ArrayRef<uint8_t> Data) const {
+ // If this write overlapped a read which previously came from the pool,
+ // someone may still be holding a pointer to that alloc which is now invalid.
+ // Compute the overlapping range and update the cache entry, so any
+ // outstanding buffers are automatically updated.
+ for (const auto &MapEntry : CacheMap) {
+ // If the end of the written extent precedes the beginning of the cached
+ // extent, ignore this map entry.
+ if (Offset + Data.size() < MapEntry.first)
+ continue;
+ for (const auto &Alloc : MapEntry.second) {
+ // If the end of the cached extent precedes the beginning of the written
+ // extent, ignore this alloc.
+ if (MapEntry.first + Alloc.size() < Offset)
+ continue;
+
+ // If we get here, they are guaranteed to overlap.
+ Interval WriteInterval = std::make_pair(Offset, Offset + Data.size());
+ Interval CachedInterval =
+ std::make_pair(MapEntry.first, MapEntry.first + Alloc.size());
+ // If they overlap, we need to write the new data into the overlapping
+ // range.
+ auto Intersection = intersect(WriteInterval, CachedInterval);
+ assert(Intersection.first <= Intersection.second);
+
+ uint32_t Length = Intersection.second - Intersection.first;
+ uint32_t SrcOffset =
+ AbsoluteDifference(WriteInterval.first, Intersection.first);
+ uint32_t DestOffset =
+ AbsoluteDifference(CachedInterval.first, Intersection.first);
+ ::memcpy(Alloc.data() + DestOffset, Data.data() + SrcOffset, Length);
+ }
+ }
+}
+
+WritableMappedBlockStream::WritableMappedBlockStream(
+ uint32_t BlockSize, const MSFStreamLayout &Layout,
+ WritableBinaryStreamRef MsfData, BumpPtrAllocator &Allocator)
+ : ReadInterface(BlockSize, Layout, MsfData, Allocator),
+ WriteInterface(MsfData) {}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createStream(uint32_t BlockSize,
+ const MSFStreamLayout &Layout,
+ WritableBinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator) {
+ return std::make_unique<MappedBlockStreamImpl<WritableMappedBlockStream>>(
+ BlockSize, Layout, MsfData, Allocator);
+}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createIndexedStream(const MSFLayout &Layout,
+ WritableBinaryStreamRef MsfData,
+ uint32_t StreamIndex,
+ BumpPtrAllocator &Allocator) {
+ assert(StreamIndex < Layout.StreamMap.size() && "Invalid stream index");
+ MSFStreamLayout SL;
+ SL.Blocks = Layout.StreamMap[StreamIndex];
+ SL.Length = Layout.StreamSizes[StreamIndex];
+ return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
+}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createDirectoryStream(
+ const MSFLayout &Layout, WritableBinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator) {
+ MSFStreamLayout SL;
+ SL.Blocks = Layout.DirectoryBlocks;
+ SL.Length = Layout.SB->NumDirectoryBytes;
+ return createStream(Layout.SB->BlockSize, SL, MsfData, Allocator);
+}
+
+std::unique_ptr<WritableMappedBlockStream>
+WritableMappedBlockStream::createFpmStream(const MSFLayout &Layout,
+ WritableBinaryStreamRef MsfData,
+ BumpPtrAllocator &Allocator,
+ bool AltFpm) {
+ // We only want to give the user a stream containing the bytes of the FPM that
+ // are actually valid, but we want to initialize all of the bytes, even those
+ // that come from reserved FPM blocks where the entire block is unused. To do
+ // this, we first create the full layout, which gives us a stream with all
+ // bytes and all blocks, and initialize everything to 0xFF (all blocks in the
+ // file are unused). Then we create the minimal layout (which contains only a
+ // subset of the bytes previously initialized), and return that to the user.
+ MSFStreamLayout MinLayout(getFpmStreamLayout(Layout, false, AltFpm));
+
+ MSFStreamLayout FullLayout(getFpmStreamLayout(Layout, true, AltFpm));
+ auto Result =
+ createStream(Layout.SB->BlockSize, FullLayout, MsfData, Allocator);
+ if (!Result)
+ return Result;
+ std::vector<uint8_t> InitData(Layout.SB->BlockSize, 0xFF);
+ BinaryStreamWriter Initializer(*Result);
+ while (Initializer.bytesRemaining() > 0)
+ cantFail(Initializer.writeBytes(InitData));
+ return createStream(Layout.SB->BlockSize, MinLayout, MsfData, Allocator);
+}
+
+Error WritableMappedBlockStream::readBytes(uint32_t Offset, uint32_t Size,
+ ArrayRef<uint8_t> &Buffer) {
+ return ReadInterface.readBytes(Offset, Size, Buffer);
+}
+
+Error WritableMappedBlockStream::readLongestContiguousChunk(
+ uint32_t Offset, ArrayRef<uint8_t> &Buffer) {
+ return ReadInterface.readLongestContiguousChunk(Offset, Buffer);
+}
+
+uint32_t WritableMappedBlockStream::getLength() {
+ return ReadInterface.getLength();
+}
+
+Error WritableMappedBlockStream::writeBytes(uint32_t Offset,
+ ArrayRef<uint8_t> Buffer) {
+ // Make sure we aren't trying to write beyond the end of the stream.
+ if (auto EC = checkOffsetForWrite(Offset, Buffer.size()))
+ return EC;
+
+ uint32_t BlockNum = Offset / getBlockSize();
+ uint32_t OffsetInBlock = Offset % getBlockSize();
+
+ uint32_t BytesLeft = Buffer.size();
+ uint32_t BytesWritten = 0;
+ while (BytesLeft > 0) {
+ uint32_t StreamBlockAddr = getStreamLayout().Blocks[BlockNum];
+ uint32_t BytesToWriteInChunk =
+ std::min(BytesLeft, getBlockSize() - OffsetInBlock);
+
+ const uint8_t *Chunk = Buffer.data() + BytesWritten;
+ ArrayRef<uint8_t> ChunkData(Chunk, BytesToWriteInChunk);
+ uint32_t MsfOffset = blockToOffset(StreamBlockAddr, getBlockSize());
+ MsfOffset += OffsetInBlock;
+ if (auto EC = WriteInterface.writeBytes(MsfOffset, ChunkData))
+ return EC;
+
+ BytesLeft -= BytesToWriteInChunk;
+ BytesWritten += BytesToWriteInChunk;
+ ++BlockNum;
+ OffsetInBlock = 0;
+ }
+
+ ReadInterface.fixCacheAfterWrite(Offset, Buffer);
+
+ return Error::success();
+}
+
+Error WritableMappedBlockStream::commit() { return WriteInterface.commit(); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make b/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make
index a9daa7d1aa..49655ced98 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/MSF/ya.make
@@ -1,34 +1,34 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
OWNER(
orivej
g:cpp-contrib
)
-
+
LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-PEERDIR(
+PEERDIR(
contrib/libs/llvm12
contrib/libs/llvm12/lib/Support
-)
-
+)
+
ADDINCL(
contrib/libs/llvm12/lib/DebugInfo/MSF
)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
-SRCS(
- MSFBuilder.cpp
- MSFCommon.cpp
- MSFError.cpp
- MappedBlockStream.cpp
-)
-
-END()
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+SRCS(
+ MSFBuilder.cpp
+ MSFCommon.cpp
+ MSFError.cpp
+ MappedBlockStream.cpp
+)
+
+END()
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/GenericError.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/GenericError.cpp
index 0e4cba3174..623fd9f66e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/GenericError.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/GenericError.cpp
@@ -1,48 +1,48 @@
-//===- Error.cpp - system_error extensions for PDB --------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/GenericError.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
-
-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.
-class PDBErrorCategory : public std::error_category {
-public:
- const char *name() const noexcept override { return "llvm.pdb"; }
- std::string message(int Condition) const override {
- switch (static_cast<pdb_error_code>(Condition)) {
- case pdb_error_code::unspecified:
- return "An unknown error has occurred.";
- case pdb_error_code::dia_sdk_not_present:
- return "LLVM was not compiled with support for DIA. This usually means "
- "that you are not using MSVC, or your Visual Studio "
- "installation is corrupt.";
- case pdb_error_code::dia_failed_loading:
- return "DIA is only supported when using MSVC.";
- case pdb_error_code::invalid_utf8_path:
- return "The PDB file path is an invalid UTF8 sequence.";
- case pdb_error_code::signature_out_of_date:
- return "The signature does not match; the file(s) might be out of date.";
- case pdb_error_code::no_matching_pch:
- return "No matching precompiled header could be located.";
- }
- llvm_unreachable("Unrecognized generic_error_code");
- }
-};
-} // namespace
-
-static llvm::ManagedStatic<PDBErrorCategory> PDBCategory;
-const std::error_category &llvm::pdb::PDBErrCategory() { return *PDBCategory; }
-
-char PDBError::ID;
+//===- Error.cpp - system_error extensions for PDB --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/GenericError.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+
+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.
+class PDBErrorCategory : public std::error_category {
+public:
+ const char *name() const noexcept override { return "llvm.pdb"; }
+ std::string message(int Condition) const override {
+ switch (static_cast<pdb_error_code>(Condition)) {
+ case pdb_error_code::unspecified:
+ return "An unknown error has occurred.";
+ case pdb_error_code::dia_sdk_not_present:
+ return "LLVM was not compiled with support for DIA. This usually means "
+ "that you are not using MSVC, or your Visual Studio "
+ "installation is corrupt.";
+ case pdb_error_code::dia_failed_loading:
+ return "DIA is only supported when using MSVC.";
+ case pdb_error_code::invalid_utf8_path:
+ return "The PDB file path is an invalid UTF8 sequence.";
+ case pdb_error_code::signature_out_of_date:
+ return "The signature does not match; the file(s) might be out of date.";
+ case pdb_error_code::no_matching_pch:
+ return "No matching precompiled header could be located.";
+ }
+ llvm_unreachable("Unrecognized generic_error_code");
+ }
+};
+} // namespace
+
+static llvm::ManagedStatic<PDBErrorCategory> PDBCategory;
+const std::error_category &llvm::pdb::PDBErrCategory() { return *PDBCategory; }
+
+char PDBError::ID;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/IPDBSourceFile.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/IPDBSourceFile.cpp
index 113ee04bab..c92bbd4044 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/IPDBSourceFile.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/IPDBSourceFile.cpp
@@ -1,34 +1,34 @@
-//===- IPDBSourceFile.cpp - base interface for a PDB source file ----------===//
-//
-// 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/IPDBSourceFile.h"
-#include "llvm/DebugInfo/PDB/PDBExtras.h"
-#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
-#include <cstdint>
-#include <string>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-IPDBSourceFile::~IPDBSourceFile() = default;
-
-void IPDBSourceFile::dump(raw_ostream &OS, int Indent) const {
- OS.indent(Indent);
- PDB_Checksum ChecksumType = getChecksumType();
- OS << "[";
- if (ChecksumType != PDB_Checksum::None) {
- OS << ChecksumType << ": ";
- std::string Checksum = getChecksum();
- for (uint8_t c : Checksum)
- OS << format_hex_no_prefix(c, 2, true);
- } else
- OS << "No checksum";
- OS << "] " << getFileName() << "\n";
-}
+//===- IPDBSourceFile.cpp - base interface for a PDB source file ----------===//
+//
+// 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/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
+#include <string>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+IPDBSourceFile::~IPDBSourceFile() = default;
+
+void IPDBSourceFile::dump(raw_ostream &OS, int Indent) const {
+ OS.indent(Indent);
+ PDB_Checksum ChecksumType = getChecksumType();
+ OS << "[";
+ if (ChecksumType != PDB_Checksum::None) {
+ OS << ChecksumType << ": ";
+ std::string Checksum = getChecksum();
+ for (uint8_t c : Checksum)
+ OS << format_hex_no_prefix(c, 2, true);
+ } else
+ OS << "No checksum";
+ OS << "] " << getFileName() << "\n";
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
index 9755f2ca3b..7b8cb308a8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptor.cpp
@@ -1,86 +1,86 @@
-//===- DbiModuleDescriptor.cpp - PDB module information -------------------===//
-//
-// 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/DbiModuleDescriptor.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::pdb;
-using namespace llvm::support;
-
-Error DbiModuleDescriptor::initialize(BinaryStreamRef Stream,
- DbiModuleDescriptor &Info) {
- BinaryStreamReader Reader(Stream);
- if (auto EC = Reader.readObject(Info.Layout))
- return EC;
-
- if (auto EC = Reader.readCString(Info.ModuleName))
- return EC;
-
- if (auto EC = Reader.readCString(Info.ObjFileName))
- return EC;
- return Error::success();
-}
-
-bool DbiModuleDescriptor::hasECInfo() const {
- return (Layout->Flags & ModInfoFlags::HasECFlagMask) != 0;
-}
-
-uint16_t DbiModuleDescriptor::getTypeServerIndex() const {
- return (Layout->Flags & ModInfoFlags::TypeServerIndexMask) >>
- ModInfoFlags::TypeServerIndexShift;
-}
-
-const SectionContrib &DbiModuleDescriptor::getSectionContrib() const {
- return Layout->SC;
-}
-
-uint16_t DbiModuleDescriptor::getModuleStreamIndex() const {
- return Layout->ModDiStream;
-}
-
-uint32_t DbiModuleDescriptor::getSymbolDebugInfoByteSize() const {
- return Layout->SymBytes;
-}
-
-uint32_t DbiModuleDescriptor::getC11LineInfoByteSize() const {
- return Layout->C11Bytes;
-}
-
-uint32_t DbiModuleDescriptor::getC13LineInfoByteSize() const {
- return Layout->C13Bytes;
-}
-
-uint32_t DbiModuleDescriptor::getNumberOfFiles() const {
- return Layout->NumFiles;
-}
-
-uint32_t DbiModuleDescriptor::getSourceFileNameIndex() const {
- return Layout->SrcFileNameNI;
-}
-
-uint32_t DbiModuleDescriptor::getPdbFilePathNameIndex() const {
- return Layout->PdbFilePathNI;
-}
-
-StringRef DbiModuleDescriptor::getModuleName() const { return ModuleName; }
-
-StringRef DbiModuleDescriptor::getObjFileName() const { return ObjFileName; }
-
-uint32_t DbiModuleDescriptor::getRecordLength() const {
- uint32_t M = ModuleName.str().size() + 1;
- uint32_t O = ObjFileName.str().size() + 1;
- uint32_t Size = sizeof(ModuleInfoHeader) + M + O;
- Size = alignTo(Size, 4);
- return Size;
-}
+//===- DbiModuleDescriptor.cpp - PDB module information -------------------===//
+//
+// 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/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+Error DbiModuleDescriptor::initialize(BinaryStreamRef Stream,
+ DbiModuleDescriptor &Info) {
+ BinaryStreamReader Reader(Stream);
+ if (auto EC = Reader.readObject(Info.Layout))
+ return EC;
+
+ if (auto EC = Reader.readCString(Info.ModuleName))
+ return EC;
+
+ if (auto EC = Reader.readCString(Info.ObjFileName))
+ return EC;
+ return Error::success();
+}
+
+bool DbiModuleDescriptor::hasECInfo() const {
+ return (Layout->Flags & ModInfoFlags::HasECFlagMask) != 0;
+}
+
+uint16_t DbiModuleDescriptor::getTypeServerIndex() const {
+ return (Layout->Flags & ModInfoFlags::TypeServerIndexMask) >>
+ ModInfoFlags::TypeServerIndexShift;
+}
+
+const SectionContrib &DbiModuleDescriptor::getSectionContrib() const {
+ return Layout->SC;
+}
+
+uint16_t DbiModuleDescriptor::getModuleStreamIndex() const {
+ return Layout->ModDiStream;
+}
+
+uint32_t DbiModuleDescriptor::getSymbolDebugInfoByteSize() const {
+ return Layout->SymBytes;
+}
+
+uint32_t DbiModuleDescriptor::getC11LineInfoByteSize() const {
+ return Layout->C11Bytes;
+}
+
+uint32_t DbiModuleDescriptor::getC13LineInfoByteSize() const {
+ return Layout->C13Bytes;
+}
+
+uint32_t DbiModuleDescriptor::getNumberOfFiles() const {
+ return Layout->NumFiles;
+}
+
+uint32_t DbiModuleDescriptor::getSourceFileNameIndex() const {
+ return Layout->SrcFileNameNI;
+}
+
+uint32_t DbiModuleDescriptor::getPdbFilePathNameIndex() const {
+ return Layout->PdbFilePathNI;
+}
+
+StringRef DbiModuleDescriptor::getModuleName() const { return ModuleName; }
+
+StringRef DbiModuleDescriptor::getObjFileName() const { return ObjFileName; }
+
+uint32_t DbiModuleDescriptor::getRecordLength() const {
+ uint32_t M = ModuleName.str().size() + 1;
+ uint32_t O = ObjFileName.str().size() + 1;
+ uint32_t Size = sizeof(ModuleInfoHeader) + M + O;
+ Size = alignTo(Size, 4);
+ return Size;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
index b6f11a942a..84866366e9 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.cpp
@@ -1,87 +1,87 @@
-//===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
-#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize,
- uint32_t C13Size) {
- uint32_t Size = sizeof(uint32_t); // Signature
- Size += alignTo(SymbolByteSize, 4); // Symbol Data
- Size += 0; // TODO: Layout.C11Bytes
- Size += C13Size; // C13 Debug Info Size
- Size += sizeof(uint32_t); // GlobalRefs substream size (always 0)
- Size += 0; // GlobalRefs substream bytes
- return Size;
-}
-
-DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
- uint32_t ModIndex,
- msf::MSFBuilder &Msf)
- : MSF(Msf), ModuleName(std::string(ModuleName)) {
- ::memset(&Layout, 0, sizeof(Layout));
- Layout.Mod = ModIndex;
-}
-
-DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() {}
-
-uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const {
- return Layout.ModDiStream;
-}
-
-void DbiModuleDescriptorBuilder::setObjFileName(StringRef Name) {
- ObjFileName = std::string(Name);
-}
-
-void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) {
- PdbFilePathNI = NI;
-}
-
-void DbiModuleDescriptorBuilder::setFirstSectionContrib(
- const SectionContrib &SC) {
- Layout.SC = SC;
-}
-
-void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
- // Defer to the bulk API. It does the same thing.
- addSymbolsInBulk(Symbol.data());
-}
-
-void DbiModuleDescriptorBuilder::addSymbolsInBulk(
- ArrayRef<uint8_t> BulkSymbols) {
- // Do nothing for empty runs of symbols.
- if (BulkSymbols.empty())
- return;
-
+//===- DbiModuleDescriptorBuilder.cpp - PDB Mod Info Creation ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+static uint32_t calculateDiSymbolStreamSize(uint32_t SymbolByteSize,
+ uint32_t C13Size) {
+ uint32_t Size = sizeof(uint32_t); // Signature
+ Size += alignTo(SymbolByteSize, 4); // Symbol Data
+ Size += 0; // TODO: Layout.C11Bytes
+ Size += C13Size; // C13 Debug Info Size
+ Size += sizeof(uint32_t); // GlobalRefs substream size (always 0)
+ Size += 0; // GlobalRefs substream bytes
+ return Size;
+}
+
+DbiModuleDescriptorBuilder::DbiModuleDescriptorBuilder(StringRef ModuleName,
+ uint32_t ModIndex,
+ msf::MSFBuilder &Msf)
+ : MSF(Msf), ModuleName(std::string(ModuleName)) {
+ ::memset(&Layout, 0, sizeof(Layout));
+ Layout.Mod = ModIndex;
+}
+
+DbiModuleDescriptorBuilder::~DbiModuleDescriptorBuilder() {}
+
+uint16_t DbiModuleDescriptorBuilder::getStreamIndex() const {
+ return Layout.ModDiStream;
+}
+
+void DbiModuleDescriptorBuilder::setObjFileName(StringRef Name) {
+ ObjFileName = std::string(Name);
+}
+
+void DbiModuleDescriptorBuilder::setPdbFilePathNI(uint32_t NI) {
+ PdbFilePathNI = NI;
+}
+
+void DbiModuleDescriptorBuilder::setFirstSectionContrib(
+ const SectionContrib &SC) {
+ Layout.SC = SC;
+}
+
+void DbiModuleDescriptorBuilder::addSymbol(CVSymbol Symbol) {
+ // Defer to the bulk API. It does the same thing.
+ addSymbolsInBulk(Symbol.data());
+}
+
+void DbiModuleDescriptorBuilder::addSymbolsInBulk(
+ ArrayRef<uint8_t> BulkSymbols) {
+ // Do nothing for empty runs of symbols.
+ if (BulkSymbols.empty())
+ return;
+
Symbols.push_back(SymbolListWrapper(BulkSymbols));
- // Symbols written to a PDB file are required to be 4 byte aligned. The same
- // is not true of object files.
- assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
- "Invalid Symbol alignment!");
- SymbolByteSize += BulkSymbols.size();
-}
-
+ // Symbols written to a PDB file are required to be 4 byte aligned. The same
+ // is not true of object files.
+ assert(BulkSymbols.size() % alignOf(CodeViewContainer::Pdb) == 0 &&
+ "Invalid Symbol alignment!");
+ SymbolByteSize += BulkSymbols.size();
+}
+
void DbiModuleDescriptorBuilder::addUnmergedSymbols(void *SymSrc,
uint32_t SymLength) {
assert(SymLength > 0);
@@ -94,69 +94,69 @@ void DbiModuleDescriptorBuilder::addUnmergedSymbols(void *SymSrc,
SymbolByteSize += SymLength;
}
-void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
- SourceFiles.push_back(std::string(Path));
-}
-
-uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
- uint32_t Result = 0;
- for (const auto &Builder : C13Builders) {
- Result += Builder.calculateSerializedLength();
- }
- return Result;
-}
-
-uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const {
- uint32_t L = sizeof(Layout);
- uint32_t M = ModuleName.size() + 1;
- uint32_t O = ObjFileName.size() + 1;
- return alignTo(L + M + O, sizeof(uint32_t));
-}
-
-void DbiModuleDescriptorBuilder::finalize() {
- Layout.FileNameOffs = 0; // TODO: Fix this
- Layout.Flags = 0; // TODO: Fix this
- Layout.C11Bytes = 0;
- Layout.C13Bytes = calculateC13DebugInfoSize();
- (void)Layout.Mod; // Set in constructor
- (void)Layout.ModDiStream; // Set in finalizeMsfLayout
- Layout.NumFiles = SourceFiles.size();
- Layout.PdbFilePathNI = PdbFilePathNI;
- Layout.SrcFileNameNI = 0;
-
- // This value includes both the signature field as well as the record bytes
- // from the symbol stream.
- 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)
- return ExpectedSN.takeError();
- Layout.ModDiStream = *ExpectedSN;
- return Error::success();
-}
-
+void DbiModuleDescriptorBuilder::addSourceFile(StringRef Path) {
+ SourceFiles.push_back(std::string(Path));
+}
+
+uint32_t DbiModuleDescriptorBuilder::calculateC13DebugInfoSize() const {
+ uint32_t Result = 0;
+ for (const auto &Builder : C13Builders) {
+ Result += Builder.calculateSerializedLength();
+ }
+ return Result;
+}
+
+uint32_t DbiModuleDescriptorBuilder::calculateSerializedLength() const {
+ uint32_t L = sizeof(Layout);
+ uint32_t M = ModuleName.size() + 1;
+ uint32_t O = ObjFileName.size() + 1;
+ return alignTo(L + M + O, sizeof(uint32_t));
+}
+
+void DbiModuleDescriptorBuilder::finalize() {
+ Layout.FileNameOffs = 0; // TODO: Fix this
+ Layout.Flags = 0; // TODO: Fix this
+ Layout.C11Bytes = 0;
+ Layout.C13Bytes = calculateC13DebugInfoSize();
+ (void)Layout.Mod; // Set in constructor
+ (void)Layout.ModDiStream; // Set in finalizeMsfLayout
+ Layout.NumFiles = SourceFiles.size();
+ Layout.PdbFilePathNI = PdbFilePathNI;
+ Layout.SrcFileNameNI = 0;
+
+ // This value includes both the signature field as well as the record bytes
+ // from the symbol stream.
+ 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)
+ return ExpectedSN.takeError();
+ Layout.ModDiStream = *ExpectedSN;
+ return Error::success();
+}
+
Error DbiModuleDescriptorBuilder::commit(BinaryStreamWriter &ModiWriter) {
- // We write the Modi record to the `ModiWriter`, but we additionally write its
- // symbol stream to a brand new stream.
- if (auto EC = ModiWriter.writeObject(Layout))
- return EC;
- if (auto EC = ModiWriter.writeCString(ModuleName))
- return EC;
- if (auto EC = ModiWriter.writeCString(ObjFileName))
- return EC;
- if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
- return EC;
+ // We write the Modi record to the `ModiWriter`, but we additionally write its
+ // symbol stream to a brand new stream.
+ if (auto EC = ModiWriter.writeObject(Layout))
+ return EC;
+ if (auto EC = ModiWriter.writeCString(ModuleName))
+ return EC;
+ if (auto EC = ModiWriter.writeCString(ObjFileName))
+ return EC;
+ if (auto EC = ModiWriter.padToAlignment(sizeof(uint32_t)))
+ return EC;
return Error::success();
}
-
+
Error DbiModuleDescriptorBuilder::commitSymbolStream(
const msf::MSFLayout &MsfLayout, WritableBinaryStreamRef MsfBuffer) {
if (Layout.ModDiStream == kInvalidStreamIndex)
@@ -173,13 +173,13 @@ Error DbiModuleDescriptorBuilder::commitSymbolStream(
if (Sym.NeedsToBeMerged) {
assert(MergeSymsCallback);
if (auto EC = MergeSymsCallback(MergeSymsCtx, Sym.SymPtr, SymbolWriter))
- return EC;
+ return EC;
} else {
if (auto EC = SymbolWriter.writeBytes(Sym.asArray()))
- return EC;
- }
+ return EC;
+ }
}
-
+
// Apply the string table fixups.
auto SavedOffset = SymbolWriter.getOffset();
for (const StringTableFixup &Fixup : StringTableFixups) {
@@ -194,8 +194,8 @@ Error DbiModuleDescriptorBuilder::commitSymbolStream(
// TODO: Write C11 Line data
for (const auto &Builder : C13Builders) {
if (auto EC = Builder.commit(SymbolWriter, CodeViewContainer::Pdb))
- return EC;
- }
+ return EC;
+ }
// TODO: Figure out what GlobalRefs substream actually is and populate it.
if (auto EC = SymbolWriter.writeInteger<uint32_t>(0))
@@ -203,16 +203,16 @@ Error DbiModuleDescriptorBuilder::commitSymbolStream(
if (SymbolWriter.bytesRemaining() > 0)
return make_error<RawError>(raw_error_code::stream_too_long);
- return Error::success();
-}
-
-void DbiModuleDescriptorBuilder::addDebugSubsection(
- std::shared_ptr<DebugSubsection> Subsection) {
- assert(Subsection);
- C13Builders.push_back(DebugSubsectionRecordBuilder(std::move(Subsection)));
-}
-
-void DbiModuleDescriptorBuilder::addDebugSubsection(
- const DebugSubsectionRecord &SubsectionContents) {
- C13Builders.push_back(DebugSubsectionRecordBuilder(SubsectionContents));
-}
+ return Error::success();
+}
+
+void DbiModuleDescriptorBuilder::addDebugSubsection(
+ std::shared_ptr<DebugSubsection> Subsection) {
+ assert(Subsection);
+ C13Builders.push_back(DebugSubsectionRecordBuilder(std::move(Subsection)));
+}
+
+void DbiModuleDescriptorBuilder::addDebugSubsection(
+ const DebugSubsectionRecord &SubsectionContents) {
+ C13Builders.push_back(DebugSubsectionRecordBuilder(SubsectionContents));
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleList.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
index 5cf014e881..ed2d67a3a3 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiModuleList.cpp
@@ -1,279 +1,279 @@
-//===- DbiModuleList.cpp - PDB module information list --------------------===//
-//
-// 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/DbiModuleList.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cstddef>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-DbiModuleSourceFilesIterator::DbiModuleSourceFilesIterator(
- const DbiModuleList &Modules, uint32_t Modi, uint16_t Filei)
- : Modules(&Modules), Modi(Modi), Filei(Filei) {
- setValue();
-}
-
-bool DbiModuleSourceFilesIterator::
-operator==(const DbiModuleSourceFilesIterator &R) const {
- // incompatible iterators are never equal
- if (!isCompatible(R))
- return false;
-
- // If they're compatible, and they're both ends, then they're equal.
- if (isEnd() && R.isEnd())
- return true;
-
- // If one is an end and the other is not, they're not equal.
- if (isEnd() != R.isEnd())
- return false;
-
- // Now we know:
- // - They're compatible
- // - They're not *both* end iterators
- // - Their endness is the same.
- // Thus, they're compatible iterators pointing to a valid file on the same
- // module. All we need to check are the file indices.
- assert(Modules == R.Modules);
- assert(Modi == R.Modi);
- assert(!isEnd());
- assert(!R.isEnd());
-
- return (Filei == R.Filei);
-}
-
-bool DbiModuleSourceFilesIterator::
-operator<(const DbiModuleSourceFilesIterator &R) const {
- assert(isCompatible(R));
-
- // It's not sufficient to compare the file indices, because default
- // constructed iterators could be equal to iterators with valid indices. To
- // account for this, early-out if they're equal.
- if (*this == R)
- return false;
-
- return Filei < R.Filei;
-}
-
-std::ptrdiff_t DbiModuleSourceFilesIterator::
-operator-(const DbiModuleSourceFilesIterator &R) const {
- assert(isCompatible(R));
- assert(!(*this < R));
-
- // If they're both end iterators, the distance is 0.
- if (isEnd() && R.isEnd())
- return 0;
-
- assert(!R.isEnd());
-
- // At this point, R cannot be end, but *this can, which means that *this
- // might be a universal end iterator with none of its fields set. So in that
- // case have to rely on R as the authority to figure out how many files there
- // are to compute the distance.
- uint32_t Thisi = Filei;
- if (isEnd()) {
- uint32_t RealModi = R.Modi;
- Thisi = R.Modules->getSourceFileCount(RealModi);
- }
-
- assert(Thisi >= R.Filei);
- return Thisi - R.Filei;
-}
-
-DbiModuleSourceFilesIterator &DbiModuleSourceFilesIterator::
-operator+=(std::ptrdiff_t N) {
- assert(!isEnd());
-
- Filei += N;
- assert(Filei <= Modules->getSourceFileCount(Modi));
- setValue();
- return *this;
-}
-
-DbiModuleSourceFilesIterator &DbiModuleSourceFilesIterator::
-operator-=(std::ptrdiff_t N) {
- // Note that we can subtract from an end iterator, but not a universal end
- // iterator.
- assert(!isUniversalEnd());
-
- assert(N <= Filei);
-
- Filei -= N;
- return *this;
-}
-
-void DbiModuleSourceFilesIterator::setValue() {
- if (isEnd()) {
- ThisValue = "";
- return;
- }
-
- uint32_t Off = Modules->ModuleInitialFileIndex[Modi] + Filei;
- auto ExpectedValue = Modules->getFileName(Off);
- if (!ExpectedValue) {
- consumeError(ExpectedValue.takeError());
- Filei = Modules->getSourceFileCount(Modi);
- } else
- ThisValue = *ExpectedValue;
-}
-
-bool DbiModuleSourceFilesIterator::isEnd() const {
- if (isUniversalEnd())
- return true;
-
- assert(Modules);
- assert(Modi <= Modules->getModuleCount());
- assert(Filei <= Modules->getSourceFileCount(Modi));
-
- if (Modi == Modules->getModuleCount())
- return true;
- if (Filei == Modules->getSourceFileCount(Modi))
- return true;
- return false;
-}
-
-bool DbiModuleSourceFilesIterator::isUniversalEnd() const { return !Modules; }
-
-bool DbiModuleSourceFilesIterator::isCompatible(
- const DbiModuleSourceFilesIterator &R) const {
- // Universal iterators are compatible with any other iterator.
- if (isUniversalEnd() || R.isUniversalEnd())
- return true;
-
- // At this point, neither iterator is a universal end iterator, although one
- // or both might be non-universal end iterators. Regardless, the module index
- // is valid, so they are compatible if and only if they refer to the same
- // module.
- return Modi == R.Modi;
-}
-
-Error DbiModuleList::initialize(BinaryStreamRef ModInfo,
- BinaryStreamRef FileInfo) {
- if (auto EC = initializeModInfo(ModInfo))
- return EC;
- if (auto EC = initializeFileInfo(FileInfo))
- return EC;
-
- return Error::success();
-}
-
-Error DbiModuleList::initializeModInfo(BinaryStreamRef ModInfo) {
- ModInfoSubstream = ModInfo;
-
- if (ModInfo.getLength() == 0)
- return Error::success();
-
- BinaryStreamReader Reader(ModInfo);
-
- if (auto EC = Reader.readArray(Descriptors, ModInfo.getLength()))
- return EC;
-
- return Error::success();
-}
-
-Error DbiModuleList::initializeFileInfo(BinaryStreamRef FileInfo) {
- FileInfoSubstream = FileInfo;
-
- if (FileInfo.getLength() == 0)
- return Error::success();
-
- BinaryStreamReader FISR(FileInfo);
- if (auto EC = FISR.readObject(FileInfoHeader))
- return EC;
-
- // First is an array of `NumModules` module indices. This does not seem to be
- // used for anything meaningful, so we ignore it.
- FixedStreamArray<support::ulittle16_t> ModuleIndices;
- if (auto EC = FISR.readArray(ModuleIndices, FileInfoHeader->NumModules))
- return EC;
- if (auto EC = FISR.readArray(ModFileCountArray, FileInfoHeader->NumModules))
- return EC;
-
- // Compute the real number of source files. We can't trust the value in
- // `FileInfoHeader->NumSourceFiles` because it is a unit16, and the sum of all
- // source file counts might be larger than a unit16. So we compute the real
- // count by summing up the individual counts.
- uint32_t NumSourceFiles = 0;
- for (auto Count : ModFileCountArray)
- NumSourceFiles += Count;
-
- // In the reference implementation, this array is where the pointer documented
- // at the definition of ModuleInfoHeader::FileNameOffs points to. Note that
- // although the field in ModuleInfoHeader is ignored this array is not, as it
- // is the authority on where each filename begins in the names buffer.
- if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
- return EC;
-
- if (auto EC = FISR.readStreamRef(NamesBuffer))
- return EC;
-
- auto DescriptorIter = Descriptors.begin();
- uint32_t NextFileIndex = 0;
- ModuleInitialFileIndex.resize(FileInfoHeader->NumModules);
- ModuleDescriptorOffsets.resize(FileInfoHeader->NumModules);
- for (size_t I = 0; I < FileInfoHeader->NumModules; ++I) {
- assert(DescriptorIter != Descriptors.end());
- ModuleInitialFileIndex[I] = NextFileIndex;
- ModuleDescriptorOffsets[I] = DescriptorIter.offset();
-
- NextFileIndex += ModFileCountArray[I];
- ++DescriptorIter;
- }
-
- assert(DescriptorIter == Descriptors.end());
- assert(NextFileIndex == NumSourceFiles);
-
- return Error::success();
-}
-
-uint32_t DbiModuleList::getModuleCount() const {
- return FileInfoHeader->NumModules;
-}
-
-uint32_t DbiModuleList::getSourceFileCount() const {
- return FileNameOffsets.size();
-}
-
-uint16_t DbiModuleList::getSourceFileCount(uint32_t Modi) const {
- return ModFileCountArray[Modi];
-}
-
-DbiModuleDescriptor DbiModuleList::getModuleDescriptor(uint32_t Modi) const {
- assert(Modi < getModuleCount());
- uint32_t Offset = ModuleDescriptorOffsets[Modi];
- auto Iter = Descriptors.at(Offset);
- assert(Iter != Descriptors.end());
- return *Iter;
-}
-
-iterator_range<DbiModuleSourceFilesIterator>
-DbiModuleList::source_files(uint32_t Modi) const {
- return make_range<DbiModuleSourceFilesIterator>(
- DbiModuleSourceFilesIterator(*this, Modi, 0),
- DbiModuleSourceFilesIterator());
-}
-
-Expected<StringRef> DbiModuleList::getFileName(uint32_t Index) const {
- BinaryStreamReader Names(NamesBuffer);
- if (Index >= getSourceFileCount())
- return make_error<RawError>(raw_error_code::index_out_of_bounds);
-
- uint32_t FileOffset = FileNameOffsets[Index];
- Names.setOffset(FileOffset);
- StringRef Name;
- if (auto EC = Names.readCString(Name))
- return std::move(EC);
- return Name;
-}
+//===- DbiModuleList.cpp - PDB module information list --------------------===//
+//
+// 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/DbiModuleList.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+DbiModuleSourceFilesIterator::DbiModuleSourceFilesIterator(
+ const DbiModuleList &Modules, uint32_t Modi, uint16_t Filei)
+ : Modules(&Modules), Modi(Modi), Filei(Filei) {
+ setValue();
+}
+
+bool DbiModuleSourceFilesIterator::
+operator==(const DbiModuleSourceFilesIterator &R) const {
+ // incompatible iterators are never equal
+ if (!isCompatible(R))
+ return false;
+
+ // If they're compatible, and they're both ends, then they're equal.
+ if (isEnd() && R.isEnd())
+ return true;
+
+ // If one is an end and the other is not, they're not equal.
+ if (isEnd() != R.isEnd())
+ return false;
+
+ // Now we know:
+ // - They're compatible
+ // - They're not *both* end iterators
+ // - Their endness is the same.
+ // Thus, they're compatible iterators pointing to a valid file on the same
+ // module. All we need to check are the file indices.
+ assert(Modules == R.Modules);
+ assert(Modi == R.Modi);
+ assert(!isEnd());
+ assert(!R.isEnd());
+
+ return (Filei == R.Filei);
+}
+
+bool DbiModuleSourceFilesIterator::
+operator<(const DbiModuleSourceFilesIterator &R) const {
+ assert(isCompatible(R));
+
+ // It's not sufficient to compare the file indices, because default
+ // constructed iterators could be equal to iterators with valid indices. To
+ // account for this, early-out if they're equal.
+ if (*this == R)
+ return false;
+
+ return Filei < R.Filei;
+}
+
+std::ptrdiff_t DbiModuleSourceFilesIterator::
+operator-(const DbiModuleSourceFilesIterator &R) const {
+ assert(isCompatible(R));
+ assert(!(*this < R));
+
+ // If they're both end iterators, the distance is 0.
+ if (isEnd() && R.isEnd())
+ return 0;
+
+ assert(!R.isEnd());
+
+ // At this point, R cannot be end, but *this can, which means that *this
+ // might be a universal end iterator with none of its fields set. So in that
+ // case have to rely on R as the authority to figure out how many files there
+ // are to compute the distance.
+ uint32_t Thisi = Filei;
+ if (isEnd()) {
+ uint32_t RealModi = R.Modi;
+ Thisi = R.Modules->getSourceFileCount(RealModi);
+ }
+
+ assert(Thisi >= R.Filei);
+ return Thisi - R.Filei;
+}
+
+DbiModuleSourceFilesIterator &DbiModuleSourceFilesIterator::
+operator+=(std::ptrdiff_t N) {
+ assert(!isEnd());
+
+ Filei += N;
+ assert(Filei <= Modules->getSourceFileCount(Modi));
+ setValue();
+ return *this;
+}
+
+DbiModuleSourceFilesIterator &DbiModuleSourceFilesIterator::
+operator-=(std::ptrdiff_t N) {
+ // Note that we can subtract from an end iterator, but not a universal end
+ // iterator.
+ assert(!isUniversalEnd());
+
+ assert(N <= Filei);
+
+ Filei -= N;
+ return *this;
+}
+
+void DbiModuleSourceFilesIterator::setValue() {
+ if (isEnd()) {
+ ThisValue = "";
+ return;
+ }
+
+ uint32_t Off = Modules->ModuleInitialFileIndex[Modi] + Filei;
+ auto ExpectedValue = Modules->getFileName(Off);
+ if (!ExpectedValue) {
+ consumeError(ExpectedValue.takeError());
+ Filei = Modules->getSourceFileCount(Modi);
+ } else
+ ThisValue = *ExpectedValue;
+}
+
+bool DbiModuleSourceFilesIterator::isEnd() const {
+ if (isUniversalEnd())
+ return true;
+
+ assert(Modules);
+ assert(Modi <= Modules->getModuleCount());
+ assert(Filei <= Modules->getSourceFileCount(Modi));
+
+ if (Modi == Modules->getModuleCount())
+ return true;
+ if (Filei == Modules->getSourceFileCount(Modi))
+ return true;
+ return false;
+}
+
+bool DbiModuleSourceFilesIterator::isUniversalEnd() const { return !Modules; }
+
+bool DbiModuleSourceFilesIterator::isCompatible(
+ const DbiModuleSourceFilesIterator &R) const {
+ // Universal iterators are compatible with any other iterator.
+ if (isUniversalEnd() || R.isUniversalEnd())
+ return true;
+
+ // At this point, neither iterator is a universal end iterator, although one
+ // or both might be non-universal end iterators. Regardless, the module index
+ // is valid, so they are compatible if and only if they refer to the same
+ // module.
+ return Modi == R.Modi;
+}
+
+Error DbiModuleList::initialize(BinaryStreamRef ModInfo,
+ BinaryStreamRef FileInfo) {
+ if (auto EC = initializeModInfo(ModInfo))
+ return EC;
+ if (auto EC = initializeFileInfo(FileInfo))
+ return EC;
+
+ return Error::success();
+}
+
+Error DbiModuleList::initializeModInfo(BinaryStreamRef ModInfo) {
+ ModInfoSubstream = ModInfo;
+
+ if (ModInfo.getLength() == 0)
+ return Error::success();
+
+ BinaryStreamReader Reader(ModInfo);
+
+ if (auto EC = Reader.readArray(Descriptors, ModInfo.getLength()))
+ return EC;
+
+ return Error::success();
+}
+
+Error DbiModuleList::initializeFileInfo(BinaryStreamRef FileInfo) {
+ FileInfoSubstream = FileInfo;
+
+ if (FileInfo.getLength() == 0)
+ return Error::success();
+
+ BinaryStreamReader FISR(FileInfo);
+ if (auto EC = FISR.readObject(FileInfoHeader))
+ return EC;
+
+ // First is an array of `NumModules` module indices. This does not seem to be
+ // used for anything meaningful, so we ignore it.
+ FixedStreamArray<support::ulittle16_t> ModuleIndices;
+ if (auto EC = FISR.readArray(ModuleIndices, FileInfoHeader->NumModules))
+ return EC;
+ if (auto EC = FISR.readArray(ModFileCountArray, FileInfoHeader->NumModules))
+ return EC;
+
+ // Compute the real number of source files. We can't trust the value in
+ // `FileInfoHeader->NumSourceFiles` because it is a unit16, and the sum of all
+ // source file counts might be larger than a unit16. So we compute the real
+ // count by summing up the individual counts.
+ uint32_t NumSourceFiles = 0;
+ for (auto Count : ModFileCountArray)
+ NumSourceFiles += Count;
+
+ // In the reference implementation, this array is where the pointer documented
+ // at the definition of ModuleInfoHeader::FileNameOffs points to. Note that
+ // although the field in ModuleInfoHeader is ignored this array is not, as it
+ // is the authority on where each filename begins in the names buffer.
+ if (auto EC = FISR.readArray(FileNameOffsets, NumSourceFiles))
+ return EC;
+
+ if (auto EC = FISR.readStreamRef(NamesBuffer))
+ return EC;
+
+ auto DescriptorIter = Descriptors.begin();
+ uint32_t NextFileIndex = 0;
+ ModuleInitialFileIndex.resize(FileInfoHeader->NumModules);
+ ModuleDescriptorOffsets.resize(FileInfoHeader->NumModules);
+ for (size_t I = 0; I < FileInfoHeader->NumModules; ++I) {
+ assert(DescriptorIter != Descriptors.end());
+ ModuleInitialFileIndex[I] = NextFileIndex;
+ ModuleDescriptorOffsets[I] = DescriptorIter.offset();
+
+ NextFileIndex += ModFileCountArray[I];
+ ++DescriptorIter;
+ }
+
+ assert(DescriptorIter == Descriptors.end());
+ assert(NextFileIndex == NumSourceFiles);
+
+ return Error::success();
+}
+
+uint32_t DbiModuleList::getModuleCount() const {
+ return FileInfoHeader->NumModules;
+}
+
+uint32_t DbiModuleList::getSourceFileCount() const {
+ return FileNameOffsets.size();
+}
+
+uint16_t DbiModuleList::getSourceFileCount(uint32_t Modi) const {
+ return ModFileCountArray[Modi];
+}
+
+DbiModuleDescriptor DbiModuleList::getModuleDescriptor(uint32_t Modi) const {
+ assert(Modi < getModuleCount());
+ uint32_t Offset = ModuleDescriptorOffsets[Modi];
+ auto Iter = Descriptors.at(Offset);
+ assert(Iter != Descriptors.end());
+ return *Iter;
+}
+
+iterator_range<DbiModuleSourceFilesIterator>
+DbiModuleList::source_files(uint32_t Modi) const {
+ return make_range<DbiModuleSourceFilesIterator>(
+ DbiModuleSourceFilesIterator(*this, Modi, 0),
+ DbiModuleSourceFilesIterator());
+}
+
+Expected<StringRef> DbiModuleList::getFileName(uint32_t Index) const {
+ BinaryStreamReader Names(NamesBuffer);
+ if (Index >= getSourceFileCount())
+ return make_error<RawError>(raw_error_code::index_out_of_bounds);
+
+ uint32_t FileOffset = FileNameOffsets[Index];
+ Names.setOffset(FileOffset);
+ StringRef Name;
+ if (auto EC = Names.readCString(Name))
+ return std::move(EC);
+ return Name;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp
index 4eb1680417..60fedf6a9f 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStream.cpp
@@ -1,383 +1,383 @@
-//===- DbiStream.cpp - PDB Dbi Stream (Stream 3) 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/DbiStream.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
-#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Support/BinaryStreamArray.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstddef>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-using namespace llvm::support;
-
-template <typename ContribType>
-static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
- BinaryStreamReader &Reader) {
- if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
- return make_error<RawError>(
- raw_error_code::corrupt_file,
- "Invalid number of bytes of section contributions");
-
- uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType);
- if (auto EC = Reader.readArray(Output, Count))
- return EC;
- return Error::success();
-}
-
-DbiStream::DbiStream(std::unique_ptr<BinaryStream> Stream)
- : Stream(std::move(Stream)), Header(nullptr) {}
-
-DbiStream::~DbiStream() = default;
-
-Error DbiStream::reload(PDBFile *Pdb) {
- BinaryStreamReader Reader(*Stream);
-
- if (Stream->getLength() < sizeof(DbiStreamHeader))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI Stream does not contain a header.");
- if (auto EC = Reader.readObject(Header))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI Stream does not contain a header.");
-
- if (Header->VersionSignature != -1)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid DBI version signature.");
-
- // Require at least version 7, which should be present in all PDBs
- // produced in the last decade and allows us to avoid having to
- // special case all kinds of complicated arcane formats.
- if (Header->VersionHeader < PdbDbiV70)
- return make_error<RawError>(raw_error_code::feature_unsupported,
- "Unsupported DBI version.");
-
- if (Stream->getLength() !=
- sizeof(DbiStreamHeader) + Header->ModiSubstreamSize +
- Header->SecContrSubstreamSize + Header->SectionMapSize +
- Header->FileInfoSize + Header->TypeServerSize +
- Header->OptionalDbgHdrSize + Header->ECSubstreamSize)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI Length does not equal sum of substreams.");
-
- // Only certain substreams are guaranteed to be aligned. Validate
- // them here.
- if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI MODI substream not aligned.");
- if (Header->SecContrSubstreamSize % sizeof(uint32_t) != 0)
- return make_error<RawError>(
- raw_error_code::corrupt_file,
- "DBI section contribution substream not aligned.");
- if (Header->SectionMapSize % sizeof(uint32_t) != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI section map substream not aligned.");
- if (Header->FileInfoSize % sizeof(uint32_t) != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI file info substream not aligned.");
- if (Header->TypeServerSize % sizeof(uint32_t) != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "DBI type server substream not aligned.");
-
- if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
- return EC;
-
- if (auto EC = Reader.readSubstream(SecContrSubstream,
- Header->SecContrSubstreamSize))
- return EC;
- if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
- return EC;
- if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
- return EC;
- if (auto EC =
- Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
- return EC;
- if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
- return EC;
- if (auto EC = Reader.readArray(
- DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t)))
- return EC;
-
- if (auto EC = Modules.initialize(ModiSubstream.StreamData,
- FileInfoSubstream.StreamData))
- return EC;
-
- if (auto EC = initializeSectionContributionData())
- return EC;
- if (auto EC = initializeSectionHeadersData(Pdb))
- return EC;
- if (auto EC = initializeSectionMapData())
- return EC;
- 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,
- "Found unexpected bytes in DBI Stream.");
-
- if (!ECSubstream.empty()) {
- BinaryStreamReader ECReader(ECSubstream.StreamData);
- if (auto EC = ECNames.reload(ECReader))
- return EC;
- }
-
- return Error::success();
-}
-
-PdbRaw_DbiVer DbiStream::getDbiVersion() const {
- uint32_t Value = Header->VersionHeader;
- return static_cast<PdbRaw_DbiVer>(Value);
-}
-
-uint32_t DbiStream::getAge() const { return Header->Age; }
-
-uint16_t DbiStream::getPublicSymbolStreamIndex() const {
- return Header->PublicSymbolStreamIndex;
-}
-
-uint16_t DbiStream::getGlobalSymbolStreamIndex() const {
- return Header->GlobalSymbolStreamIndex;
-}
-
-uint16_t DbiStream::getFlags() const { return Header->Flags; }
-
-bool DbiStream::isIncrementallyLinked() const {
- return (Header->Flags & DbiFlags::FlagIncrementalMask) != 0;
-}
-
-bool DbiStream::hasCTypes() const {
- return (Header->Flags & DbiFlags::FlagHasCTypesMask) != 0;
-}
-
-bool DbiStream::isStripped() const {
- return (Header->Flags & DbiFlags::FlagStrippedMask) != 0;
-}
-
-uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; }
-
-uint16_t DbiStream::getBuildMajorVersion() const {
- return (Header->BuildNumber & DbiBuildNo::BuildMajorMask) >>
- DbiBuildNo::BuildMajorShift;
-}
-
-uint16_t DbiStream::getBuildMinorVersion() const {
- return (Header->BuildNumber & DbiBuildNo::BuildMinorMask) >>
- DbiBuildNo::BuildMinorShift;
-}
-
-uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; }
-
-uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; }
-
-uint32_t DbiStream::getSymRecordStreamIndex() const {
- return Header->SymRecordStreamIndex;
-}
-
-PDB_Machine DbiStream::getMachineType() const {
- uint16_t Machine = Header->MachineType;
- return static_cast<PDB_Machine>(Machine);
-}
-
-FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const {
- return SectionHeaders;
-}
-
-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; }
-
-FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
- return SectionMap;
-}
-
-void DbiStream::visitSectionContributions(
- ISectionContribVisitor &Visitor) const {
- if (!SectionContribs.empty()) {
- assert(SectionContribVersion == DbiSecContribVer60);
- for (auto &SC : SectionContribs)
- Visitor.visit(SC);
- } else if (!SectionContribs2.empty()) {
- assert(SectionContribVersion == DbiSecContribV2);
- for (auto &SC : SectionContribs2)
- Visitor.visit(SC);
- }
-}
-
-Expected<StringRef> DbiStream::getECName(uint32_t NI) const {
- return ECNames.getStringForID(NI);
-}
-
-Error DbiStream::initializeSectionContributionData() {
- if (SecContrSubstream.empty())
- return Error::success();
-
- BinaryStreamReader SCReader(SecContrSubstream.StreamData);
- if (auto EC = SCReader.readEnum(SectionContribVersion))
- return EC;
-
- if (SectionContribVersion == DbiSecContribVer60)
- return loadSectionContribs<SectionContrib>(SectionContribs, SCReader);
- if (SectionContribVersion == DbiSecContribV2)
- return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader);
-
- return make_error<RawError>(raw_error_code::feature_unsupported,
- "Unsupported DBI Section Contribution version");
-}
-
-// Initializes this->SectionHeaders.
-Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) {
- Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
- createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr);
- if (auto EC = ExpectedStream.takeError())
- return EC;
-
- auto &SHS = *ExpectedStream;
- if (!SHS)
- return Error::success();
-
- size_t StreamLen = SHS->getLength();
- if (StreamLen % sizeof(object::coff_section))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Corrupted section header stream.");
-
- size_t NumSections = StreamLen / sizeof(object::coff_section);
- BinaryStreamReader Reader(*SHS);
- if (auto EC = Reader.readArray(SectionHeaders, NumSections))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read a bitmap.");
-
- SectionHeaderStream = std::move(SHS);
- return Error::success();
-}
-
-// Initializes this->Fpos.
-Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) {
- Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
- createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO);
- if (auto EC = ExpectedStream.takeError())
- return EC;
-
- auto &FS = *ExpectedStream;
- if (!FS)
- return Error::success();
-
- size_t StreamLen = FS->getLength();
- if (StreamLen % sizeof(object::FpoData))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Corrupted Old FPO stream.");
-
- size_t NumRecords = StreamLen / sizeof(object::FpoData);
- BinaryStreamReader Reader(*FS);
- if (auto EC = Reader.readArray(OldFpoRecords, NumRecords))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "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;
-}
-
-BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
- return SecMapSubstream;
-}
-
-BinarySubstreamRef DbiStream::getModiSubstreamData() const {
- return ModiSubstream;
-}
-
-BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
- return FileInfoSubstream;
-}
-
-BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
- return TypeServerMapSubstream;
-}
-
-BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }
-
-Error DbiStream::initializeSectionMapData() {
- if (SecMapSubstream.empty())
- return Error::success();
-
- BinaryStreamReader SMReader(SecMapSubstream.StreamData);
- const SecMapHeader *Header;
- if (auto EC = SMReader.readObject(Header))
- return EC;
- if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
- return EC;
- return Error::success();
-}
-
-uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
- uint16_t T = static_cast<uint16_t>(Type);
- if (T >= DbgStreams.size())
- return kInvalidStreamIndex;
- return DbgStreams[T];
-}
+//===- DbiStream.cpp - PDB Dbi Stream (Stream 3) 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/DbiStream.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
+#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+template <typename ContribType>
+static Error loadSectionContribs(FixedStreamArray<ContribType> &Output,
+ BinaryStreamReader &Reader) {
+ if (Reader.bytesRemaining() % sizeof(ContribType) != 0)
+ return make_error<RawError>(
+ raw_error_code::corrupt_file,
+ "Invalid number of bytes of section contributions");
+
+ uint32_t Count = Reader.bytesRemaining() / sizeof(ContribType);
+ if (auto EC = Reader.readArray(Output, Count))
+ return EC;
+ return Error::success();
+}
+
+DbiStream::DbiStream(std::unique_ptr<BinaryStream> Stream)
+ : Stream(std::move(Stream)), Header(nullptr) {}
+
+DbiStream::~DbiStream() = default;
+
+Error DbiStream::reload(PDBFile *Pdb) {
+ BinaryStreamReader Reader(*Stream);
+
+ if (Stream->getLength() < sizeof(DbiStreamHeader))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "DBI Stream does not contain a header.");
+ if (auto EC = Reader.readObject(Header))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "DBI Stream does not contain a header.");
+
+ if (Header->VersionSignature != -1)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid DBI version signature.");
+
+ // Require at least version 7, which should be present in all PDBs
+ // produced in the last decade and allows us to avoid having to
+ // special case all kinds of complicated arcane formats.
+ if (Header->VersionHeader < PdbDbiV70)
+ return make_error<RawError>(raw_error_code::feature_unsupported,
+ "Unsupported DBI version.");
+
+ if (Stream->getLength() !=
+ sizeof(DbiStreamHeader) + Header->ModiSubstreamSize +
+ Header->SecContrSubstreamSize + Header->SectionMapSize +
+ Header->FileInfoSize + Header->TypeServerSize +
+ Header->OptionalDbgHdrSize + Header->ECSubstreamSize)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "DBI Length does not equal sum of substreams.");
+
+ // Only certain substreams are guaranteed to be aligned. Validate
+ // them here.
+ if (Header->ModiSubstreamSize % sizeof(uint32_t) != 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "DBI MODI substream not aligned.");
+ if (Header->SecContrSubstreamSize % sizeof(uint32_t) != 0)
+ return make_error<RawError>(
+ raw_error_code::corrupt_file,
+ "DBI section contribution substream not aligned.");
+ if (Header->SectionMapSize % sizeof(uint32_t) != 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "DBI section map substream not aligned.");
+ if (Header->FileInfoSize % sizeof(uint32_t) != 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "DBI file info substream not aligned.");
+ if (Header->TypeServerSize % sizeof(uint32_t) != 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "DBI type server substream not aligned.");
+
+ if (auto EC = Reader.readSubstream(ModiSubstream, Header->ModiSubstreamSize))
+ return EC;
+
+ if (auto EC = Reader.readSubstream(SecContrSubstream,
+ Header->SecContrSubstreamSize))
+ return EC;
+ if (auto EC = Reader.readSubstream(SecMapSubstream, Header->SectionMapSize))
+ return EC;
+ if (auto EC = Reader.readSubstream(FileInfoSubstream, Header->FileInfoSize))
+ return EC;
+ if (auto EC =
+ Reader.readSubstream(TypeServerMapSubstream, Header->TypeServerSize))
+ return EC;
+ if (auto EC = Reader.readSubstream(ECSubstream, Header->ECSubstreamSize))
+ return EC;
+ if (auto EC = Reader.readArray(
+ DbgStreams, Header->OptionalDbgHdrSize / sizeof(ulittle16_t)))
+ return EC;
+
+ if (auto EC = Modules.initialize(ModiSubstream.StreamData,
+ FileInfoSubstream.StreamData))
+ return EC;
+
+ if (auto EC = initializeSectionContributionData())
+ return EC;
+ if (auto EC = initializeSectionHeadersData(Pdb))
+ return EC;
+ if (auto EC = initializeSectionMapData())
+ return EC;
+ 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,
+ "Found unexpected bytes in DBI Stream.");
+
+ if (!ECSubstream.empty()) {
+ BinaryStreamReader ECReader(ECSubstream.StreamData);
+ if (auto EC = ECNames.reload(ECReader))
+ return EC;
+ }
+
+ return Error::success();
+}
+
+PdbRaw_DbiVer DbiStream::getDbiVersion() const {
+ uint32_t Value = Header->VersionHeader;
+ return static_cast<PdbRaw_DbiVer>(Value);
+}
+
+uint32_t DbiStream::getAge() const { return Header->Age; }
+
+uint16_t DbiStream::getPublicSymbolStreamIndex() const {
+ return Header->PublicSymbolStreamIndex;
+}
+
+uint16_t DbiStream::getGlobalSymbolStreamIndex() const {
+ return Header->GlobalSymbolStreamIndex;
+}
+
+uint16_t DbiStream::getFlags() const { return Header->Flags; }
+
+bool DbiStream::isIncrementallyLinked() const {
+ return (Header->Flags & DbiFlags::FlagIncrementalMask) != 0;
+}
+
+bool DbiStream::hasCTypes() const {
+ return (Header->Flags & DbiFlags::FlagHasCTypesMask) != 0;
+}
+
+bool DbiStream::isStripped() const {
+ return (Header->Flags & DbiFlags::FlagStrippedMask) != 0;
+}
+
+uint16_t DbiStream::getBuildNumber() const { return Header->BuildNumber; }
+
+uint16_t DbiStream::getBuildMajorVersion() const {
+ return (Header->BuildNumber & DbiBuildNo::BuildMajorMask) >>
+ DbiBuildNo::BuildMajorShift;
+}
+
+uint16_t DbiStream::getBuildMinorVersion() const {
+ return (Header->BuildNumber & DbiBuildNo::BuildMinorMask) >>
+ DbiBuildNo::BuildMinorShift;
+}
+
+uint16_t DbiStream::getPdbDllRbld() const { return Header->PdbDllRbld; }
+
+uint32_t DbiStream::getPdbDllVersion() const { return Header->PdbDllVersion; }
+
+uint32_t DbiStream::getSymRecordStreamIndex() const {
+ return Header->SymRecordStreamIndex;
+}
+
+PDB_Machine DbiStream::getMachineType() const {
+ uint16_t Machine = Header->MachineType;
+ return static_cast<PDB_Machine>(Machine);
+}
+
+FixedStreamArray<object::coff_section> DbiStream::getSectionHeaders() const {
+ return SectionHeaders;
+}
+
+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; }
+
+FixedStreamArray<SecMapEntry> DbiStream::getSectionMap() const {
+ return SectionMap;
+}
+
+void DbiStream::visitSectionContributions(
+ ISectionContribVisitor &Visitor) const {
+ if (!SectionContribs.empty()) {
+ assert(SectionContribVersion == DbiSecContribVer60);
+ for (auto &SC : SectionContribs)
+ Visitor.visit(SC);
+ } else if (!SectionContribs2.empty()) {
+ assert(SectionContribVersion == DbiSecContribV2);
+ for (auto &SC : SectionContribs2)
+ Visitor.visit(SC);
+ }
+}
+
+Expected<StringRef> DbiStream::getECName(uint32_t NI) const {
+ return ECNames.getStringForID(NI);
+}
+
+Error DbiStream::initializeSectionContributionData() {
+ if (SecContrSubstream.empty())
+ return Error::success();
+
+ BinaryStreamReader SCReader(SecContrSubstream.StreamData);
+ if (auto EC = SCReader.readEnum(SectionContribVersion))
+ return EC;
+
+ if (SectionContribVersion == DbiSecContribVer60)
+ return loadSectionContribs<SectionContrib>(SectionContribs, SCReader);
+ if (SectionContribVersion == DbiSecContribV2)
+ return loadSectionContribs<SectionContrib2>(SectionContribs2, SCReader);
+
+ return make_error<RawError>(raw_error_code::feature_unsupported,
+ "Unsupported DBI Section Contribution version");
+}
+
+// Initializes this->SectionHeaders.
+Error DbiStream::initializeSectionHeadersData(PDBFile *Pdb) {
+ Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
+ createIndexedStreamForHeaderType(Pdb, DbgHeaderType::SectionHdr);
+ if (auto EC = ExpectedStream.takeError())
+ return EC;
+
+ auto &SHS = *ExpectedStream;
+ if (!SHS)
+ return Error::success();
+
+ size_t StreamLen = SHS->getLength();
+ if (StreamLen % sizeof(object::coff_section))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Corrupted section header stream.");
+
+ size_t NumSections = StreamLen / sizeof(object::coff_section);
+ BinaryStreamReader Reader(*SHS);
+ if (auto EC = Reader.readArray(SectionHeaders, NumSections))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read a bitmap.");
+
+ SectionHeaderStream = std::move(SHS);
+ return Error::success();
+}
+
+// Initializes this->Fpos.
+Error DbiStream::initializeOldFpoRecords(PDBFile *Pdb) {
+ Expected<std::unique_ptr<msf::MappedBlockStream>> ExpectedStream =
+ createIndexedStreamForHeaderType(Pdb, DbgHeaderType::FPO);
+ if (auto EC = ExpectedStream.takeError())
+ return EC;
+
+ auto &FS = *ExpectedStream;
+ if (!FS)
+ return Error::success();
+
+ size_t StreamLen = FS->getLength();
+ if (StreamLen % sizeof(object::FpoData))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Corrupted Old FPO stream.");
+
+ size_t NumRecords = StreamLen / sizeof(object::FpoData);
+ BinaryStreamReader Reader(*FS);
+ if (auto EC = Reader.readArray(OldFpoRecords, NumRecords))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "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;
+}
+
+BinarySubstreamRef DbiStream::getSecMapSubstreamData() const {
+ return SecMapSubstream;
+}
+
+BinarySubstreamRef DbiStream::getModiSubstreamData() const {
+ return ModiSubstream;
+}
+
+BinarySubstreamRef DbiStream::getFileInfoSubstreamData() const {
+ return FileInfoSubstream;
+}
+
+BinarySubstreamRef DbiStream::getTypeServerMapSubstreamData() const {
+ return TypeServerMapSubstream;
+}
+
+BinarySubstreamRef DbiStream::getECSubstreamData() const { return ECSubstream; }
+
+Error DbiStream::initializeSectionMapData() {
+ if (SecMapSubstream.empty())
+ return Error::success();
+
+ BinaryStreamReader SMReader(SecMapSubstream.StreamData);
+ const SecMapHeader *Header;
+ if (auto EC = SMReader.readObject(Header))
+ return EC;
+ if (auto EC = SMReader.readArray(SectionMap, Header->SecCount))
+ return EC;
+ return Error::success();
+}
+
+uint32_t DbiStream::getDebugStreamIndex(DbgHeaderType Type) const {
+ uint16_t T = static_cast<uint16_t>(Type);
+ if (T >= DbgStreams.size())
+ return kInvalidStreamIndex;
+ return DbgStreams[T];
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
index 98a8acaffd..c727ba4a48 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/DbiStreamBuilder.cpp
@@ -1,404 +1,404 @@
-//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Support/BinaryStreamWriter.h"
+//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/CodeView/DebugFrameDataSubsection.h"
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/BinaryStreamWriter.h"
#include "llvm/Support/Parallel.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-DbiStreamBuilder::DbiStreamBuilder(msf::MSFBuilder &Msf)
- : Msf(Msf), Allocator(Msf.getAllocator()), Age(1), BuildNumber(0),
- PdbDllVersion(0), PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86),
- Header(nullptr) {}
-
-DbiStreamBuilder::~DbiStreamBuilder() {}
-
-void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
-
-void DbiStreamBuilder::setAge(uint32_t A) { Age = A; }
-
-void DbiStreamBuilder::setBuildNumber(uint16_t B) { BuildNumber = B; }
-
-void DbiStreamBuilder::setBuildNumber(uint8_t Major, uint8_t Minor) {
- BuildNumber = (uint16_t(Major) << DbiBuildNo::BuildMajorShift) &
- DbiBuildNo::BuildMajorMask;
- BuildNumber |= (uint16_t(Minor) << DbiBuildNo::BuildMinorShift) &
- DbiBuildNo::BuildMinorMask;
- BuildNumber |= DbiBuildNo::NewVersionFormatMask;
-}
-
-void DbiStreamBuilder::setPdbDllVersion(uint16_t V) { PdbDllVersion = V; }
-
-void DbiStreamBuilder::setPdbDllRbld(uint16_t R) { PdbDllRbld = R; }
-
-void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; }
-
-void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; }
-
-void DbiStreamBuilder::setMachineType(COFF::MachineTypes M) {
- // These enums are mirrors of each other, so we can just cast the value.
- MachineType = static_cast<pdb::PDB_Machine>(static_cast<unsigned>(M));
-}
-
-void DbiStreamBuilder::setGlobalsStreamIndex(uint32_t Index) {
- GlobalsStreamIndex = Index;
-}
-
-void DbiStreamBuilder::setSymbolRecordStreamIndex(uint32_t Index) {
- SymRecordStreamIndex = Index;
-}
-
-void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) {
- PublicsStreamIndex = Index;
-}
-
-void DbiStreamBuilder::addNewFpoData(const codeview::FrameData &FD) {
- if (!NewFpoData.hasValue())
- NewFpoData.emplace(false);
-
- NewFpoData->addFrameData(FD);
-}
-
-void DbiStreamBuilder::addOldFpoData(const object::FpoData &FD) {
- OldFpoData.push_back(FD);
-}
-
-Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
- ArrayRef<uint8_t> Data) {
- assert(Type != DbgHeaderType::NewFPO &&
- "NewFPO data should be written via addFrameData()!");
-
- DbgStreams[(int)Type].emplace();
- DbgStreams[(int)Type]->Size = Data.size();
- DbgStreams[(int)Type]->WriteFn = [Data](BinaryStreamWriter &Writer) {
- return Writer.writeArray(Data);
- };
- return Error::success();
-}
-
-uint32_t DbiStreamBuilder::addECName(StringRef Name) {
- return ECNamesBuilder.insert(Name);
-}
-
-uint32_t DbiStreamBuilder::calculateSerializedLength() const {
- // For now we only support serializing the header.
- return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() +
- calculateModiSubstreamSize() + calculateSectionContribsStreamSize() +
- calculateSectionMapStreamSize() + calculateDbgStreamsSize() +
- ECNamesBuilder.calculateSerializedSize();
-}
-
-Expected<DbiModuleDescriptorBuilder &>
-DbiStreamBuilder::addModuleInfo(StringRef ModuleName) {
- uint32_t Index = ModiList.size();
- ModiList.push_back(
- std::make_unique<DbiModuleDescriptorBuilder>(ModuleName, Index, Msf));
- return *ModiList.back();
-}
-
-Error DbiStreamBuilder::addModuleSourceFile(DbiModuleDescriptorBuilder &Module,
- StringRef File) {
- uint32_t Index = SourceFileNames.size();
- SourceFileNames.insert(std::make_pair(File, Index));
- Module.addSourceFile(File);
- return Error::success();
-}
-
-Expected<uint32_t> DbiStreamBuilder::getSourceFileNameIndex(StringRef File) {
- auto NameIter = SourceFileNames.find(File);
- if (NameIter == SourceFileNames.end())
- return make_error<RawError>(raw_error_code::no_entry,
- "The specified source file was not found");
- return NameIter->getValue();
-}
-
-uint32_t DbiStreamBuilder::calculateModiSubstreamSize() const {
- uint32_t Size = 0;
- for (const auto &M : ModiList)
- Size += M->calculateSerializedLength();
- return Size;
-}
-
-uint32_t DbiStreamBuilder::calculateSectionContribsStreamSize() const {
- if (SectionContribs.empty())
- return 0;
- return sizeof(enum PdbRaw_DbiSecContribVer) +
- sizeof(SectionContribs[0]) * SectionContribs.size();
-}
-
-uint32_t DbiStreamBuilder::calculateSectionMapStreamSize() const {
- if (SectionMap.empty())
- return 0;
- return sizeof(SecMapHeader) + sizeof(SecMapEntry) * SectionMap.size();
-}
-
-uint32_t DbiStreamBuilder::calculateNamesOffset() const {
- uint32_t Offset = 0;
- Offset += sizeof(ulittle16_t); // NumModules
- Offset += sizeof(ulittle16_t); // NumSourceFiles
- Offset += ModiList.size() * sizeof(ulittle16_t); // ModIndices
- Offset += ModiList.size() * sizeof(ulittle16_t); // ModFileCounts
- uint32_t NumFileInfos = 0;
- for (const auto &M : ModiList)
- NumFileInfos += M->source_files().size();
- Offset += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets
- return Offset;
-}
-
-uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const {
- uint32_t Size = calculateNamesOffset();
- Size += calculateNamesBufferSize();
- return alignTo(Size, sizeof(uint32_t));
-}
-
-uint32_t DbiStreamBuilder::calculateNamesBufferSize() const {
- uint32_t Size = 0;
- for (const auto &F : SourceFileNames) {
- Size += F.getKeyLength() + 1; // Names[I];
- }
- return Size;
-}
-
-uint32_t DbiStreamBuilder::calculateDbgStreamsSize() const {
- return DbgStreams.size() * sizeof(uint16_t);
-}
-
-Error DbiStreamBuilder::generateFileInfoSubstream() {
- uint32_t Size = calculateFileInfoSubstreamSize();
- auto Data = Allocator.Allocate<uint8_t>(Size);
- uint32_t NamesOffset = calculateNamesOffset();
-
- FileInfoBuffer = MutableBinaryByteStream(MutableArrayRef<uint8_t>(Data, Size),
- llvm::support::little);
-
- WritableBinaryStreamRef MetadataBuffer =
- WritableBinaryStreamRef(FileInfoBuffer).keep_front(NamesOffset);
- BinaryStreamWriter MetadataWriter(MetadataBuffer);
-
- uint16_t ModiCount = std::min<uint32_t>(UINT16_MAX, ModiList.size());
- uint16_t FileCount = std::min<uint32_t>(UINT16_MAX, SourceFileNames.size());
- if (auto EC = MetadataWriter.writeInteger(ModiCount)) // NumModules
- return EC;
- if (auto EC = MetadataWriter.writeInteger(FileCount)) // NumSourceFiles
- return EC;
- for (uint16_t I = 0; I < ModiCount; ++I) {
- if (auto EC = MetadataWriter.writeInteger(I)) // Mod Indices
- return EC;
- }
- for (const auto &MI : ModiList) {
- FileCount = static_cast<uint16_t>(MI->source_files().size());
- if (auto EC = MetadataWriter.writeInteger(FileCount)) // Mod File Counts
- return EC;
- }
-
- // Before writing the FileNameOffsets array, write the NamesBuffer array.
- // A side effect of this is that this will actually compute the various
- // file name offsets, so we can then go back and write the FileNameOffsets
- // array to the other substream.
- NamesBuffer = WritableBinaryStreamRef(FileInfoBuffer).drop_front(NamesOffset);
- BinaryStreamWriter NameBufferWriter(NamesBuffer);
- for (auto &Name : SourceFileNames) {
- Name.second = NameBufferWriter.getOffset();
- if (auto EC = NameBufferWriter.writeCString(Name.getKey()))
- return EC;
- }
-
- for (const auto &MI : ModiList) {
- for (StringRef Name : MI->source_files()) {
- auto Result = SourceFileNames.find(Name);
- if (Result == SourceFileNames.end())
- return make_error<RawError>(raw_error_code::no_entry,
- "The source file was not found.");
- if (auto EC = MetadataWriter.writeInteger(Result->second))
- return EC;
- }
- }
-
- if (auto EC = NameBufferWriter.padToAlignment(sizeof(uint32_t)))
- return EC;
-
- if (NameBufferWriter.bytesRemaining() > 0)
- return make_error<RawError>(raw_error_code::invalid_format,
- "The names buffer contained unexpected data.");
-
- if (MetadataWriter.bytesRemaining() > sizeof(uint32_t))
- return make_error<RawError>(
- raw_error_code::invalid_format,
- "The metadata buffer contained unexpected data.");
-
- return Error::success();
-}
-
-Error DbiStreamBuilder::finalize() {
- if (Header)
- return Error::success();
-
- for (auto &MI : ModiList)
- MI->finalize();
-
- if (auto EC = generateFileInfoSubstream())
- return EC;
-
- DbiStreamHeader *H = Allocator.Allocate<DbiStreamHeader>();
- ::memset(H, 0, sizeof(DbiStreamHeader));
- H->VersionHeader = *VerHeader;
- H->VersionSignature = -1;
- H->Age = Age;
- H->BuildNumber = BuildNumber;
- H->Flags = Flags;
- H->PdbDllRbld = PdbDllRbld;
- H->PdbDllVersion = PdbDllVersion;
- H->MachineType = static_cast<uint16_t>(MachineType);
-
- H->ECSubstreamSize = ECNamesBuilder.calculateSerializedSize();
- H->FileInfoSize = FileInfoBuffer.getLength();
- H->ModiSubstreamSize = calculateModiSubstreamSize();
- H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t);
- H->SecContrSubstreamSize = calculateSectionContribsStreamSize();
- H->SectionMapSize = calculateSectionMapStreamSize();
- H->TypeServerSize = 0;
- H->SymRecordStreamIndex = SymRecordStreamIndex;
- H->PublicSymbolStreamIndex = PublicsStreamIndex;
- H->MFCTypeServerIndex = 0; // Not sure what this is, but link.exe writes 0.
- H->GlobalSymbolStreamIndex = GlobalsStreamIndex;
-
- Header = H;
- return Error::success();
-}
-
-Error DbiStreamBuilder::finalizeMsfLayout() {
- if (NewFpoData.hasValue()) {
- DbgStreams[(int)DbgHeaderType::NewFPO].emplace();
- DbgStreams[(int)DbgHeaderType::NewFPO]->Size =
- NewFpoData->calculateSerializedSize();
- DbgStreams[(int)DbgHeaderType::NewFPO]->WriteFn =
- [this](BinaryStreamWriter &Writer) {
- return NewFpoData->commit(Writer);
- };
- }
-
- if (!OldFpoData.empty()) {
- DbgStreams[(int)DbgHeaderType::FPO].emplace();
- DbgStreams[(int)DbgHeaderType::FPO]->Size =
- sizeof(object::FpoData) * OldFpoData.size();
- DbgStreams[(int)DbgHeaderType::FPO]->WriteFn =
- [this](BinaryStreamWriter &Writer) {
- return Writer.writeArray(makeArrayRef(OldFpoData));
- };
- }
-
- for (auto &S : DbgStreams) {
- if (!S.hasValue())
- continue;
- auto ExpectedIndex = Msf.addStream(S->Size);
- if (!ExpectedIndex)
- return ExpectedIndex.takeError();
- S->StreamNumber = *ExpectedIndex;
- }
-
- for (auto &MI : ModiList) {
- if (auto EC = MI->finalizeMsfLayout())
- return EC;
- }
-
- uint32_t Length = calculateSerializedLength();
- if (auto EC = Msf.setStreamSize(StreamDBI, Length))
- return EC;
- return Error::success();
-}
-
-static uint16_t toSecMapFlags(uint32_t Flags) {
- uint16_t Ret = 0;
- if (Flags & COFF::IMAGE_SCN_MEM_READ)
- Ret |= static_cast<uint16_t>(OMFSegDescFlags::Read);
- if (Flags & COFF::IMAGE_SCN_MEM_WRITE)
- Ret |= static_cast<uint16_t>(OMFSegDescFlags::Write);
- if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
- Ret |= static_cast<uint16_t>(OMFSegDescFlags::Execute);
- if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
- Ret |= static_cast<uint16_t>(OMFSegDescFlags::Execute);
- if (!(Flags & COFF::IMAGE_SCN_MEM_16BIT))
- Ret |= static_cast<uint16_t>(OMFSegDescFlags::AddressIs32Bit);
-
- // This seems always 1.
- Ret |= static_cast<uint16_t>(OMFSegDescFlags::IsSelector);
-
- return Ret;
-}
-
-// Populate the Section Map from COFF section headers.
-//
-// A Section Map seem to be a copy of a COFF section list in other format.
-// I don't know why a PDB file contains both a COFF section header and
-// a Section Map, but it seems it must be present in a PDB.
-void DbiStreamBuilder::createSectionMap(
- ArrayRef<llvm::object::coff_section> SecHdrs) {
- int Idx = 0;
-
- auto Add = [&]() -> SecMapEntry & {
- SectionMap.emplace_back();
- auto &Entry = SectionMap.back();
- memset(&Entry, 0, sizeof(Entry));
-
- Entry.Frame = Idx + 1;
-
- // We don't know the meaning of these fields yet.
- Entry.SecName = UINT16_MAX;
- Entry.ClassName = UINT16_MAX;
-
- return Entry;
- };
-
- for (auto &Hdr : SecHdrs) {
- auto &Entry = Add();
- Entry.Flags = toSecMapFlags(Hdr.Characteristics);
- Entry.SecByteLength = Hdr.VirtualSize;
- ++Idx;
- }
-
- // The last entry is for absolute symbols.
- auto &Entry = Add();
- Entry.Flags = static_cast<uint16_t>(OMFSegDescFlags::AddressIs32Bit) |
- static_cast<uint16_t>(OMFSegDescFlags::IsAbsoluteAddress);
- Entry.SecByteLength = UINT32_MAX;
-}
-
-Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
- WritableBinaryStreamRef MsfBuffer) {
- if (auto EC = finalize())
- return EC;
-
- auto DbiS = WritableMappedBlockStream::createIndexedStream(
- Layout, MsfBuffer, StreamDBI, Allocator);
-
- BinaryStreamWriter Writer(*DbiS);
- if (auto EC = Writer.writeObject(*Header))
- return EC;
-
- for (auto &M : ModiList) {
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+DbiStreamBuilder::DbiStreamBuilder(msf::MSFBuilder &Msf)
+ : Msf(Msf), Allocator(Msf.getAllocator()), Age(1), BuildNumber(0),
+ PdbDllVersion(0), PdbDllRbld(0), Flags(0), MachineType(PDB_Machine::x86),
+ Header(nullptr) {}
+
+DbiStreamBuilder::~DbiStreamBuilder() {}
+
+void DbiStreamBuilder::setVersionHeader(PdbRaw_DbiVer V) { VerHeader = V; }
+
+void DbiStreamBuilder::setAge(uint32_t A) { Age = A; }
+
+void DbiStreamBuilder::setBuildNumber(uint16_t B) { BuildNumber = B; }
+
+void DbiStreamBuilder::setBuildNumber(uint8_t Major, uint8_t Minor) {
+ BuildNumber = (uint16_t(Major) << DbiBuildNo::BuildMajorShift) &
+ DbiBuildNo::BuildMajorMask;
+ BuildNumber |= (uint16_t(Minor) << DbiBuildNo::BuildMinorShift) &
+ DbiBuildNo::BuildMinorMask;
+ BuildNumber |= DbiBuildNo::NewVersionFormatMask;
+}
+
+void DbiStreamBuilder::setPdbDllVersion(uint16_t V) { PdbDllVersion = V; }
+
+void DbiStreamBuilder::setPdbDllRbld(uint16_t R) { PdbDllRbld = R; }
+
+void DbiStreamBuilder::setFlags(uint16_t F) { Flags = F; }
+
+void DbiStreamBuilder::setMachineType(PDB_Machine M) { MachineType = M; }
+
+void DbiStreamBuilder::setMachineType(COFF::MachineTypes M) {
+ // These enums are mirrors of each other, so we can just cast the value.
+ MachineType = static_cast<pdb::PDB_Machine>(static_cast<unsigned>(M));
+}
+
+void DbiStreamBuilder::setGlobalsStreamIndex(uint32_t Index) {
+ GlobalsStreamIndex = Index;
+}
+
+void DbiStreamBuilder::setSymbolRecordStreamIndex(uint32_t Index) {
+ SymRecordStreamIndex = Index;
+}
+
+void DbiStreamBuilder::setPublicsStreamIndex(uint32_t Index) {
+ PublicsStreamIndex = Index;
+}
+
+void DbiStreamBuilder::addNewFpoData(const codeview::FrameData &FD) {
+ if (!NewFpoData.hasValue())
+ NewFpoData.emplace(false);
+
+ NewFpoData->addFrameData(FD);
+}
+
+void DbiStreamBuilder::addOldFpoData(const object::FpoData &FD) {
+ OldFpoData.push_back(FD);
+}
+
+Error DbiStreamBuilder::addDbgStream(pdb::DbgHeaderType Type,
+ ArrayRef<uint8_t> Data) {
+ assert(Type != DbgHeaderType::NewFPO &&
+ "NewFPO data should be written via addFrameData()!");
+
+ DbgStreams[(int)Type].emplace();
+ DbgStreams[(int)Type]->Size = Data.size();
+ DbgStreams[(int)Type]->WriteFn = [Data](BinaryStreamWriter &Writer) {
+ return Writer.writeArray(Data);
+ };
+ return Error::success();
+}
+
+uint32_t DbiStreamBuilder::addECName(StringRef Name) {
+ return ECNamesBuilder.insert(Name);
+}
+
+uint32_t DbiStreamBuilder::calculateSerializedLength() const {
+ // For now we only support serializing the header.
+ return sizeof(DbiStreamHeader) + calculateFileInfoSubstreamSize() +
+ calculateModiSubstreamSize() + calculateSectionContribsStreamSize() +
+ calculateSectionMapStreamSize() + calculateDbgStreamsSize() +
+ ECNamesBuilder.calculateSerializedSize();
+}
+
+Expected<DbiModuleDescriptorBuilder &>
+DbiStreamBuilder::addModuleInfo(StringRef ModuleName) {
+ uint32_t Index = ModiList.size();
+ ModiList.push_back(
+ std::make_unique<DbiModuleDescriptorBuilder>(ModuleName, Index, Msf));
+ return *ModiList.back();
+}
+
+Error DbiStreamBuilder::addModuleSourceFile(DbiModuleDescriptorBuilder &Module,
+ StringRef File) {
+ uint32_t Index = SourceFileNames.size();
+ SourceFileNames.insert(std::make_pair(File, Index));
+ Module.addSourceFile(File);
+ return Error::success();
+}
+
+Expected<uint32_t> DbiStreamBuilder::getSourceFileNameIndex(StringRef File) {
+ auto NameIter = SourceFileNames.find(File);
+ if (NameIter == SourceFileNames.end())
+ return make_error<RawError>(raw_error_code::no_entry,
+ "The specified source file was not found");
+ return NameIter->getValue();
+}
+
+uint32_t DbiStreamBuilder::calculateModiSubstreamSize() const {
+ uint32_t Size = 0;
+ for (const auto &M : ModiList)
+ Size += M->calculateSerializedLength();
+ return Size;
+}
+
+uint32_t DbiStreamBuilder::calculateSectionContribsStreamSize() const {
+ if (SectionContribs.empty())
+ return 0;
+ return sizeof(enum PdbRaw_DbiSecContribVer) +
+ sizeof(SectionContribs[0]) * SectionContribs.size();
+}
+
+uint32_t DbiStreamBuilder::calculateSectionMapStreamSize() const {
+ if (SectionMap.empty())
+ return 0;
+ return sizeof(SecMapHeader) + sizeof(SecMapEntry) * SectionMap.size();
+}
+
+uint32_t DbiStreamBuilder::calculateNamesOffset() const {
+ uint32_t Offset = 0;
+ Offset += sizeof(ulittle16_t); // NumModules
+ Offset += sizeof(ulittle16_t); // NumSourceFiles
+ Offset += ModiList.size() * sizeof(ulittle16_t); // ModIndices
+ Offset += ModiList.size() * sizeof(ulittle16_t); // ModFileCounts
+ uint32_t NumFileInfos = 0;
+ for (const auto &M : ModiList)
+ NumFileInfos += M->source_files().size();
+ Offset += NumFileInfos * sizeof(ulittle32_t); // FileNameOffsets
+ return Offset;
+}
+
+uint32_t DbiStreamBuilder::calculateFileInfoSubstreamSize() const {
+ uint32_t Size = calculateNamesOffset();
+ Size += calculateNamesBufferSize();
+ return alignTo(Size, sizeof(uint32_t));
+}
+
+uint32_t DbiStreamBuilder::calculateNamesBufferSize() const {
+ uint32_t Size = 0;
+ for (const auto &F : SourceFileNames) {
+ Size += F.getKeyLength() + 1; // Names[I];
+ }
+ return Size;
+}
+
+uint32_t DbiStreamBuilder::calculateDbgStreamsSize() const {
+ return DbgStreams.size() * sizeof(uint16_t);
+}
+
+Error DbiStreamBuilder::generateFileInfoSubstream() {
+ uint32_t Size = calculateFileInfoSubstreamSize();
+ auto Data = Allocator.Allocate<uint8_t>(Size);
+ uint32_t NamesOffset = calculateNamesOffset();
+
+ FileInfoBuffer = MutableBinaryByteStream(MutableArrayRef<uint8_t>(Data, Size),
+ llvm::support::little);
+
+ WritableBinaryStreamRef MetadataBuffer =
+ WritableBinaryStreamRef(FileInfoBuffer).keep_front(NamesOffset);
+ BinaryStreamWriter MetadataWriter(MetadataBuffer);
+
+ uint16_t ModiCount = std::min<uint32_t>(UINT16_MAX, ModiList.size());
+ uint16_t FileCount = std::min<uint32_t>(UINT16_MAX, SourceFileNames.size());
+ if (auto EC = MetadataWriter.writeInteger(ModiCount)) // NumModules
+ return EC;
+ if (auto EC = MetadataWriter.writeInteger(FileCount)) // NumSourceFiles
+ return EC;
+ for (uint16_t I = 0; I < ModiCount; ++I) {
+ if (auto EC = MetadataWriter.writeInteger(I)) // Mod Indices
+ return EC;
+ }
+ for (const auto &MI : ModiList) {
+ FileCount = static_cast<uint16_t>(MI->source_files().size());
+ if (auto EC = MetadataWriter.writeInteger(FileCount)) // Mod File Counts
+ return EC;
+ }
+
+ // Before writing the FileNameOffsets array, write the NamesBuffer array.
+ // A side effect of this is that this will actually compute the various
+ // file name offsets, so we can then go back and write the FileNameOffsets
+ // array to the other substream.
+ NamesBuffer = WritableBinaryStreamRef(FileInfoBuffer).drop_front(NamesOffset);
+ BinaryStreamWriter NameBufferWriter(NamesBuffer);
+ for (auto &Name : SourceFileNames) {
+ Name.second = NameBufferWriter.getOffset();
+ if (auto EC = NameBufferWriter.writeCString(Name.getKey()))
+ return EC;
+ }
+
+ for (const auto &MI : ModiList) {
+ for (StringRef Name : MI->source_files()) {
+ auto Result = SourceFileNames.find(Name);
+ if (Result == SourceFileNames.end())
+ return make_error<RawError>(raw_error_code::no_entry,
+ "The source file was not found.");
+ if (auto EC = MetadataWriter.writeInteger(Result->second))
+ return EC;
+ }
+ }
+
+ if (auto EC = NameBufferWriter.padToAlignment(sizeof(uint32_t)))
+ return EC;
+
+ if (NameBufferWriter.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::invalid_format,
+ "The names buffer contained unexpected data.");
+
+ if (MetadataWriter.bytesRemaining() > sizeof(uint32_t))
+ return make_error<RawError>(
+ raw_error_code::invalid_format,
+ "The metadata buffer contained unexpected data.");
+
+ return Error::success();
+}
+
+Error DbiStreamBuilder::finalize() {
+ if (Header)
+ return Error::success();
+
+ for (auto &MI : ModiList)
+ MI->finalize();
+
+ if (auto EC = generateFileInfoSubstream())
+ return EC;
+
+ DbiStreamHeader *H = Allocator.Allocate<DbiStreamHeader>();
+ ::memset(H, 0, sizeof(DbiStreamHeader));
+ H->VersionHeader = *VerHeader;
+ H->VersionSignature = -1;
+ H->Age = Age;
+ H->BuildNumber = BuildNumber;
+ H->Flags = Flags;
+ H->PdbDllRbld = PdbDllRbld;
+ H->PdbDllVersion = PdbDllVersion;
+ H->MachineType = static_cast<uint16_t>(MachineType);
+
+ H->ECSubstreamSize = ECNamesBuilder.calculateSerializedSize();
+ H->FileInfoSize = FileInfoBuffer.getLength();
+ H->ModiSubstreamSize = calculateModiSubstreamSize();
+ H->OptionalDbgHdrSize = DbgStreams.size() * sizeof(uint16_t);
+ H->SecContrSubstreamSize = calculateSectionContribsStreamSize();
+ H->SectionMapSize = calculateSectionMapStreamSize();
+ H->TypeServerSize = 0;
+ H->SymRecordStreamIndex = SymRecordStreamIndex;
+ H->PublicSymbolStreamIndex = PublicsStreamIndex;
+ H->MFCTypeServerIndex = 0; // Not sure what this is, but link.exe writes 0.
+ H->GlobalSymbolStreamIndex = GlobalsStreamIndex;
+
+ Header = H;
+ return Error::success();
+}
+
+Error DbiStreamBuilder::finalizeMsfLayout() {
+ if (NewFpoData.hasValue()) {
+ DbgStreams[(int)DbgHeaderType::NewFPO].emplace();
+ DbgStreams[(int)DbgHeaderType::NewFPO]->Size =
+ NewFpoData->calculateSerializedSize();
+ DbgStreams[(int)DbgHeaderType::NewFPO]->WriteFn =
+ [this](BinaryStreamWriter &Writer) {
+ return NewFpoData->commit(Writer);
+ };
+ }
+
+ if (!OldFpoData.empty()) {
+ DbgStreams[(int)DbgHeaderType::FPO].emplace();
+ DbgStreams[(int)DbgHeaderType::FPO]->Size =
+ sizeof(object::FpoData) * OldFpoData.size();
+ DbgStreams[(int)DbgHeaderType::FPO]->WriteFn =
+ [this](BinaryStreamWriter &Writer) {
+ return Writer.writeArray(makeArrayRef(OldFpoData));
+ };
+ }
+
+ for (auto &S : DbgStreams) {
+ if (!S.hasValue())
+ continue;
+ auto ExpectedIndex = Msf.addStream(S->Size);
+ if (!ExpectedIndex)
+ return ExpectedIndex.takeError();
+ S->StreamNumber = *ExpectedIndex;
+ }
+
+ for (auto &MI : ModiList) {
+ if (auto EC = MI->finalizeMsfLayout())
+ return EC;
+ }
+
+ uint32_t Length = calculateSerializedLength();
+ if (auto EC = Msf.setStreamSize(StreamDBI, Length))
+ return EC;
+ return Error::success();
+}
+
+static uint16_t toSecMapFlags(uint32_t Flags) {
+ uint16_t Ret = 0;
+ if (Flags & COFF::IMAGE_SCN_MEM_READ)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Read);
+ if (Flags & COFF::IMAGE_SCN_MEM_WRITE)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Write);
+ if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Execute);
+ if (Flags & COFF::IMAGE_SCN_MEM_EXECUTE)
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::Execute);
+ if (!(Flags & COFF::IMAGE_SCN_MEM_16BIT))
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::AddressIs32Bit);
+
+ // This seems always 1.
+ Ret |= static_cast<uint16_t>(OMFSegDescFlags::IsSelector);
+
+ return Ret;
+}
+
+// Populate the Section Map from COFF section headers.
+//
+// A Section Map seem to be a copy of a COFF section list in other format.
+// I don't know why a PDB file contains both a COFF section header and
+// a Section Map, but it seems it must be present in a PDB.
+void DbiStreamBuilder::createSectionMap(
+ ArrayRef<llvm::object::coff_section> SecHdrs) {
+ int Idx = 0;
+
+ auto Add = [&]() -> SecMapEntry & {
+ SectionMap.emplace_back();
+ auto &Entry = SectionMap.back();
+ memset(&Entry, 0, sizeof(Entry));
+
+ Entry.Frame = Idx + 1;
+
+ // We don't know the meaning of these fields yet.
+ Entry.SecName = UINT16_MAX;
+ Entry.ClassName = UINT16_MAX;
+
+ return Entry;
+ };
+
+ for (auto &Hdr : SecHdrs) {
+ auto &Entry = Add();
+ Entry.Flags = toSecMapFlags(Hdr.Characteristics);
+ Entry.SecByteLength = Hdr.VirtualSize;
+ ++Idx;
+ }
+
+ // The last entry is for absolute symbols.
+ auto &Entry = Add();
+ Entry.Flags = static_cast<uint16_t>(OMFSegDescFlags::AddressIs32Bit) |
+ static_cast<uint16_t>(OMFSegDescFlags::IsAbsoluteAddress);
+ Entry.SecByteLength = UINT32_MAX;
+}
+
+Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
+ WritableBinaryStreamRef MsfBuffer) {
+ if (auto EC = finalize())
+ return EC;
+
+ auto DbiS = WritableMappedBlockStream::createIndexedStream(
+ Layout, MsfBuffer, StreamDBI, Allocator);
+
+ BinaryStreamWriter Writer(*DbiS);
+ if (auto EC = Writer.writeObject(*Header))
+ return EC;
+
+ for (auto &M : ModiList) {
if (auto EC = M->commit(Writer))
- return EC;
- }
-
+ return EC;
+ }
+
// Commit symbol streams. This is a lot of data, so do it in parallel.
if (auto EC = parallelForEachError(
ModiList, [&](std::unique_ptr<DbiModuleDescriptorBuilder> &M) {
@@ -406,51 +406,51 @@ Error DbiStreamBuilder::commit(const msf::MSFLayout &Layout,
}))
return EC;
- if (!SectionContribs.empty()) {
- if (auto EC = Writer.writeEnum(DbiSecContribVer60))
- return EC;
- if (auto EC = Writer.writeArray(makeArrayRef(SectionContribs)))
- return EC;
- }
-
- if (!SectionMap.empty()) {
- ulittle16_t Size = static_cast<ulittle16_t>(SectionMap.size());
- SecMapHeader SMHeader = {Size, Size};
- if (auto EC = Writer.writeObject(SMHeader))
- return EC;
- if (auto EC = Writer.writeArray(makeArrayRef(SectionMap)))
- return EC;
- }
-
- if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
- return EC;
-
- if (auto EC = ECNamesBuilder.commit(Writer))
- return EC;
-
- for (auto &Stream : DbgStreams) {
- uint16_t StreamNumber = kInvalidStreamIndex;
- if (Stream.hasValue())
- StreamNumber = Stream->StreamNumber;
- if (auto EC = Writer.writeInteger(StreamNumber))
- return EC;
- }
-
- for (auto &Stream : DbgStreams) {
- if (!Stream.hasValue())
- continue;
- assert(Stream->StreamNumber != kInvalidStreamIndex);
-
- auto WritableStream = WritableMappedBlockStream::createIndexedStream(
- Layout, MsfBuffer, Stream->StreamNumber, Allocator);
- BinaryStreamWriter DbgStreamWriter(*WritableStream);
-
- if (auto EC = Stream->WriteFn(DbgStreamWriter))
- return EC;
- }
-
- if (Writer.bytesRemaining() > 0)
- return make_error<RawError>(raw_error_code::invalid_format,
- "Unexpected bytes found in DBI Stream");
- return Error::success();
-}
+ if (!SectionContribs.empty()) {
+ if (auto EC = Writer.writeEnum(DbiSecContribVer60))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(SectionContribs)))
+ return EC;
+ }
+
+ if (!SectionMap.empty()) {
+ ulittle16_t Size = static_cast<ulittle16_t>(SectionMap.size());
+ SecMapHeader SMHeader = {Size, Size};
+ if (auto EC = Writer.writeObject(SMHeader))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(SectionMap)))
+ return EC;
+ }
+
+ if (auto EC = Writer.writeStreamRef(FileInfoBuffer))
+ return EC;
+
+ if (auto EC = ECNamesBuilder.commit(Writer))
+ return EC;
+
+ for (auto &Stream : DbgStreams) {
+ uint16_t StreamNumber = kInvalidStreamIndex;
+ if (Stream.hasValue())
+ StreamNumber = Stream->StreamNumber;
+ if (auto EC = Writer.writeInteger(StreamNumber))
+ return EC;
+ }
+
+ for (auto &Stream : DbgStreams) {
+ if (!Stream.hasValue())
+ continue;
+ assert(Stream->StreamNumber != kInvalidStreamIndex);
+
+ auto WritableStream = WritableMappedBlockStream::createIndexedStream(
+ Layout, MsfBuffer, Stream->StreamNumber, Allocator);
+ BinaryStreamWriter DbgStreamWriter(*WritableStream);
+
+ if (auto EC = Stream->WriteFn(DbgStreamWriter))
+ return EC;
+ }
+
+ if (Writer.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::invalid_format,
+ "Unexpected bytes found in DBI Stream");
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/EnumTables.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/EnumTables.cpp
index 37192ba36a..bb7ffe82f0 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/EnumTables.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/EnumTables.cpp
@@ -1,37 +1,37 @@
-//===- EnumTables.cpp - Enum to string conversion tables --------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/EnumTables.h"
-#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-#define PDB_ENUM_CLASS_ENT(enum_class, enum) \
- { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
-
-#define PDB_ENUM_ENT(ns, enum) \
- { #enum, ns::enum }
-
-static const EnumEntry<uint16_t> OMFSegMapDescFlagNames[] = {
- PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Read),
- PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Write),
- PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Execute),
- PDB_ENUM_CLASS_ENT(OMFSegDescFlags, AddressIs32Bit),
- PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsSelector),
- PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsAbsoluteAddress),
- PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsGroup),
-};
-
-namespace llvm {
-namespace pdb {
-ArrayRef<EnumEntry<uint16_t>> getOMFSegMapDescFlagNames() {
- return makeArrayRef(OMFSegMapDescFlagNames);
-}
-}
-}
+//===- EnumTables.cpp - Enum to string conversion tables --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/EnumTables.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+#define PDB_ENUM_CLASS_ENT(enum_class, enum) \
+ { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
+
+#define PDB_ENUM_ENT(ns, enum) \
+ { #enum, ns::enum }
+
+static const EnumEntry<uint16_t> OMFSegMapDescFlagNames[] = {
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Read),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Write),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, Execute),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, AddressIs32Bit),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsSelector),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsAbsoluteAddress),
+ PDB_ENUM_CLASS_ENT(OMFSegDescFlags, IsGroup),
+};
+
+namespace llvm {
+namespace pdb {
+ArrayRef<EnumEntry<uint16_t>> getOMFSegMapDescFlagNames() {
+ return makeArrayRef(OMFSegMapDescFlagNames);
+}
+}
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 52df26b679..344304a2c1 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -1,494 +1,494 @@
-//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// The data structures defined in this file are based on the reference
-// implementation which is available at
-// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.cpp
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
-#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/Support/BinaryItemStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Parallel.h"
-#include "llvm/Support/xxhash.h"
-#include <algorithm>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-using namespace llvm::codeview;
-
-// Helper class for building the public and global PDB hash table buckets.
-struct llvm::pdb::GSIHashStreamBuilder {
- // Sum of the size of all public or global records.
- uint32_t RecordByteSize = 0;
-
- std::vector<PSHashRecord> HashRecords;
-
- // The hash bitmap has `ceil((IPHR_HASH + 1) / 32)` words in it. The
- // reference implementation builds a hash table with IPHR_HASH buckets in it.
- // The last bucket is used to link together free hash table cells in a linked
- // list, but it is always empty in the compressed, on-disk format. However,
- // the bitmap must have a bit for it.
- std::array<support::ulittle32_t, (IPHR_HASH + 32) / 32> HashBitmap;
-
- std::vector<support::ulittle32_t> HashBuckets;
-
- uint32_t calculateSerializedLength() const;
- Error commit(BinaryStreamWriter &Writer);
-
- void finalizePublicBuckets();
- void finalizeGlobalBuckets(uint32_t RecordZeroOffset);
-
- // Assign public and global symbol records into hash table buckets.
- // Modifies the list of records to store the bucket index, but does not
- // change the order.
- void finalizeBuckets(uint32_t RecordZeroOffset,
- MutableArrayRef<BulkPublic> Globals);
-};
-
-// DenseMapInfo implementation for deduplicating symbol records.
-struct llvm::pdb::SymbolDenseMapInfo {
- static inline CVSymbol getEmptyKey() {
- static CVSymbol Empty;
- return Empty;
- }
- static inline CVSymbol getTombstoneKey() {
- static CVSymbol Tombstone(
- DenseMapInfo<ArrayRef<uint8_t>>::getTombstoneKey());
- return Tombstone;
- }
- static unsigned getHashValue(const CVSymbol &Val) {
- return xxHash64(Val.RecordData);
- }
- static bool isEqual(const CVSymbol &LHS, const CVSymbol &RHS) {
- return LHS.RecordData == RHS.RecordData;
- }
-};
-
-namespace {
-LLVM_PACKED_START
-struct PublicSym32Layout {
- RecordPrefix Prefix;
- PublicSym32Header Pub;
- // char Name[];
-};
-LLVM_PACKED_END
-} // namespace
-
-// Calculate how much memory this public needs when serialized.
-static uint32_t sizeOfPublic(const BulkPublic &Pub) {
- uint32_t NameLen = Pub.NameLen;
- NameLen = std::min(NameLen,
- uint32_t(MaxRecordLength - sizeof(PublicSym32Layout) - 1));
- return alignTo(sizeof(PublicSym32Layout) + NameLen + 1, 4);
-}
-
-static CVSymbol serializePublic(uint8_t *Mem, const BulkPublic &Pub) {
- // Assume the caller has allocated sizeOfPublic bytes.
- uint32_t NameLen = std::min(
- Pub.NameLen, uint32_t(MaxRecordLength - sizeof(PublicSym32Layout) - 1));
- size_t Size = alignTo(sizeof(PublicSym32Layout) + NameLen + 1, 4);
- assert(Size == sizeOfPublic(Pub));
- auto *FixedMem = reinterpret_cast<PublicSym32Layout *>(Mem);
- FixedMem->Prefix.RecordKind = static_cast<uint16_t>(codeview::S_PUB32);
- FixedMem->Prefix.RecordLen = static_cast<uint16_t>(Size - 2);
- FixedMem->Pub.Flags = Pub.Flags;
- FixedMem->Pub.Offset = Pub.Offset;
- FixedMem->Pub.Segment = Pub.Segment;
- char *NameMem = reinterpret_cast<char *>(FixedMem + 1);
- memcpy(NameMem, Pub.Name, NameLen);
- // Zero the null terminator and remaining bytes.
- memset(&NameMem[NameLen], 0, Size - sizeof(PublicSym32Layout) - NameLen);
- return CVSymbol(makeArrayRef(reinterpret_cast<uint8_t *>(Mem), Size));
-}
-
-uint32_t GSIHashStreamBuilder::calculateSerializedLength() const {
- uint32_t Size = sizeof(GSIHashHeader);
- Size += HashRecords.size() * sizeof(PSHashRecord);
- Size += HashBitmap.size() * sizeof(uint32_t);
- Size += HashBuckets.size() * sizeof(uint32_t);
- return Size;
-}
-
-Error GSIHashStreamBuilder::commit(BinaryStreamWriter &Writer) {
- GSIHashHeader Header;
- Header.VerSignature = GSIHashHeader::HdrSignature;
- Header.VerHdr = GSIHashHeader::HdrVersion;
- Header.HrSize = HashRecords.size() * sizeof(PSHashRecord);
- Header.NumBuckets = HashBitmap.size() * 4 + HashBuckets.size() * 4;
-
- if (auto EC = Writer.writeObject(Header))
- return EC;
-
- if (auto EC = Writer.writeArray(makeArrayRef(HashRecords)))
- return EC;
- if (auto EC = Writer.writeArray(makeArrayRef(HashBitmap)))
- return EC;
- if (auto EC = Writer.writeArray(makeArrayRef(HashBuckets)))
- return EC;
- return Error::success();
-}
-
-static bool isAsciiString(StringRef S) {
- return llvm::all_of(S, [](char C) { return unsigned(C) < 0x80; });
-}
-
-// See `caseInsensitiveComparePchPchCchCch` in gsi.cpp
-static int gsiRecordCmp(StringRef S1, StringRef S2) {
- size_t LS = S1.size();
- size_t RS = S2.size();
- // Shorter strings always compare less than longer strings.
- if (LS != RS)
- return LS - RS;
-
- // If either string contains non ascii characters, memcmp them.
- if (LLVM_UNLIKELY(!isAsciiString(S1) || !isAsciiString(S2)))
- return memcmp(S1.data(), S2.data(), LS);
-
+//===- DbiStreamBuilder.cpp - PDB Dbi Stream Creation -----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The data structures defined in this file are based on the reference
+// implementation which is available at
+// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.cpp
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/Support/BinaryItemStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Parallel.h"
+#include "llvm/Support/xxhash.h"
+#include <algorithm>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+using namespace llvm::codeview;
+
+// Helper class for building the public and global PDB hash table buckets.
+struct llvm::pdb::GSIHashStreamBuilder {
+ // Sum of the size of all public or global records.
+ uint32_t RecordByteSize = 0;
+
+ std::vector<PSHashRecord> HashRecords;
+
+ // The hash bitmap has `ceil((IPHR_HASH + 1) / 32)` words in it. The
+ // reference implementation builds a hash table with IPHR_HASH buckets in it.
+ // The last bucket is used to link together free hash table cells in a linked
+ // list, but it is always empty in the compressed, on-disk format. However,
+ // the bitmap must have a bit for it.
+ std::array<support::ulittle32_t, (IPHR_HASH + 32) / 32> HashBitmap;
+
+ std::vector<support::ulittle32_t> HashBuckets;
+
+ uint32_t calculateSerializedLength() const;
+ Error commit(BinaryStreamWriter &Writer);
+
+ void finalizePublicBuckets();
+ void finalizeGlobalBuckets(uint32_t RecordZeroOffset);
+
+ // Assign public and global symbol records into hash table buckets.
+ // Modifies the list of records to store the bucket index, but does not
+ // change the order.
+ void finalizeBuckets(uint32_t RecordZeroOffset,
+ MutableArrayRef<BulkPublic> Globals);
+};
+
+// DenseMapInfo implementation for deduplicating symbol records.
+struct llvm::pdb::SymbolDenseMapInfo {
+ static inline CVSymbol getEmptyKey() {
+ static CVSymbol Empty;
+ return Empty;
+ }
+ static inline CVSymbol getTombstoneKey() {
+ static CVSymbol Tombstone(
+ DenseMapInfo<ArrayRef<uint8_t>>::getTombstoneKey());
+ return Tombstone;
+ }
+ static unsigned getHashValue(const CVSymbol &Val) {
+ return xxHash64(Val.RecordData);
+ }
+ static bool isEqual(const CVSymbol &LHS, const CVSymbol &RHS) {
+ return LHS.RecordData == RHS.RecordData;
+ }
+};
+
+namespace {
+LLVM_PACKED_START
+struct PublicSym32Layout {
+ RecordPrefix Prefix;
+ PublicSym32Header Pub;
+ // char Name[];
+};
+LLVM_PACKED_END
+} // namespace
+
+// Calculate how much memory this public needs when serialized.
+static uint32_t sizeOfPublic(const BulkPublic &Pub) {
+ uint32_t NameLen = Pub.NameLen;
+ NameLen = std::min(NameLen,
+ uint32_t(MaxRecordLength - sizeof(PublicSym32Layout) - 1));
+ return alignTo(sizeof(PublicSym32Layout) + NameLen + 1, 4);
+}
+
+static CVSymbol serializePublic(uint8_t *Mem, const BulkPublic &Pub) {
+ // Assume the caller has allocated sizeOfPublic bytes.
+ uint32_t NameLen = std::min(
+ Pub.NameLen, uint32_t(MaxRecordLength - sizeof(PublicSym32Layout) - 1));
+ size_t Size = alignTo(sizeof(PublicSym32Layout) + NameLen + 1, 4);
+ assert(Size == sizeOfPublic(Pub));
+ auto *FixedMem = reinterpret_cast<PublicSym32Layout *>(Mem);
+ FixedMem->Prefix.RecordKind = static_cast<uint16_t>(codeview::S_PUB32);
+ FixedMem->Prefix.RecordLen = static_cast<uint16_t>(Size - 2);
+ FixedMem->Pub.Flags = Pub.Flags;
+ FixedMem->Pub.Offset = Pub.Offset;
+ FixedMem->Pub.Segment = Pub.Segment;
+ char *NameMem = reinterpret_cast<char *>(FixedMem + 1);
+ memcpy(NameMem, Pub.Name, NameLen);
+ // Zero the null terminator and remaining bytes.
+ memset(&NameMem[NameLen], 0, Size - sizeof(PublicSym32Layout) - NameLen);
+ return CVSymbol(makeArrayRef(reinterpret_cast<uint8_t *>(Mem), Size));
+}
+
+uint32_t GSIHashStreamBuilder::calculateSerializedLength() const {
+ uint32_t Size = sizeof(GSIHashHeader);
+ Size += HashRecords.size() * sizeof(PSHashRecord);
+ Size += HashBitmap.size() * sizeof(uint32_t);
+ Size += HashBuckets.size() * sizeof(uint32_t);
+ return Size;
+}
+
+Error GSIHashStreamBuilder::commit(BinaryStreamWriter &Writer) {
+ GSIHashHeader Header;
+ Header.VerSignature = GSIHashHeader::HdrSignature;
+ Header.VerHdr = GSIHashHeader::HdrVersion;
+ Header.HrSize = HashRecords.size() * sizeof(PSHashRecord);
+ Header.NumBuckets = HashBitmap.size() * 4 + HashBuckets.size() * 4;
+
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+
+ if (auto EC = Writer.writeArray(makeArrayRef(HashRecords)))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(HashBitmap)))
+ return EC;
+ if (auto EC = Writer.writeArray(makeArrayRef(HashBuckets)))
+ return EC;
+ return Error::success();
+}
+
+static bool isAsciiString(StringRef S) {
+ return llvm::all_of(S, [](char C) { return unsigned(C) < 0x80; });
+}
+
+// See `caseInsensitiveComparePchPchCchCch` in gsi.cpp
+static int gsiRecordCmp(StringRef S1, StringRef S2) {
+ size_t LS = S1.size();
+ size_t RS = S2.size();
+ // Shorter strings always compare less than longer strings.
+ if (LS != RS)
+ return LS - RS;
+
+ // If either string contains non ascii characters, memcmp them.
+ if (LLVM_UNLIKELY(!isAsciiString(S1) || !isAsciiString(S2)))
+ return memcmp(S1.data(), S2.data(), LS);
+
// Both strings are ascii, perform a case-insensitive comparison.
- return S1.compare_lower(S2.data());
-}
-
-void GSIStreamBuilder::finalizePublicBuckets() {
- PSH->finalizeBuckets(0, Publics);
-}
-
-void GSIStreamBuilder::finalizeGlobalBuckets(uint32_t RecordZeroOffset) {
- // Build up a list of globals to be bucketed. Use the BulkPublic data
- // structure for this purpose, even though these are global records, not
- // public records. Most of the same fields are required:
- // - Name
- // - NameLen
- // - SymOffset
- // - BucketIdx
- // The dead fields are Offset, Segment, and Flags.
- std::vector<BulkPublic> Records;
- Records.resize(Globals.size());
- uint32_t SymOffset = RecordZeroOffset;
- for (size_t I = 0, E = Globals.size(); I < E; ++I) {
- StringRef Name = getSymbolName(Globals[I]);
- Records[I].Name = Name.data();
- Records[I].NameLen = Name.size();
- Records[I].SymOffset = SymOffset;
- SymOffset += Globals[I].length();
- }
-
- GSH->finalizeBuckets(RecordZeroOffset, Records);
-}
-
-void GSIHashStreamBuilder::finalizeBuckets(
- uint32_t RecordZeroOffset, MutableArrayRef<BulkPublic> Records) {
- // Hash every name in parallel.
- parallelForEachN(0, Records.size(), [&](size_t I) {
- Records[I].setBucketIdx(hashStringV1(Records[I].Name) % IPHR_HASH);
- });
-
- // Count up the size of each bucket. Then, use an exclusive prefix sum to
- // calculate the bucket start offsets. This is C++17 std::exclusive_scan, but
- // we can't use it yet.
- uint32_t BucketStarts[IPHR_HASH] = {0};
- for (const BulkPublic &P : Records)
- ++BucketStarts[P.BucketIdx];
- uint32_t Sum = 0;
- for (uint32_t &B : BucketStarts) {
- uint32_t Size = B;
- B = Sum;
- Sum += Size;
- }
-
- // Place globals into the hash table in bucket order. When placing a global,
- // update the bucket start. Every hash table slot should be filled. Always use
- // a refcount of one for now.
- HashRecords.resize(Records.size());
- uint32_t BucketCursors[IPHR_HASH];
- memcpy(BucketCursors, BucketStarts, sizeof(BucketCursors));
- for (int I = 0, E = Records.size(); I < E; ++I) {
- uint32_t HashIdx = BucketCursors[Records[I].BucketIdx]++;
- HashRecords[HashIdx].Off = I;
- HashRecords[HashIdx].CRef = 1;
- }
-
- // Within the buckets, sort each bucket by memcmp of the symbol's name. It's
- // important that we use the same sorting algorithm as is used by the
- // reference implementation to ensure that the search for a record within a
- // bucket can properly early-out when it detects the record won't be found.
- // The algorithm used here corresponds to the function
- // caseInsensitiveComparePchPchCchCch in the reference implementation.
- parallelForEachN(0, IPHR_HASH, [&](size_t I) {
- auto B = HashRecords.begin() + BucketStarts[I];
- auto E = HashRecords.begin() + BucketCursors[I];
- if (B == E)
- return;
- auto BucketCmp = [Records](const PSHashRecord &LHash,
- const PSHashRecord &RHash) {
- const BulkPublic &L = Records[uint32_t(LHash.Off)];
- const BulkPublic &R = Records[uint32_t(RHash.Off)];
- assert(L.BucketIdx == R.BucketIdx);
- int Cmp = gsiRecordCmp(L.getName(), R.getName());
- if (Cmp != 0)
- return Cmp < 0;
- // This comparison is necessary to make the sorting stable in the presence
- // of two static globals with the same name. The easiest way to observe
- // this is with S_LDATA32 records.
- return L.SymOffset < R.SymOffset;
- };
- llvm::sort(B, E, BucketCmp);
-
- // After we are done sorting, replace the global indices with the stream
- // offsets of each global. Add one when writing symbol offsets to disk.
- // See GSI1::fixSymRecs.
- for (PSHashRecord &HRec : make_range(B, E))
- HRec.Off = Records[uint32_t(HRec.Off)].SymOffset + 1;
- });
-
- // For each non-empty bucket, push the bucket start offset into HashBuckets
- // and set a bit in the hash bitmap.
- for (uint32_t I = 0; I < HashBitmap.size(); ++I) {
- uint32_t Word = 0;
- for (uint32_t J = 0; J < 32; ++J) {
- // Skip empty buckets.
- uint32_t BucketIdx = I * 32 + J;
- if (BucketIdx >= IPHR_HASH ||
- BucketStarts[BucketIdx] == BucketCursors[BucketIdx])
- continue;
- Word |= (1U << J);
-
- // Calculate what the offset of the first hash record in the chain would
- // be if it were inflated to contain 32-bit pointers. On a 32-bit system,
- // each record would be 12 bytes. See HROffsetCalc in gsi.h.
- const int SizeOfHROffsetCalc = 12;
- ulittle32_t ChainStartOff =
- ulittle32_t(BucketStarts[BucketIdx] * SizeOfHROffsetCalc);
- HashBuckets.push_back(ChainStartOff);
- }
- HashBitmap[I] = Word;
- }
-}
-
-GSIStreamBuilder::GSIStreamBuilder(msf::MSFBuilder &Msf)
- : Msf(Msf), PSH(std::make_unique<GSIHashStreamBuilder>()),
- GSH(std::make_unique<GSIHashStreamBuilder>()) {}
-
-GSIStreamBuilder::~GSIStreamBuilder() {}
-
-uint32_t GSIStreamBuilder::calculatePublicsHashStreamSize() const {
- uint32_t Size = 0;
- Size += sizeof(PublicsStreamHeader);
- Size += PSH->calculateSerializedLength();
- Size += Publics.size() * sizeof(uint32_t); // AddrMap
- // FIXME: Add thunk map and section offsets for incremental linking.
-
- return Size;
-}
-
-uint32_t GSIStreamBuilder::calculateGlobalsHashStreamSize() const {
- return GSH->calculateSerializedLength();
-}
-
-Error GSIStreamBuilder::finalizeMsfLayout() {
- // First we write public symbol records, then we write global symbol records.
- finalizePublicBuckets();
- finalizeGlobalBuckets(PSH->RecordByteSize);
-
- Expected<uint32_t> Idx = Msf.addStream(calculateGlobalsHashStreamSize());
- if (!Idx)
- return Idx.takeError();
- GlobalsStreamIndex = *Idx;
-
- Idx = Msf.addStream(calculatePublicsHashStreamSize());
- if (!Idx)
- return Idx.takeError();
- PublicsStreamIndex = *Idx;
-
- uint32_t RecordBytes = PSH->RecordByteSize + GSH->RecordByteSize;
-
- Idx = Msf.addStream(RecordBytes);
- if (!Idx)
- return Idx.takeError();
- RecordStreamIndex = *Idx;
- return Error::success();
-}
-
-void GSIStreamBuilder::addPublicSymbols(std::vector<BulkPublic> &&PublicsIn) {
- assert(Publics.empty() && PSH->RecordByteSize == 0 &&
- "publics can only be added once");
- Publics = std::move(PublicsIn);
-
- // Sort the symbols by name. PDBs contain lots of symbols, so use parallelism.
- parallelSort(Publics, [](const BulkPublic &L, const BulkPublic &R) {
- return L.getName() < R.getName();
- });
-
- // Assign offsets and calculate the length of the public symbol records.
- uint32_t SymOffset = 0;
- for (BulkPublic &Pub : Publics) {
- Pub.SymOffset = SymOffset;
- SymOffset += sizeOfPublic(Pub);
- }
-
- // Remember the length of the public stream records.
- PSH->RecordByteSize = SymOffset;
-}
-
-void GSIStreamBuilder::addGlobalSymbol(const ProcRefSym &Sym) {
- serializeAndAddGlobal(Sym);
-}
-
-void GSIStreamBuilder::addGlobalSymbol(const DataSym &Sym) {
- serializeAndAddGlobal(Sym);
-}
-
-void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) {
- serializeAndAddGlobal(Sym);
-}
-
-template <typename T>
-void GSIStreamBuilder::serializeAndAddGlobal(const T &Symbol) {
- T Copy(Symbol);
- addGlobalSymbol(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(),
- CodeViewContainer::Pdb));
-}
-
-void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Symbol) {
- // Ignore duplicate typedefs and constants.
- if (Symbol.kind() == S_UDT || Symbol.kind() == S_CONSTANT) {
- auto Iter = GlobalsSeen.insert(Symbol);
- if (!Iter.second)
- return;
- }
- GSH->RecordByteSize += Symbol.length();
- Globals.push_back(Symbol);
-}
-
-// Serialize each public and write it.
-static Error writePublics(BinaryStreamWriter &Writer,
- ArrayRef<BulkPublic> Publics) {
- std::vector<uint8_t> Storage;
- for (const BulkPublic &Pub : Publics) {
- Storage.resize(sizeOfPublic(Pub));
- serializePublic(Storage.data(), Pub);
- if (Error E = Writer.writeBytes(Storage))
- return E;
- }
- return Error::success();
-}
-
-static Error writeRecords(BinaryStreamWriter &Writer,
- ArrayRef<CVSymbol> Records) {
- BinaryItemStream<CVSymbol> ItemStream(support::endianness::little);
- ItemStream.setItems(Records);
- BinaryStreamRef RecordsRef(ItemStream);
- return Writer.writeStreamRef(RecordsRef);
-}
-
-Error GSIStreamBuilder::commitSymbolRecordStream(
- WritableBinaryStreamRef Stream) {
- BinaryStreamWriter Writer(Stream);
-
- // Write public symbol records first, followed by global symbol records. This
- // must match the order that we assume in finalizeMsfLayout when computing
- // PSHZero and GSHZero.
- if (auto EC = writePublics(Writer, Publics))
- return EC;
- if (auto EC = writeRecords(Writer, Globals))
- return EC;
-
- return Error::success();
-}
-
-static std::vector<support::ulittle32_t>
-computeAddrMap(ArrayRef<BulkPublic> Publics) {
- // Build a parallel vector of indices into the Publics vector, and sort it by
- // address.
- std::vector<ulittle32_t> PubAddrMap;
- PubAddrMap.reserve(Publics.size());
- for (int I = 0, E = Publics.size(); I < E; ++I)
- PubAddrMap.push_back(ulittle32_t(I));
-
- auto AddrCmp = [Publics](const ulittle32_t &LIdx, const ulittle32_t &RIdx) {
- const BulkPublic &L = Publics[LIdx];
- const BulkPublic &R = Publics[RIdx];
- if (L.Segment != R.Segment)
- return L.Segment < R.Segment;
- if (L.Offset != R.Offset)
- return L.Offset < R.Offset;
- // parallelSort is unstable, so we have to do name comparison to ensure
- // that two names for the same location come out in a deterministic order.
- return L.getName() < R.getName();
- };
- parallelSort(PubAddrMap, AddrCmp);
-
- // Rewrite the public symbol indices into symbol offsets.
- for (ulittle32_t &Entry : PubAddrMap)
- Entry = Publics[Entry].SymOffset;
- return PubAddrMap;
-}
-
-Error GSIStreamBuilder::commitPublicsHashStream(
- WritableBinaryStreamRef Stream) {
- BinaryStreamWriter Writer(Stream);
- PublicsStreamHeader Header;
-
- // FIXME: Fill these in. They are for incremental linking.
- Header.SymHash = PSH->calculateSerializedLength();
- Header.AddrMap = Publics.size() * 4;
- Header.NumThunks = 0;
- Header.SizeOfThunk = 0;
- Header.ISectThunkTable = 0;
- memset(Header.Padding, 0, sizeof(Header.Padding));
- Header.OffThunkTable = 0;
- Header.NumSections = 0;
- if (auto EC = Writer.writeObject(Header))
- return EC;
-
- if (auto EC = PSH->commit(Writer))
- return EC;
-
- std::vector<support::ulittle32_t> PubAddrMap = computeAddrMap(Publics);
- assert(PubAddrMap.size() == Publics.size());
- if (auto EC = Writer.writeArray(makeArrayRef(PubAddrMap)))
- return EC;
-
- return Error::success();
-}
-
-Error GSIStreamBuilder::commitGlobalsHashStream(
- WritableBinaryStreamRef Stream) {
- BinaryStreamWriter Writer(Stream);
- return GSH->commit(Writer);
-}
-
-Error GSIStreamBuilder::commit(const msf::MSFLayout &Layout,
- WritableBinaryStreamRef Buffer) {
- auto GS = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, getGlobalsStreamIndex(), Msf.getAllocator());
- auto PS = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, getPublicsStreamIndex(), Msf.getAllocator());
- auto PRS = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, getRecordStreamIndex(), Msf.getAllocator());
-
- if (auto EC = commitSymbolRecordStream(*PRS))
- return EC;
- if (auto EC = commitGlobalsHashStream(*GS))
- return EC;
- if (auto EC = commitPublicsHashStream(*PS))
- return EC;
- return Error::success();
-}
+ return S1.compare_lower(S2.data());
+}
+
+void GSIStreamBuilder::finalizePublicBuckets() {
+ PSH->finalizeBuckets(0, Publics);
+}
+
+void GSIStreamBuilder::finalizeGlobalBuckets(uint32_t RecordZeroOffset) {
+ // Build up a list of globals to be bucketed. Use the BulkPublic data
+ // structure for this purpose, even though these are global records, not
+ // public records. Most of the same fields are required:
+ // - Name
+ // - NameLen
+ // - SymOffset
+ // - BucketIdx
+ // The dead fields are Offset, Segment, and Flags.
+ std::vector<BulkPublic> Records;
+ Records.resize(Globals.size());
+ uint32_t SymOffset = RecordZeroOffset;
+ for (size_t I = 0, E = Globals.size(); I < E; ++I) {
+ StringRef Name = getSymbolName(Globals[I]);
+ Records[I].Name = Name.data();
+ Records[I].NameLen = Name.size();
+ Records[I].SymOffset = SymOffset;
+ SymOffset += Globals[I].length();
+ }
+
+ GSH->finalizeBuckets(RecordZeroOffset, Records);
+}
+
+void GSIHashStreamBuilder::finalizeBuckets(
+ uint32_t RecordZeroOffset, MutableArrayRef<BulkPublic> Records) {
+ // Hash every name in parallel.
+ parallelForEachN(0, Records.size(), [&](size_t I) {
+ Records[I].setBucketIdx(hashStringV1(Records[I].Name) % IPHR_HASH);
+ });
+
+ // Count up the size of each bucket. Then, use an exclusive prefix sum to
+ // calculate the bucket start offsets. This is C++17 std::exclusive_scan, but
+ // we can't use it yet.
+ uint32_t BucketStarts[IPHR_HASH] = {0};
+ for (const BulkPublic &P : Records)
+ ++BucketStarts[P.BucketIdx];
+ uint32_t Sum = 0;
+ for (uint32_t &B : BucketStarts) {
+ uint32_t Size = B;
+ B = Sum;
+ Sum += Size;
+ }
+
+ // Place globals into the hash table in bucket order. When placing a global,
+ // update the bucket start. Every hash table slot should be filled. Always use
+ // a refcount of one for now.
+ HashRecords.resize(Records.size());
+ uint32_t BucketCursors[IPHR_HASH];
+ memcpy(BucketCursors, BucketStarts, sizeof(BucketCursors));
+ for (int I = 0, E = Records.size(); I < E; ++I) {
+ uint32_t HashIdx = BucketCursors[Records[I].BucketIdx]++;
+ HashRecords[HashIdx].Off = I;
+ HashRecords[HashIdx].CRef = 1;
+ }
+
+ // Within the buckets, sort each bucket by memcmp of the symbol's name. It's
+ // important that we use the same sorting algorithm as is used by the
+ // reference implementation to ensure that the search for a record within a
+ // bucket can properly early-out when it detects the record won't be found.
+ // The algorithm used here corresponds to the function
+ // caseInsensitiveComparePchPchCchCch in the reference implementation.
+ parallelForEachN(0, IPHR_HASH, [&](size_t I) {
+ auto B = HashRecords.begin() + BucketStarts[I];
+ auto E = HashRecords.begin() + BucketCursors[I];
+ if (B == E)
+ return;
+ auto BucketCmp = [Records](const PSHashRecord &LHash,
+ const PSHashRecord &RHash) {
+ const BulkPublic &L = Records[uint32_t(LHash.Off)];
+ const BulkPublic &R = Records[uint32_t(RHash.Off)];
+ assert(L.BucketIdx == R.BucketIdx);
+ int Cmp = gsiRecordCmp(L.getName(), R.getName());
+ if (Cmp != 0)
+ return Cmp < 0;
+ // This comparison is necessary to make the sorting stable in the presence
+ // of two static globals with the same name. The easiest way to observe
+ // this is with S_LDATA32 records.
+ return L.SymOffset < R.SymOffset;
+ };
+ llvm::sort(B, E, BucketCmp);
+
+ // After we are done sorting, replace the global indices with the stream
+ // offsets of each global. Add one when writing symbol offsets to disk.
+ // See GSI1::fixSymRecs.
+ for (PSHashRecord &HRec : make_range(B, E))
+ HRec.Off = Records[uint32_t(HRec.Off)].SymOffset + 1;
+ });
+
+ // For each non-empty bucket, push the bucket start offset into HashBuckets
+ // and set a bit in the hash bitmap.
+ for (uint32_t I = 0; I < HashBitmap.size(); ++I) {
+ uint32_t Word = 0;
+ for (uint32_t J = 0; J < 32; ++J) {
+ // Skip empty buckets.
+ uint32_t BucketIdx = I * 32 + J;
+ if (BucketIdx >= IPHR_HASH ||
+ BucketStarts[BucketIdx] == BucketCursors[BucketIdx])
+ continue;
+ Word |= (1U << J);
+
+ // Calculate what the offset of the first hash record in the chain would
+ // be if it were inflated to contain 32-bit pointers. On a 32-bit system,
+ // each record would be 12 bytes. See HROffsetCalc in gsi.h.
+ const int SizeOfHROffsetCalc = 12;
+ ulittle32_t ChainStartOff =
+ ulittle32_t(BucketStarts[BucketIdx] * SizeOfHROffsetCalc);
+ HashBuckets.push_back(ChainStartOff);
+ }
+ HashBitmap[I] = Word;
+ }
+}
+
+GSIStreamBuilder::GSIStreamBuilder(msf::MSFBuilder &Msf)
+ : Msf(Msf), PSH(std::make_unique<GSIHashStreamBuilder>()),
+ GSH(std::make_unique<GSIHashStreamBuilder>()) {}
+
+GSIStreamBuilder::~GSIStreamBuilder() {}
+
+uint32_t GSIStreamBuilder::calculatePublicsHashStreamSize() const {
+ uint32_t Size = 0;
+ Size += sizeof(PublicsStreamHeader);
+ Size += PSH->calculateSerializedLength();
+ Size += Publics.size() * sizeof(uint32_t); // AddrMap
+ // FIXME: Add thunk map and section offsets for incremental linking.
+
+ return Size;
+}
+
+uint32_t GSIStreamBuilder::calculateGlobalsHashStreamSize() const {
+ return GSH->calculateSerializedLength();
+}
+
+Error GSIStreamBuilder::finalizeMsfLayout() {
+ // First we write public symbol records, then we write global symbol records.
+ finalizePublicBuckets();
+ finalizeGlobalBuckets(PSH->RecordByteSize);
+
+ Expected<uint32_t> Idx = Msf.addStream(calculateGlobalsHashStreamSize());
+ if (!Idx)
+ return Idx.takeError();
+ GlobalsStreamIndex = *Idx;
+
+ Idx = Msf.addStream(calculatePublicsHashStreamSize());
+ if (!Idx)
+ return Idx.takeError();
+ PublicsStreamIndex = *Idx;
+
+ uint32_t RecordBytes = PSH->RecordByteSize + GSH->RecordByteSize;
+
+ Idx = Msf.addStream(RecordBytes);
+ if (!Idx)
+ return Idx.takeError();
+ RecordStreamIndex = *Idx;
+ return Error::success();
+}
+
+void GSIStreamBuilder::addPublicSymbols(std::vector<BulkPublic> &&PublicsIn) {
+ assert(Publics.empty() && PSH->RecordByteSize == 0 &&
+ "publics can only be added once");
+ Publics = std::move(PublicsIn);
+
+ // Sort the symbols by name. PDBs contain lots of symbols, so use parallelism.
+ parallelSort(Publics, [](const BulkPublic &L, const BulkPublic &R) {
+ return L.getName() < R.getName();
+ });
+
+ // Assign offsets and calculate the length of the public symbol records.
+ uint32_t SymOffset = 0;
+ for (BulkPublic &Pub : Publics) {
+ Pub.SymOffset = SymOffset;
+ SymOffset += sizeOfPublic(Pub);
+ }
+
+ // Remember the length of the public stream records.
+ PSH->RecordByteSize = SymOffset;
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const ProcRefSym &Sym) {
+ serializeAndAddGlobal(Sym);
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const DataSym &Sym) {
+ serializeAndAddGlobal(Sym);
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const ConstantSym &Sym) {
+ serializeAndAddGlobal(Sym);
+}
+
+template <typename T>
+void GSIStreamBuilder::serializeAndAddGlobal(const T &Symbol) {
+ T Copy(Symbol);
+ addGlobalSymbol(SymbolSerializer::writeOneSymbol(Copy, Msf.getAllocator(),
+ CodeViewContainer::Pdb));
+}
+
+void GSIStreamBuilder::addGlobalSymbol(const codeview::CVSymbol &Symbol) {
+ // Ignore duplicate typedefs and constants.
+ if (Symbol.kind() == S_UDT || Symbol.kind() == S_CONSTANT) {
+ auto Iter = GlobalsSeen.insert(Symbol);
+ if (!Iter.second)
+ return;
+ }
+ GSH->RecordByteSize += Symbol.length();
+ Globals.push_back(Symbol);
+}
+
+// Serialize each public and write it.
+static Error writePublics(BinaryStreamWriter &Writer,
+ ArrayRef<BulkPublic> Publics) {
+ std::vector<uint8_t> Storage;
+ for (const BulkPublic &Pub : Publics) {
+ Storage.resize(sizeOfPublic(Pub));
+ serializePublic(Storage.data(), Pub);
+ if (Error E = Writer.writeBytes(Storage))
+ return E;
+ }
+ return Error::success();
+}
+
+static Error writeRecords(BinaryStreamWriter &Writer,
+ ArrayRef<CVSymbol> Records) {
+ BinaryItemStream<CVSymbol> ItemStream(support::endianness::little);
+ ItemStream.setItems(Records);
+ BinaryStreamRef RecordsRef(ItemStream);
+ return Writer.writeStreamRef(RecordsRef);
+}
+
+Error GSIStreamBuilder::commitSymbolRecordStream(
+ WritableBinaryStreamRef Stream) {
+ BinaryStreamWriter Writer(Stream);
+
+ // Write public symbol records first, followed by global symbol records. This
+ // must match the order that we assume in finalizeMsfLayout when computing
+ // PSHZero and GSHZero.
+ if (auto EC = writePublics(Writer, Publics))
+ return EC;
+ if (auto EC = writeRecords(Writer, Globals))
+ return EC;
+
+ return Error::success();
+}
+
+static std::vector<support::ulittle32_t>
+computeAddrMap(ArrayRef<BulkPublic> Publics) {
+ // Build a parallel vector of indices into the Publics vector, and sort it by
+ // address.
+ std::vector<ulittle32_t> PubAddrMap;
+ PubAddrMap.reserve(Publics.size());
+ for (int I = 0, E = Publics.size(); I < E; ++I)
+ PubAddrMap.push_back(ulittle32_t(I));
+
+ auto AddrCmp = [Publics](const ulittle32_t &LIdx, const ulittle32_t &RIdx) {
+ const BulkPublic &L = Publics[LIdx];
+ const BulkPublic &R = Publics[RIdx];
+ if (L.Segment != R.Segment)
+ return L.Segment < R.Segment;
+ if (L.Offset != R.Offset)
+ return L.Offset < R.Offset;
+ // parallelSort is unstable, so we have to do name comparison to ensure
+ // that two names for the same location come out in a deterministic order.
+ return L.getName() < R.getName();
+ };
+ parallelSort(PubAddrMap, AddrCmp);
+
+ // Rewrite the public symbol indices into symbol offsets.
+ for (ulittle32_t &Entry : PubAddrMap)
+ Entry = Publics[Entry].SymOffset;
+ return PubAddrMap;
+}
+
+Error GSIStreamBuilder::commitPublicsHashStream(
+ WritableBinaryStreamRef Stream) {
+ BinaryStreamWriter Writer(Stream);
+ PublicsStreamHeader Header;
+
+ // FIXME: Fill these in. They are for incremental linking.
+ Header.SymHash = PSH->calculateSerializedLength();
+ Header.AddrMap = Publics.size() * 4;
+ Header.NumThunks = 0;
+ Header.SizeOfThunk = 0;
+ Header.ISectThunkTable = 0;
+ memset(Header.Padding, 0, sizeof(Header.Padding));
+ Header.OffThunkTable = 0;
+ Header.NumSections = 0;
+ if (auto EC = Writer.writeObject(Header))
+ return EC;
+
+ if (auto EC = PSH->commit(Writer))
+ return EC;
+
+ std::vector<support::ulittle32_t> PubAddrMap = computeAddrMap(Publics);
+ assert(PubAddrMap.size() == Publics.size());
+ if (auto EC = Writer.writeArray(makeArrayRef(PubAddrMap)))
+ return EC;
+
+ return Error::success();
+}
+
+Error GSIStreamBuilder::commitGlobalsHashStream(
+ WritableBinaryStreamRef Stream) {
+ BinaryStreamWriter Writer(Stream);
+ return GSH->commit(Writer);
+}
+
+Error GSIStreamBuilder::commit(const msf::MSFLayout &Layout,
+ WritableBinaryStreamRef Buffer) {
+ auto GS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, getGlobalsStreamIndex(), Msf.getAllocator());
+ auto PS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, getPublicsStreamIndex(), Msf.getAllocator());
+ auto PRS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, getRecordStreamIndex(), Msf.getAllocator());
+
+ if (auto EC = commitSymbolRecordStream(*PRS))
+ return EC;
+ if (auto EC = commitGlobalsHashStream(*GS))
+ return EC;
+ if (auto EC = commitPublicsHashStream(*PS))
+ return EC;
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GlobalsStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
index f27d60f468..68344075d0 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/GlobalsStream.cpp
@@ -1,181 +1,181 @@
-//===- GlobalsStream.cpp - PDB Index of Symbols by Name ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// The on-disk structores used in this file are based on the reference
-// implementation which is available at
-// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
-//
-// When you are reading the reference source code, you'd find the
-// information below useful.
-//
-// - ppdb1->m_fMinimalDbgInfo seems to be always true.
-// - SMALLBUCKETS macro is defined.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
-
-#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-GlobalsStream::GlobalsStream(std::unique_ptr<MappedBlockStream> Stream)
- : Stream(std::move(Stream)) {}
-
-GlobalsStream::~GlobalsStream() = default;
-
-Error GlobalsStream::reload() {
- BinaryStreamReader Reader(*Stream);
- if (auto E = GlobalsTable.read(Reader))
- return E;
- return Error::success();
-}
-
-std::vector<std::pair<uint32_t, codeview::CVSymbol>>
-GlobalsStream::findRecordsByName(StringRef Name,
- const SymbolStream &Symbols) const {
- std::vector<std::pair<uint32_t, codeview::CVSymbol>> Result;
-
- // Hash the name to figure out which bucket this goes into.
- size_t ExpandedBucketIndex = hashStringV1(Name) % IPHR_HASH;
- int32_t CompressedBucketIndex = GlobalsTable.BucketMap[ExpandedBucketIndex];
- if (CompressedBucketIndex == -1)
- return Result;
-
- uint32_t LastBucketIndex = GlobalsTable.HashBuckets.size() - 1;
- uint32_t StartRecordIndex =
- GlobalsTable.HashBuckets[CompressedBucketIndex] / 12;
- uint32_t EndRecordIndex = 0;
- if (LLVM_LIKELY(uint32_t(CompressedBucketIndex) < LastBucketIndex)) {
- EndRecordIndex = GlobalsTable.HashBuckets[CompressedBucketIndex + 1];
- } else {
- // If this is the last bucket, it consists of all hash records until the end
- // of the HashRecords array.
- EndRecordIndex = GlobalsTable.HashRecords.size() * 12;
- }
-
- EndRecordIndex /= 12;
-
- assert(EndRecordIndex <= GlobalsTable.HashRecords.size());
- while (StartRecordIndex < EndRecordIndex) {
- PSHashRecord PSH = GlobalsTable.HashRecords[StartRecordIndex];
- uint32_t Off = PSH.Off - 1;
- codeview::CVSymbol Record = Symbols.readRecord(Off);
- if (codeview::getSymbolName(Record) == Name)
- Result.push_back(std::make_pair(Off, std::move(Record)));
- ++StartRecordIndex;
- }
- return Result;
-}
-
-static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
- if (HashHdr->VerHdr != GSIHashHeader::HdrVersion)
- return make_error<RawError>(
- raw_error_code::feature_unsupported,
- "Encountered unsupported globals stream version.");
-
- return Error::success();
-}
-
-static Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
- BinaryStreamReader &Reader) {
- if (Reader.readObject(HashHdr))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Stream does not contain a GSIHashHeader.");
-
- if (HashHdr->VerSignature != GSIHashHeader::HdrSignature)
- return make_error<RawError>(
- raw_error_code::feature_unsupported,
- "GSIHashHeader signature (0xffffffff) not found.");
-
- return Error::success();
-}
-
-static Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
- const GSIHashHeader *HashHdr,
- BinaryStreamReader &Reader) {
- if (auto EC = checkHashHdrVersion(HashHdr))
- return EC;
-
- // HashHdr->HrSize specifies the number of bytes of PSHashRecords we have.
- // Verify that we can read them all.
- if (HashHdr->HrSize % sizeof(PSHashRecord))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid HR array size.");
- uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord);
- if (auto EC = Reader.readArray(HashRecords, NumHashRecords))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Error reading hash records."));
-
- return Error::success();
-}
-
-static Error
-readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
- FixedStreamArray<support::ulittle32_t> &HashBitmap,
- const GSIHashHeader *HashHdr,
- MutableArrayRef<int32_t> BucketMap,
- BinaryStreamReader &Reader) {
- if (auto EC = checkHashHdrVersion(HashHdr))
- return EC;
-
- // Before the actual hash buckets, there is a bitmap of length determined by
- // IPHR_HASH.
- size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
- uint32_t NumBitmapEntries = BitmapSizeInBits / 32;
- if (auto EC = Reader.readArray(HashBitmap, NumBitmapEntries))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read a bitmap."));
- uint32_t NumBuckets1 = 0;
- uint32_t CompressedBucketIdx = 0;
- for (uint32_t I = 0; I <= IPHR_HASH; ++I) {
- uint8_t WordIdx = I / 32;
- uint8_t BitIdx = I % 32;
- bool IsSet = HashBitmap[WordIdx] & (1U << BitIdx);
- if (IsSet) {
- ++NumBuckets1;
- BucketMap[I] = CompressedBucketIdx++;
- } else {
- BucketMap[I] = -1;
- }
- }
-
- uint32_t NumBuckets = 0;
- for (uint32_t B : HashBitmap)
- NumBuckets += countPopulation(B);
-
- // Hash buckets follow.
- if (auto EC = Reader.readArray(HashBuckets, NumBuckets))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Hash buckets corrupted."));
-
- return Error::success();
-}
-
-Error GSIHashTable::read(BinaryStreamReader &Reader) {
- if (auto EC = readGSIHashHeader(HashHdr, Reader))
- return EC;
- if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader))
- return EC;
- if (HashHdr->HrSize > 0)
- if (auto EC = readGSIHashBuckets(HashBuckets, HashBitmap, HashHdr,
- BucketMap, Reader))
- return EC;
- return Error::success();
-}
+//===- GlobalsStream.cpp - PDB Index of Symbols by Name ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// The on-disk structores used in this file are based on the reference
+// implementation which is available at
+// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
+//
+// When you are reading the reference source code, you'd find the
+// information below useful.
+//
+// - ppdb1->m_fMinimalDbgInfo seems to be always true.
+// - SMALLBUCKETS macro is defined.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+GlobalsStream::GlobalsStream(std::unique_ptr<MappedBlockStream> Stream)
+ : Stream(std::move(Stream)) {}
+
+GlobalsStream::~GlobalsStream() = default;
+
+Error GlobalsStream::reload() {
+ BinaryStreamReader Reader(*Stream);
+ if (auto E = GlobalsTable.read(Reader))
+ return E;
+ return Error::success();
+}
+
+std::vector<std::pair<uint32_t, codeview::CVSymbol>>
+GlobalsStream::findRecordsByName(StringRef Name,
+ const SymbolStream &Symbols) const {
+ std::vector<std::pair<uint32_t, codeview::CVSymbol>> Result;
+
+ // Hash the name to figure out which bucket this goes into.
+ size_t ExpandedBucketIndex = hashStringV1(Name) % IPHR_HASH;
+ int32_t CompressedBucketIndex = GlobalsTable.BucketMap[ExpandedBucketIndex];
+ if (CompressedBucketIndex == -1)
+ return Result;
+
+ uint32_t LastBucketIndex = GlobalsTable.HashBuckets.size() - 1;
+ uint32_t StartRecordIndex =
+ GlobalsTable.HashBuckets[CompressedBucketIndex] / 12;
+ uint32_t EndRecordIndex = 0;
+ if (LLVM_LIKELY(uint32_t(CompressedBucketIndex) < LastBucketIndex)) {
+ EndRecordIndex = GlobalsTable.HashBuckets[CompressedBucketIndex + 1];
+ } else {
+ // If this is the last bucket, it consists of all hash records until the end
+ // of the HashRecords array.
+ EndRecordIndex = GlobalsTable.HashRecords.size() * 12;
+ }
+
+ EndRecordIndex /= 12;
+
+ assert(EndRecordIndex <= GlobalsTable.HashRecords.size());
+ while (StartRecordIndex < EndRecordIndex) {
+ PSHashRecord PSH = GlobalsTable.HashRecords[StartRecordIndex];
+ uint32_t Off = PSH.Off - 1;
+ codeview::CVSymbol Record = Symbols.readRecord(Off);
+ if (codeview::getSymbolName(Record) == Name)
+ Result.push_back(std::make_pair(Off, std::move(Record)));
+ ++StartRecordIndex;
+ }
+ return Result;
+}
+
+static Error checkHashHdrVersion(const GSIHashHeader *HashHdr) {
+ if (HashHdr->VerHdr != GSIHashHeader::HdrVersion)
+ return make_error<RawError>(
+ raw_error_code::feature_unsupported,
+ "Encountered unsupported globals stream version.");
+
+ return Error::success();
+}
+
+static Error readGSIHashHeader(const GSIHashHeader *&HashHdr,
+ BinaryStreamReader &Reader) {
+ if (Reader.readObject(HashHdr))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Stream does not contain a GSIHashHeader.");
+
+ if (HashHdr->VerSignature != GSIHashHeader::HdrSignature)
+ return make_error<RawError>(
+ raw_error_code::feature_unsupported,
+ "GSIHashHeader signature (0xffffffff) not found.");
+
+ return Error::success();
+}
+
+static Error readGSIHashRecords(FixedStreamArray<PSHashRecord> &HashRecords,
+ const GSIHashHeader *HashHdr,
+ BinaryStreamReader &Reader) {
+ if (auto EC = checkHashHdrVersion(HashHdr))
+ return EC;
+
+ // HashHdr->HrSize specifies the number of bytes of PSHashRecords we have.
+ // Verify that we can read them all.
+ if (HashHdr->HrSize % sizeof(PSHashRecord))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid HR array size.");
+ uint32_t NumHashRecords = HashHdr->HrSize / sizeof(PSHashRecord);
+ if (auto EC = Reader.readArray(HashRecords, NumHashRecords))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Error reading hash records."));
+
+ return Error::success();
+}
+
+static Error
+readGSIHashBuckets(FixedStreamArray<support::ulittle32_t> &HashBuckets,
+ FixedStreamArray<support::ulittle32_t> &HashBitmap,
+ const GSIHashHeader *HashHdr,
+ MutableArrayRef<int32_t> BucketMap,
+ BinaryStreamReader &Reader) {
+ if (auto EC = checkHashHdrVersion(HashHdr))
+ return EC;
+
+ // Before the actual hash buckets, there is a bitmap of length determined by
+ // IPHR_HASH.
+ size_t BitmapSizeInBits = alignTo(IPHR_HASH + 1, 32);
+ uint32_t NumBitmapEntries = BitmapSizeInBits / 32;
+ if (auto EC = Reader.readArray(HashBitmap, NumBitmapEntries))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read a bitmap."));
+ uint32_t NumBuckets1 = 0;
+ uint32_t CompressedBucketIdx = 0;
+ for (uint32_t I = 0; I <= IPHR_HASH; ++I) {
+ uint8_t WordIdx = I / 32;
+ uint8_t BitIdx = I % 32;
+ bool IsSet = HashBitmap[WordIdx] & (1U << BitIdx);
+ if (IsSet) {
+ ++NumBuckets1;
+ BucketMap[I] = CompressedBucketIdx++;
+ } else {
+ BucketMap[I] = -1;
+ }
+ }
+
+ uint32_t NumBuckets = 0;
+ for (uint32_t B : HashBitmap)
+ NumBuckets += countPopulation(B);
+
+ // Hash buckets follow.
+ if (auto EC = Reader.readArray(HashBuckets, NumBuckets))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Hash buckets corrupted."));
+
+ return Error::success();
+}
+
+Error GSIHashTable::read(BinaryStreamReader &Reader) {
+ if (auto EC = readGSIHashHeader(HashHdr, Reader))
+ return EC;
+ if (auto EC = readGSIHashRecords(HashRecords, HashHdr, Reader))
+ return EC;
+ if (HashHdr->HrSize > 0)
+ if (auto EC = readGSIHashBuckets(HashBuckets, HashBitmap, HashHdr,
+ BucketMap, Reader))
+ return EC;
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/Hash.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/Hash.cpp
index 7fb6b4bd5d..7f0c15527d 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/Hash.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/Hash.cpp
@@ -1,84 +1,84 @@
-//===- Hash.cpp - PDB Hash Functions --------------------------------------===//
-//
-// 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/Hash.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/CRC.h"
-#include "llvm/Support/Endian.h"
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::support;
-
-// Corresponds to `Hasher::lhashPbCb` in PDB/include/misc.h.
-// Used for name hash table and TPI/IPI hashes.
-uint32_t pdb::hashStringV1(StringRef Str) {
- uint32_t Result = 0;
- uint32_t Size = Str.size();
-
- ArrayRef<ulittle32_t> Longs(reinterpret_cast<const ulittle32_t *>(Str.data()),
- Size / 4);
-
- for (auto Value : Longs)
- Result ^= Value;
-
- const uint8_t *Remainder = reinterpret_cast<const uint8_t *>(Longs.end());
- uint32_t RemainderSize = Size % 4;
-
- // Maximum of 3 bytes left. Hash a 2 byte word if possible, then hash the
- // possibly remaining 1 byte.
- if (RemainderSize >= 2) {
- uint16_t Value = *reinterpret_cast<const ulittle16_t *>(Remainder);
- Result ^= static_cast<uint32_t>(Value);
- Remainder += 2;
- RemainderSize -= 2;
- }
-
- // hash possible odd byte
- if (RemainderSize == 1) {
- Result ^= *(Remainder++);
- }
-
- const uint32_t toLowerMask = 0x20202020;
- Result |= toLowerMask;
- Result ^= (Result >> 11);
-
- return Result ^ (Result >> 16);
-}
-
-// Corresponds to `HasherV2::HashULONG` in PDB/include/misc.h.
-// Used for name hash table.
-uint32_t pdb::hashStringV2(StringRef Str) {
- uint32_t Hash = 0xb170a1bf;
-
- ArrayRef<char> Buffer(Str.begin(), Str.end());
-
- ArrayRef<ulittle32_t> Items(
- reinterpret_cast<const ulittle32_t *>(Buffer.data()),
- Buffer.size() / sizeof(ulittle32_t));
- for (ulittle32_t Item : Items) {
- Hash += Item;
- Hash += (Hash << 10);
- Hash ^= (Hash >> 6);
- }
- Buffer = Buffer.slice(Items.size() * sizeof(ulittle32_t));
- for (uint8_t Item : Buffer) {
- Hash += Item;
- Hash += (Hash << 10);
- Hash ^= (Hash >> 6);
- }
-
- return Hash * 1664525U + 1013904223U;
-}
-
-// Corresponds to `SigForPbCb` in langapi/shared/crc32.h.
-uint32_t pdb::hashBufferV8(ArrayRef<uint8_t> Buf) {
- JamCRC JC(/*Init=*/0U);
- JC.update(Buf);
- return JC.getCRC();
-}
+//===- Hash.cpp - PDB Hash Functions --------------------------------------===//
+//
+// 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/Hash.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/CRC.h"
+#include "llvm/Support/Endian.h"
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::support;
+
+// Corresponds to `Hasher::lhashPbCb` in PDB/include/misc.h.
+// Used for name hash table and TPI/IPI hashes.
+uint32_t pdb::hashStringV1(StringRef Str) {
+ uint32_t Result = 0;
+ uint32_t Size = Str.size();
+
+ ArrayRef<ulittle32_t> Longs(reinterpret_cast<const ulittle32_t *>(Str.data()),
+ Size / 4);
+
+ for (auto Value : Longs)
+ Result ^= Value;
+
+ const uint8_t *Remainder = reinterpret_cast<const uint8_t *>(Longs.end());
+ uint32_t RemainderSize = Size % 4;
+
+ // Maximum of 3 bytes left. Hash a 2 byte word if possible, then hash the
+ // possibly remaining 1 byte.
+ if (RemainderSize >= 2) {
+ uint16_t Value = *reinterpret_cast<const ulittle16_t *>(Remainder);
+ Result ^= static_cast<uint32_t>(Value);
+ Remainder += 2;
+ RemainderSize -= 2;
+ }
+
+ // hash possible odd byte
+ if (RemainderSize == 1) {
+ Result ^= *(Remainder++);
+ }
+
+ const uint32_t toLowerMask = 0x20202020;
+ Result |= toLowerMask;
+ Result ^= (Result >> 11);
+
+ return Result ^ (Result >> 16);
+}
+
+// Corresponds to `HasherV2::HashULONG` in PDB/include/misc.h.
+// Used for name hash table.
+uint32_t pdb::hashStringV2(StringRef Str) {
+ uint32_t Hash = 0xb170a1bf;
+
+ ArrayRef<char> Buffer(Str.begin(), Str.end());
+
+ ArrayRef<ulittle32_t> Items(
+ reinterpret_cast<const ulittle32_t *>(Buffer.data()),
+ Buffer.size() / sizeof(ulittle32_t));
+ for (ulittle32_t Item : Items) {
+ Hash += Item;
+ Hash += (Hash << 10);
+ Hash ^= (Hash >> 6);
+ }
+ Buffer = Buffer.slice(Items.size() * sizeof(ulittle32_t));
+ for (uint8_t Item : Buffer) {
+ Hash += Item;
+ Hash += (Hash << 10);
+ Hash ^= (Hash >> 6);
+ }
+
+ return Hash * 1664525U + 1013904223U;
+}
+
+// Corresponds to `SigForPbCb` in langapi/shared/crc32.h.
+uint32_t pdb::hashBufferV8(ArrayRef<uint8_t> Buf) {
+ JamCRC JC(/*Init=*/0U);
+ JC.update(Buf);
+ return JC.getCRC();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/HashTable.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/HashTable.cpp
index dfdcdf1f4e..aab0c8b958 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/HashTable.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/HashTable.cpp
@@ -1,71 +1,71 @@
-//===- HashTable.cpp - PDB Hash Table -------------------------------------===//
-//
-// 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/HashTable.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MathExtras.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-Error llvm::pdb::readSparseBitVector(BinaryStreamReader &Stream,
- SparseBitVector<> &V) {
- uint32_t NumWords;
- if (auto EC = Stream.readInteger(NumWords))
- return joinErrors(
- std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected hash table number of words"));
-
- for (uint32_t I = 0; I != NumWords; ++I) {
- uint32_t Word;
- if (auto EC = Stream.readInteger(Word))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected hash table word"));
- for (unsigned Idx = 0; Idx < 32; ++Idx)
- if (Word & (1U << Idx))
- V.set((I * 32) + Idx);
- }
- return Error::success();
-}
-
-Error llvm::pdb::writeSparseBitVector(BinaryStreamWriter &Writer,
- SparseBitVector<> &Vec) {
- constexpr int BitsPerWord = 8 * sizeof(uint32_t);
-
- int ReqBits = Vec.find_last() + 1;
- uint32_t ReqWords = alignTo(ReqBits, BitsPerWord) / BitsPerWord;
- if (auto EC = Writer.writeInteger(ReqWords))
- return joinErrors(
- std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not write linear map number of words"));
-
- uint32_t Idx = 0;
- for (uint32_t I = 0; I != ReqWords; ++I) {
- uint32_t Word = 0;
- for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) {
- if (Vec.test(Idx))
- Word |= (1 << WordIdx);
- }
- if (auto EC = Writer.writeInteger(Word))
- return joinErrors(std::move(EC), make_error<RawError>(
- raw_error_code::corrupt_file,
- "Could not write linear map word"));
- }
- return Error::success();
-}
+//===- HashTable.cpp - PDB Hash Table -------------------------------------===//
+//
+// 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/HashTable.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MathExtras.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+Error llvm::pdb::readSparseBitVector(BinaryStreamReader &Stream,
+ SparseBitVector<> &V) {
+ uint32_t NumWords;
+ if (auto EC = Stream.readInteger(NumWords))
+ return joinErrors(
+ std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Expected hash table number of words"));
+
+ for (uint32_t I = 0; I != NumWords; ++I) {
+ uint32_t Word;
+ if (auto EC = Stream.readInteger(Word))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Expected hash table word"));
+ for (unsigned Idx = 0; Idx < 32; ++Idx)
+ if (Word & (1U << Idx))
+ V.set((I * 32) + Idx);
+ }
+ return Error::success();
+}
+
+Error llvm::pdb::writeSparseBitVector(BinaryStreamWriter &Writer,
+ SparseBitVector<> &Vec) {
+ constexpr int BitsPerWord = 8 * sizeof(uint32_t);
+
+ int ReqBits = Vec.find_last() + 1;
+ uint32_t ReqWords = alignTo(ReqBits, BitsPerWord) / BitsPerWord;
+ if (auto EC = Writer.writeInteger(ReqWords))
+ return joinErrors(
+ std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not write linear map number of words"));
+
+ uint32_t Idx = 0;
+ for (uint32_t I = 0; I != ReqWords; ++I) {
+ uint32_t Word = 0;
+ for (uint32_t WordIdx = 0; WordIdx < 32; ++WordIdx, ++Idx) {
+ if (Vec.test(Idx))
+ Word |= (1 << WordIdx);
+ }
+ if (auto EC = Writer.writeInteger(Word))
+ return joinErrors(std::move(EC), make_error<RawError>(
+ raw_error_code::corrupt_file,
+ "Could not write linear map word"));
+ }
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStream.cpp
index f41bb32d69..ad504af60a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStream.cpp
@@ -1,131 +1,131 @@
-//===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/Support/BinaryStreamReader.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
- : Stream(std::move(Stream)), Header(nullptr) {}
-
-Error InfoStream::reload() {
- BinaryStreamReader Reader(*Stream);
-
- if (auto EC = Reader.readObject(Header))
- return joinErrors(
- std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "PDB Stream does not contain a header."));
-
- switch (Header->Version) {
- case PdbImplVC70:
- case PdbImplVC80:
- case PdbImplVC110:
- case PdbImplVC140:
- break;
- default:
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Unsupported PDB stream version.");
- }
-
- uint32_t Offset = Reader.getOffset();
- if (auto EC = NamedStreams.load(Reader))
- return EC;
- uint32_t NewOffset = Reader.getOffset();
- NamedStreamMapByteSize = NewOffset - Offset;
-
- Reader.setOffset(Offset);
- if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize))
- return EC;
-
- bool Stop = false;
- while (!Stop && !Reader.empty()) {
- PdbRaw_FeatureSig Sig;
- if (auto EC = Reader.readEnum(Sig))
- return EC;
- // Since this value comes from a file, it's possible we have some strange
- // value which doesn't correspond to any value. We don't want to warn on
- // -Wcovered-switch-default in this case, so switch on the integral value
- // instead of the enumeration value.
- switch (uint32_t(Sig)) {
- case uint32_t(PdbRaw_FeatureSig::VC110):
- // No other flags for VC110 PDB.
- Stop = true;
- LLVM_FALLTHROUGH;
- case uint32_t(PdbRaw_FeatureSig::VC140):
- Features |= PdbFeatureContainsIdStream;
- break;
- case uint32_t(PdbRaw_FeatureSig::NoTypeMerge):
- Features |= PdbFeatureNoTypeMerging;
- break;
- case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo):
- Features |= PdbFeatureMinimalDebugInfo;
- break;
- default:
- continue;
- }
- FeatureSignatures.push_back(Sig);
- }
- return Error::success();
-}
-
-uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
-
-Expected<uint32_t> InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
- uint32_t Result;
- if (!NamedStreams.get(Name, Result))
- return make_error<RawError>(raw_error_code::no_stream);
- return Result;
-}
-
-StringMap<uint32_t> InfoStream::named_streams() const {
- return NamedStreams.entries();
-}
-
-bool InfoStream::containsIdStream() const {
- return !!(Features & PdbFeatureContainsIdStream);
-}
-
-PdbRaw_ImplVer InfoStream::getVersion() const {
- return static_cast<PdbRaw_ImplVer>(uint32_t(Header->Version));
-}
-
-uint32_t InfoStream::getSignature() const {
- return uint32_t(Header->Signature);
-}
-
-uint32_t InfoStream::getAge() const { return uint32_t(Header->Age); }
-
-GUID InfoStream::getGuid() const { return Header->Guid; }
-
-uint32_t InfoStream::getNamedStreamMapByteSize() const {
- return NamedStreamMapByteSize;
-}
-
-PdbRaw_Features InfoStream::getFeatures() const { return Features; }
-
-ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
- return FeatureSignatures;
-}
-
-const NamedStreamMap &InfoStream::getNamedStreams() const {
- return NamedStreams;
-}
-
-BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
- return SubNamedStreams;
-}
+//===- InfoStream.cpp - PDB Info Stream (Stream 1) Access -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+InfoStream::InfoStream(std::unique_ptr<BinaryStream> Stream)
+ : Stream(std::move(Stream)), Header(nullptr) {}
+
+Error InfoStream::reload() {
+ BinaryStreamReader Reader(*Stream);
+
+ if (auto EC = Reader.readObject(Header))
+ return joinErrors(
+ std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "PDB Stream does not contain a header."));
+
+ switch (Header->Version) {
+ case PdbImplVC70:
+ case PdbImplVC80:
+ case PdbImplVC110:
+ case PdbImplVC140:
+ break;
+ default:
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Unsupported PDB stream version.");
+ }
+
+ uint32_t Offset = Reader.getOffset();
+ if (auto EC = NamedStreams.load(Reader))
+ return EC;
+ uint32_t NewOffset = Reader.getOffset();
+ NamedStreamMapByteSize = NewOffset - Offset;
+
+ Reader.setOffset(Offset);
+ if (auto EC = Reader.readSubstream(SubNamedStreams, NamedStreamMapByteSize))
+ return EC;
+
+ bool Stop = false;
+ while (!Stop && !Reader.empty()) {
+ PdbRaw_FeatureSig Sig;
+ if (auto EC = Reader.readEnum(Sig))
+ return EC;
+ // Since this value comes from a file, it's possible we have some strange
+ // value which doesn't correspond to any value. We don't want to warn on
+ // -Wcovered-switch-default in this case, so switch on the integral value
+ // instead of the enumeration value.
+ switch (uint32_t(Sig)) {
+ case uint32_t(PdbRaw_FeatureSig::VC110):
+ // No other flags for VC110 PDB.
+ Stop = true;
+ LLVM_FALLTHROUGH;
+ case uint32_t(PdbRaw_FeatureSig::VC140):
+ Features |= PdbFeatureContainsIdStream;
+ break;
+ case uint32_t(PdbRaw_FeatureSig::NoTypeMerge):
+ Features |= PdbFeatureNoTypeMerging;
+ break;
+ case uint32_t(PdbRaw_FeatureSig::MinimalDebugInfo):
+ Features |= PdbFeatureMinimalDebugInfo;
+ break;
+ default:
+ continue;
+ }
+ FeatureSignatures.push_back(Sig);
+ }
+ return Error::success();
+}
+
+uint32_t InfoStream::getStreamSize() const { return Stream->getLength(); }
+
+Expected<uint32_t> InfoStream::getNamedStreamIndex(llvm::StringRef Name) const {
+ uint32_t Result;
+ if (!NamedStreams.get(Name, Result))
+ return make_error<RawError>(raw_error_code::no_stream);
+ return Result;
+}
+
+StringMap<uint32_t> InfoStream::named_streams() const {
+ return NamedStreams.entries();
+}
+
+bool InfoStream::containsIdStream() const {
+ return !!(Features & PdbFeatureContainsIdStream);
+}
+
+PdbRaw_ImplVer InfoStream::getVersion() const {
+ return static_cast<PdbRaw_ImplVer>(uint32_t(Header->Version));
+}
+
+uint32_t InfoStream::getSignature() const {
+ return uint32_t(Header->Signature);
+}
+
+uint32_t InfoStream::getAge() const { return uint32_t(Header->Age); }
+
+GUID InfoStream::getGuid() const { return Header->Guid; }
+
+uint32_t InfoStream::getNamedStreamMapByteSize() const {
+ return NamedStreamMapByteSize;
+}
+
+PdbRaw_Features InfoStream::getFeatures() const { return Features; }
+
+ArrayRef<PdbRaw_FeatureSig> InfoStream::getFeatureSignatures() const {
+ return FeatureSignatures;
+}
+
+const NamedStreamMap &InfoStream::getNamedStreams() const {
+ return NamedStreams;
+}
+
+BinarySubstreamRef InfoStream::getNamedStreamsBuffer() const {
+ return SubNamedStreams;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
index 42daa7cae7..02844c4fa5 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InfoStreamBuilder.cpp
@@ -1,82 +1,82 @@
-//===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
-
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
- NamedStreamMap &NamedStreams)
- : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Age(0),
- NamedStreams(NamedStreams) {
- ::memset(&Guid, 0, sizeof(Guid));
-}
-
-void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
-
-void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
- Features.push_back(Sig);
-}
-
-void InfoStreamBuilder::setHashPDBContentsToGUID(bool B) {
- HashPDBContentsToGUID = B;
-}
-
-void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
-
-void InfoStreamBuilder::setSignature(uint32_t S) { Signature = S; }
-
-void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
-
-
-Error InfoStreamBuilder::finalizeMsfLayout() {
- uint32_t Length = sizeof(InfoStreamHeader) +
- NamedStreams.calculateSerializedLength() +
- (Features.size() + 1) * sizeof(uint32_t);
- if (auto EC = Msf.setStreamSize(StreamPDB, Length))
- return EC;
- return Error::success();
-}
-
-Error InfoStreamBuilder::commit(const msf::MSFLayout &Layout,
- WritableBinaryStreamRef Buffer) const {
- auto InfoS = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, StreamPDB, Msf.getAllocator());
- BinaryStreamWriter Writer(*InfoS);
-
- InfoStreamHeader H;
- // Leave the build id fields 0 so they can be set as the last step before
- // committing the file to disk.
- ::memset(&H, 0, sizeof(H));
- H.Version = Ver;
- if (auto EC = Writer.writeObject(H))
- return EC;
-
- if (auto EC = NamedStreams.commit(Writer))
- return EC;
- if (auto EC = Writer.writeInteger(0))
- return EC;
- for (auto E : Features) {
- if (auto EC = Writer.writeEnum(E))
- return EC;
- }
- assert(Writer.bytesRemaining() == 0);
- return Error::success();
-}
+//===- InfoStreamBuilder.cpp - PDB Info Stream Creation ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
+
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+InfoStreamBuilder::InfoStreamBuilder(msf::MSFBuilder &Msf,
+ NamedStreamMap &NamedStreams)
+ : Msf(Msf), Ver(PdbRaw_ImplVer::PdbImplVC70), Age(0),
+ NamedStreams(NamedStreams) {
+ ::memset(&Guid, 0, sizeof(Guid));
+}
+
+void InfoStreamBuilder::setVersion(PdbRaw_ImplVer V) { Ver = V; }
+
+void InfoStreamBuilder::addFeature(PdbRaw_FeatureSig Sig) {
+ Features.push_back(Sig);
+}
+
+void InfoStreamBuilder::setHashPDBContentsToGUID(bool B) {
+ HashPDBContentsToGUID = B;
+}
+
+void InfoStreamBuilder::setAge(uint32_t A) { Age = A; }
+
+void InfoStreamBuilder::setSignature(uint32_t S) { Signature = S; }
+
+void InfoStreamBuilder::setGuid(GUID G) { Guid = G; }
+
+
+Error InfoStreamBuilder::finalizeMsfLayout() {
+ uint32_t Length = sizeof(InfoStreamHeader) +
+ NamedStreams.calculateSerializedLength() +
+ (Features.size() + 1) * sizeof(uint32_t);
+ if (auto EC = Msf.setStreamSize(StreamPDB, Length))
+ return EC;
+ return Error::success();
+}
+
+Error InfoStreamBuilder::commit(const msf::MSFLayout &Layout,
+ WritableBinaryStreamRef Buffer) const {
+ auto InfoS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, StreamPDB, Msf.getAllocator());
+ BinaryStreamWriter Writer(*InfoS);
+
+ InfoStreamHeader H;
+ // Leave the build id fields 0 so they can be set as the last step before
+ // committing the file to disk.
+ ::memset(&H, 0, sizeof(H));
+ H.Version = Ver;
+ if (auto EC = Writer.writeObject(H))
+ return EC;
+
+ if (auto EC = NamedStreams.commit(Writer))
+ return EC;
+ if (auto EC = Writer.writeInteger(0))
+ return EC;
+ for (auto E : Features) {
+ if (auto EC = Writer.writeEnum(E))
+ return EC;
+ }
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
index 3f4101db7b..cc5da61b89 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/InjectedSourceStream.cpp
@@ -1,65 +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();
-}
+//===- 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/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
index 1445f0bd9e..ba1362f689 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/ModuleDebugStream.cpp
@@ -1,144 +1,144 @@
-//===- ModuleDebugStream.cpp - PDB Module Info 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/ModuleDebugStream.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#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"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-ModuleDebugStreamRef::ModuleDebugStreamRef(
- const DbiModuleDescriptor &Module,
- std::unique_ptr<MappedBlockStream> Stream)
- : Mod(Module), Stream(std::move(Stream)) {}
-
-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();
-
- if (C11Size > 0 && C13Size > 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Module has both C11 and C13 line info");
-
- BinaryStreamRef S;
-
- if (auto EC = Reader.readInteger(Signature))
- return EC;
- Reader.setOffset(0);
- if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize))
- return EC;
- if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
- return EC;
- if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size))
- return EC;
-
- BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
- if (auto EC = SymbolReader.readArray(
- SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t)))
- return EC;
-
- BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
- if (auto EC = SubsectionsReader.readArray(Subsections,
- SubsectionsReader.bytesRemaining()))
- return EC;
-
- uint32_t GlobalRefsSize;
- if (auto EC = Reader.readInteger(GlobalRefsSize))
- return EC;
- if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize))
- return EC;
- return Error::success();
-}
-
-const codeview::CVSymbolArray
-ModuleDebugStreamRef::getSymbolArrayForScope(uint32_t ScopeBegin) const {
- return limitSymbolArrayToScope(SymbolArray, ScopeBegin);
-}
-
-BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const {
- return SymbolsSubstream;
-}
-
-BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const {
- return C11LinesSubstream;
-}
-
-BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const {
- return C13LinesSubstream;
-}
-
-BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const {
- return GlobalRefsSubstream;
-}
-
-iterator_range<codeview::CVSymbolArray::Iterator>
-ModuleDebugStreamRef::symbols(bool *HadError) const {
- return make_range(SymbolArray.begin(HadError), SymbolArray.end());
-}
-
-CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const {
- auto Iter = SymbolArray.at(Offset);
- assert(Iter != SymbolArray.end());
- return *Iter;
-}
-
-iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
-ModuleDebugStreamRef::subsections() const {
- return make_range(Subsections.begin(), Subsections.end());
-}
-
-bool ModuleDebugStreamRef::hasDebugSubsections() const {
- return !C13LinesSubstream.empty();
-}
-
-Error ModuleDebugStreamRef::commit() { return Error::success(); }
-
-Expected<codeview::DebugChecksumsSubsectionRef>
-ModuleDebugStreamRef::findChecksumsSubsection() const {
- codeview::DebugChecksumsSubsectionRef Result;
- for (const auto &SS : subsections()) {
- if (SS.kind() != DebugSubsectionKind::FileChecksums)
- continue;
-
- if (auto EC = Result.initialize(SS.getRecordData()))
- return std::move(EC);
- return Result;
- }
- return Result;
-}
+//===- ModuleDebugStream.cpp - PDB Module Info 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/ModuleDebugStream.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/DebugChecksumsSubsection.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#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"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+ModuleDebugStreamRef::ModuleDebugStreamRef(
+ const DbiModuleDescriptor &Module,
+ std::unique_ptr<MappedBlockStream> Stream)
+ : Mod(Module), Stream(std::move(Stream)) {}
+
+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();
+
+ if (C11Size > 0 && C13Size > 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Module has both C11 and C13 line info");
+
+ BinaryStreamRef S;
+
+ if (auto EC = Reader.readInteger(Signature))
+ return EC;
+ Reader.setOffset(0);
+ if (auto EC = Reader.readSubstream(SymbolsSubstream, SymbolSize))
+ return EC;
+ if (auto EC = Reader.readSubstream(C11LinesSubstream, C11Size))
+ return EC;
+ if (auto EC = Reader.readSubstream(C13LinesSubstream, C13Size))
+ return EC;
+
+ BinaryStreamReader SymbolReader(SymbolsSubstream.StreamData);
+ if (auto EC = SymbolReader.readArray(
+ SymbolArray, SymbolReader.bytesRemaining(), sizeof(uint32_t)))
+ return EC;
+
+ BinaryStreamReader SubsectionsReader(C13LinesSubstream.StreamData);
+ if (auto EC = SubsectionsReader.readArray(Subsections,
+ SubsectionsReader.bytesRemaining()))
+ return EC;
+
+ uint32_t GlobalRefsSize;
+ if (auto EC = Reader.readInteger(GlobalRefsSize))
+ return EC;
+ if (auto EC = Reader.readSubstream(GlobalRefsSubstream, GlobalRefsSize))
+ return EC;
+ return Error::success();
+}
+
+const codeview::CVSymbolArray
+ModuleDebugStreamRef::getSymbolArrayForScope(uint32_t ScopeBegin) const {
+ return limitSymbolArrayToScope(SymbolArray, ScopeBegin);
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getSymbolsSubstream() const {
+ return SymbolsSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getC11LinesSubstream() const {
+ return C11LinesSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getC13LinesSubstream() const {
+ return C13LinesSubstream;
+}
+
+BinarySubstreamRef ModuleDebugStreamRef::getGlobalRefsSubstream() const {
+ return GlobalRefsSubstream;
+}
+
+iterator_range<codeview::CVSymbolArray::Iterator>
+ModuleDebugStreamRef::symbols(bool *HadError) const {
+ return make_range(SymbolArray.begin(HadError), SymbolArray.end());
+}
+
+CVSymbol ModuleDebugStreamRef::readSymbolAtOffset(uint32_t Offset) const {
+ auto Iter = SymbolArray.at(Offset);
+ assert(Iter != SymbolArray.end());
+ return *Iter;
+}
+
+iterator_range<ModuleDebugStreamRef::DebugSubsectionIterator>
+ModuleDebugStreamRef::subsections() const {
+ return make_range(Subsections.begin(), Subsections.end());
+}
+
+bool ModuleDebugStreamRef::hasDebugSubsections() const {
+ return !C13LinesSubstream.empty();
+}
+
+Error ModuleDebugStreamRef::commit() { return Error::success(); }
+
+Expected<codeview::DebugChecksumsSubsectionRef>
+ModuleDebugStreamRef::findChecksumsSubsection() const {
+ codeview::DebugChecksumsSubsectionRef Result;
+ for (const auto &SS : subsections()) {
+ if (SS.kind() != DebugSubsectionKind::FileChecksums)
+ continue;
+
+ if (auto EC = Result.initialize(SS.getRecordData()))
+ return std::move(EC);
+ return Result;
+ }
+ return Result;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
index 1d873b87b3..f4c46f3c3b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
@@ -1,126 +1,126 @@
-//===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
-//
-// 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/NamedStreamMap.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/DebugInfo/PDB/Native/HashTable.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamRef.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <tuple>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-NamedStreamMapTraits::NamedStreamMapTraits(NamedStreamMap &NS) : NS(&NS) {}
-
-uint16_t NamedStreamMapTraits::hashLookupKey(StringRef S) const {
- // In the reference implementation, this uses
- // HASH Hasher<ULONG*, USHORT*>::hashPbCb(PB pb, size_t cb, ULONG ulMod).
- // 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));
-}
-
-StringRef NamedStreamMapTraits::storageKeyToLookupKey(uint32_t Offset) const {
- return NS->getString(Offset);
-}
-
-uint32_t NamedStreamMapTraits::lookupKeyToStorageKey(StringRef S) {
- return NS->appendStringData(S);
-}
-
-NamedStreamMap::NamedStreamMap() : HashTraits(*this), OffsetIndexMap(1) {}
-
-Error NamedStreamMap::load(BinaryStreamReader &Stream) {
- uint32_t StringBufferSize;
- if (auto EC = Stream.readInteger(StringBufferSize))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Expected string buffer size"));
-
- StringRef Buffer;
- if (auto EC = Stream.readFixedString(Buffer, StringBufferSize))
- return EC;
- NamesBuffer.assign(Buffer.begin(), Buffer.end());
-
- return OffsetIndexMap.load(Stream);
-}
-
-Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
- // The first field is the number of bytes of string data.
- if (auto EC = Writer.writeInteger<uint32_t>(NamesBuffer.size()))
- return EC;
-
- // Then the actual string data.
- StringRef Data(NamesBuffer.data(), NamesBuffer.size());
- if (auto EC = Writer.writeFixedString(Data))
- return EC;
-
- // And finally the Offset Index map.
- if (auto EC = OffsetIndexMap.commit(Writer))
- return EC;
-
- return Error::success();
-}
-
-uint32_t NamedStreamMap::calculateSerializedLength() const {
- return sizeof(uint32_t) // String data size
- + NamesBuffer.size() // String data
- + OffsetIndexMap.calculateSerializedLength(); // Offset Index Map
-}
-
-uint32_t NamedStreamMap::size() const { return OffsetIndexMap.size(); }
-
-StringRef NamedStreamMap::getString(uint32_t Offset) const {
- assert(NamesBuffer.size() > Offset);
- return StringRef(NamesBuffer.data() + Offset);
-}
-
-uint32_t NamedStreamMap::hashString(uint32_t Offset) const {
- return hashStringV1(getString(Offset));
-}
-
-bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
- auto Iter = OffsetIndexMap.find_as(Stream, HashTraits);
- if (Iter == OffsetIndexMap.end())
- return false;
- StreamNo = (*Iter).second;
- return true;
-}
-
-StringMap<uint32_t> NamedStreamMap::entries() const {
- StringMap<uint32_t> Result;
- for (const auto &Entry : OffsetIndexMap) {
- StringRef Stream(NamesBuffer.data() + Entry.first);
- Result.try_emplace(Stream, Entry.second);
- }
- return Result;
-}
-
-uint32_t NamedStreamMap::appendStringData(StringRef S) {
- uint32_t Offset = NamesBuffer.size();
+//===- NamedStreamMap.cpp - PDB Named Stream Map --------------------------===//
+//
+// 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/NamedStreamMap.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/HashTable.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamRef.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <tuple>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NamedStreamMapTraits::NamedStreamMapTraits(NamedStreamMap &NS) : NS(&NS) {}
+
+uint16_t NamedStreamMapTraits::hashLookupKey(StringRef S) const {
+ // In the reference implementation, this uses
+ // HASH Hasher<ULONG*, USHORT*>::hashPbCb(PB pb, size_t cb, ULONG ulMod).
+ // 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));
+}
+
+StringRef NamedStreamMapTraits::storageKeyToLookupKey(uint32_t Offset) const {
+ return NS->getString(Offset);
+}
+
+uint32_t NamedStreamMapTraits::lookupKeyToStorageKey(StringRef S) {
+ return NS->appendStringData(S);
+}
+
+NamedStreamMap::NamedStreamMap() : HashTraits(*this), OffsetIndexMap(1) {}
+
+Error NamedStreamMap::load(BinaryStreamReader &Stream) {
+ uint32_t StringBufferSize;
+ if (auto EC = Stream.readInteger(StringBufferSize))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Expected string buffer size"));
+
+ StringRef Buffer;
+ if (auto EC = Stream.readFixedString(Buffer, StringBufferSize))
+ return EC;
+ NamesBuffer.assign(Buffer.begin(), Buffer.end());
+
+ return OffsetIndexMap.load(Stream);
+}
+
+Error NamedStreamMap::commit(BinaryStreamWriter &Writer) const {
+ // The first field is the number of bytes of string data.
+ if (auto EC = Writer.writeInteger<uint32_t>(NamesBuffer.size()))
+ return EC;
+
+ // Then the actual string data.
+ StringRef Data(NamesBuffer.data(), NamesBuffer.size());
+ if (auto EC = Writer.writeFixedString(Data))
+ return EC;
+
+ // And finally the Offset Index map.
+ if (auto EC = OffsetIndexMap.commit(Writer))
+ return EC;
+
+ return Error::success();
+}
+
+uint32_t NamedStreamMap::calculateSerializedLength() const {
+ return sizeof(uint32_t) // String data size
+ + NamesBuffer.size() // String data
+ + OffsetIndexMap.calculateSerializedLength(); // Offset Index Map
+}
+
+uint32_t NamedStreamMap::size() const { return OffsetIndexMap.size(); }
+
+StringRef NamedStreamMap::getString(uint32_t Offset) const {
+ assert(NamesBuffer.size() > Offset);
+ return StringRef(NamesBuffer.data() + Offset);
+}
+
+uint32_t NamedStreamMap::hashString(uint32_t Offset) const {
+ return hashStringV1(getString(Offset));
+}
+
+bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
+ auto Iter = OffsetIndexMap.find_as(Stream, HashTraits);
+ if (Iter == OffsetIndexMap.end())
+ return false;
+ StreamNo = (*Iter).second;
+ return true;
+}
+
+StringMap<uint32_t> NamedStreamMap::entries() const {
+ StringMap<uint32_t> Result;
+ for (const auto &Entry : OffsetIndexMap) {
+ StringRef Stream(NamesBuffer.data() + Entry.first);
+ Result.try_emplace(Stream, Entry.second);
+ }
+ return Result;
+}
+
+uint32_t NamedStreamMap::appendStringData(StringRef S) {
+ uint32_t Offset = NamesBuffer.size();
llvm::append_range(NamesBuffer, S);
- NamesBuffer.push_back('\0');
- return Offset;
-}
-
-void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
- OffsetIndexMap.set_as(Stream, support::ulittle32_t(StreamNo), HashTraits);
-}
+ NamesBuffer.push_back('\0');
+ return Offset;
+}
+
+void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
+ OffsetIndexMap.set_as(Stream, support::ulittle32_t(StreamNo), HashTraits);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
index 7717f062ea..a1b5027e3a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeCompilandSymbol.cpp
@@ -1,60 +1,60 @@
-//===- NativeCompilandSymbol.cpp - Native impl for compilands ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-
-#include "llvm/ADT/STLExtras.h"
-
-namespace llvm {
-namespace pdb {
-
-NativeCompilandSymbol::NativeCompilandSymbol(NativeSession &Session,
- SymIndexId SymbolId,
- DbiModuleDescriptor MI)
- : NativeRawSymbol(Session, PDB_SymType::Compiland, SymbolId), Module(MI) {}
-
-PDB_SymType NativeCompilandSymbol::getSymTag() const {
- return PDB_SymType::Compiland;
-}
-
-void NativeCompilandSymbol::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
- PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
- dumpSymbolField(OS, "libraryName", getLibraryName(), Indent);
- dumpSymbolField(OS, "name", getName(), Indent);
- dumpSymbolField(OS, "editAndContinueEnabled", isEditAndContinueEnabled(),
- Indent);
-}
-
-bool NativeCompilandSymbol::isEditAndContinueEnabled() const {
- return Module.hasECInfo();
-}
-
-SymIndexId NativeCompilandSymbol::getLexicalParentId() const { return 0; }
-
-// The usage of getObjFileName for getLibraryName and getModuleName for getName
-// may seem backwards, but it is consistent with DIA, which is what this API
-// was modeled after. We may rename these methods later to try to eliminate
-// this potential confusion.
-
-std::string NativeCompilandSymbol::getLibraryName() const {
- return std::string(Module.getObjFileName());
-}
-
-std::string NativeCompilandSymbol::getName() const {
- return std::string(Module.getModuleName());
-}
-
-} // namespace pdb
-} // namespace llvm
+//===- NativeCompilandSymbol.cpp - Native impl for compilands ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+#include "llvm/ADT/STLExtras.h"
+
+namespace llvm {
+namespace pdb {
+
+NativeCompilandSymbol::NativeCompilandSymbol(NativeSession &Session,
+ SymIndexId SymbolId,
+ DbiModuleDescriptor MI)
+ : NativeRawSymbol(Session, PDB_SymType::Compiland, SymbolId), Module(MI) {}
+
+PDB_SymType NativeCompilandSymbol::getSymTag() const {
+ return PDB_SymType::Compiland;
+}
+
+void NativeCompilandSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "libraryName", getLibraryName(), Indent);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolField(OS, "editAndContinueEnabled", isEditAndContinueEnabled(),
+ Indent);
+}
+
+bool NativeCompilandSymbol::isEditAndContinueEnabled() const {
+ return Module.hasECInfo();
+}
+
+SymIndexId NativeCompilandSymbol::getLexicalParentId() const { return 0; }
+
+// The usage of getObjFileName for getLibraryName and getModuleName for getName
+// may seem backwards, but it is consistent with DIA, which is what this API
+// was modeled after. We may rename these methods later to try to eliminate
+// this potential confusion.
+
+std::string NativeCompilandSymbol::getLibraryName() const {
+ return std::string(Module.getObjFileName());
+}
+
+std::string NativeCompilandSymbol::getName() const {
+ return std::string(Module.getModuleName());
+}
+
+} // namespace pdb
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
index 54646867bc..3490ac89c1 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumGlobals.cpp
@@ -1,54 +1,54 @@
-//==- NativeEnumGlobals.cpp - Native Global Enumerator impl ------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
-
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeEnumGlobals::NativeEnumGlobals(NativeSession &PDBSession,
- std::vector<codeview::SymbolKind> Kinds)
- : Index(0), Session(PDBSession) {
- GlobalsStream &GS = cantFail(Session.getPDBFile().getPDBGlobalsStream());
- SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
- for (uint32_t Off : GS.getGlobalsTable()) {
- CVSymbol S = SS.readRecord(Off);
- if (!llvm::is_contained(Kinds, S.kind()))
- continue;
- MatchOffsets.push_back(Off);
- }
-}
-
-uint32_t NativeEnumGlobals::getChildCount() const {
- return static_cast<uint32_t>(MatchOffsets.size());
-}
-
-std::unique_ptr<PDBSymbol>
-NativeEnumGlobals::getChildAtIndex(uint32_t N) const {
- if (N >= MatchOffsets.size())
- return nullptr;
-
- SymIndexId Id =
- Session.getSymbolCache().getOrCreateGlobalSymbolByOffset(MatchOffsets[N]);
- return Session.getSymbolCache().getSymbolById(Id);
-}
-
-std::unique_ptr<PDBSymbol> NativeEnumGlobals::getNext() {
- return getChildAtIndex(Index++);
-}
-
-void NativeEnumGlobals::reset() { Index = 0; }
+//==- NativeEnumGlobals.cpp - Native Global Enumerator impl ------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeEnumGlobals::NativeEnumGlobals(NativeSession &PDBSession,
+ std::vector<codeview::SymbolKind> Kinds)
+ : Index(0), Session(PDBSession) {
+ GlobalsStream &GS = cantFail(Session.getPDBFile().getPDBGlobalsStream());
+ SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
+ for (uint32_t Off : GS.getGlobalsTable()) {
+ CVSymbol S = SS.readRecord(Off);
+ if (!llvm::is_contained(Kinds, S.kind()))
+ continue;
+ MatchOffsets.push_back(Off);
+ }
+}
+
+uint32_t NativeEnumGlobals::getChildCount() const {
+ return static_cast<uint32_t>(MatchOffsets.size());
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumGlobals::getChildAtIndex(uint32_t N) const {
+ if (N >= MatchOffsets.size())
+ return nullptr;
+
+ SymIndexId Id =
+ Session.getSymbolCache().getOrCreateGlobalSymbolByOffset(MatchOffsets[N]);
+ return Session.getSymbolCache().getSymbolById(Id);
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumGlobals::getNext() {
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumGlobals::reset() { Index = 0; }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
index 7a258acbd7..5e154af342 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumInjectedSources.cpp
@@ -1,121 +1,121 @@
-//==- 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 {
- StringRef Ret = cantFail(Strings.getStringForID(Entry.FileNI),
- "InjectedSourceStream should have rejected this");
- return std::string(Ret);
- }
-
- std::string getObjectFileName() const override {
- StringRef Ret = cantFail(Strings.getStringForID(Entry.ObjNI),
- "InjectedSourceStream should have rejected this");
- return std::string(Ret);
- }
-
- std::string getVirtualFileName() const override {
- StringRef Ret = cantFail(Strings.getStringForID(Entry.VFileNI),
- "InjectedSourceStream should have rejected this");
- return std::string(Ret);
- }
-
- uint32_t getCompression() const override { return Entry.Compression; }
-
- std::string getCode() const override {
- // Get name of stream storing the data.
- StringRef VName =
- cantFail(Strings.getStringForID(Entry.VFileNI),
- "InjectedSourceStream should have rejected this");
- std::string StreamName = ("/src/files/" + VName).str();
-
- // Find stream with that name and read its data.
- // FIXME: Consider validating (or even loading) all this in
- // 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 std::make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
- File, Strings);
-}
-
-std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() {
- if (Cur == Stream.end())
- return nullptr;
- return std::make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
-}
-
-void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }
-
-}
-}
+//==- 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 {
+ StringRef Ret = cantFail(Strings.getStringForID(Entry.FileNI),
+ "InjectedSourceStream should have rejected this");
+ return std::string(Ret);
+ }
+
+ std::string getObjectFileName() const override {
+ StringRef Ret = cantFail(Strings.getStringForID(Entry.ObjNI),
+ "InjectedSourceStream should have rejected this");
+ return std::string(Ret);
+ }
+
+ std::string getVirtualFileName() const override {
+ StringRef Ret = cantFail(Strings.getStringForID(Entry.VFileNI),
+ "InjectedSourceStream should have rejected this");
+ return std::string(Ret);
+ }
+
+ uint32_t getCompression() const override { return Entry.Compression; }
+
+ std::string getCode() const override {
+ // Get name of stream storing the data.
+ StringRef VName =
+ cantFail(Strings.getStringForID(Entry.VFileNI),
+ "InjectedSourceStream should have rejected this");
+ std::string StreamName = ("/src/files/" + VName).str();
+
+ // Find stream with that name and read its data.
+ // FIXME: Consider validating (or even loading) all this in
+ // 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 std::make_unique<NativeInjectedSource>(std::next(Stream.begin(), N)->second,
+ File, Strings);
+}
+
+std::unique_ptr<IPDBInjectedSource> NativeEnumInjectedSources::getNext() {
+ if (Cur == Stream.end())
+ return nullptr;
+ return std::make_unique<NativeInjectedSource>((Cur++)->second, File, Strings);
+}
+
+void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }
+
+}
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
index 1e4b076463..9f413be75f 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumLineNumbers.cpp
@@ -1,42 +1,42 @@
-//==- NativeEnumLineNumbers.cpp - Native Type Enumerator impl ----*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeEnumLineNumbers::NativeEnumLineNumbers(
- std::vector<NativeLineNumber> LineNums)
- : Lines(std::move(LineNums)), Index(0) {}
-
-uint32_t NativeEnumLineNumbers::getChildCount() const {
- return static_cast<uint32_t>(Lines.size());
-}
-
-std::unique_ptr<IPDBLineNumber>
-NativeEnumLineNumbers::getChildAtIndex(uint32_t N) const {
- if (N >= getChildCount())
- return nullptr;
- return std::make_unique<NativeLineNumber>(Lines[N]);
-}
-
-std::unique_ptr<IPDBLineNumber> NativeEnumLineNumbers::getNext() {
- return getChildAtIndex(Index++);
-}
-
-void NativeEnumLineNumbers::reset() { Index = 0; }
+//==- NativeEnumLineNumbers.cpp - Native Type Enumerator impl ----*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeEnumLineNumbers::NativeEnumLineNumbers(
+ std::vector<NativeLineNumber> LineNums)
+ : Lines(std::move(LineNums)), Index(0) {}
+
+uint32_t NativeEnumLineNumbers::getChildCount() const {
+ return static_cast<uint32_t>(Lines.size());
+}
+
+std::unique_ptr<IPDBLineNumber>
+NativeEnumLineNumbers::getChildAtIndex(uint32_t N) const {
+ if (N >= getChildCount())
+ return nullptr;
+ return std::make_unique<NativeLineNumber>(Lines[N]);
+}
+
+std::unique_ptr<IPDBLineNumber> NativeEnumLineNumbers::getNext() {
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumLineNumbers::reset() { Index = 0; }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
index c6621924b5..7f12627205 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumModules.cpp
@@ -1,43 +1,43 @@
-//==- NativeEnumModules.cpp - Native Symbol Enumerator impl ------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
-
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-
-namespace llvm {
-namespace pdb {
-
-NativeEnumModules::NativeEnumModules(NativeSession &PDBSession, uint32_t Index)
- : Session(PDBSession), Index(Index) {}
-
-uint32_t NativeEnumModules::getChildCount() const {
- return Session.getSymbolCache().getNumCompilands();
-}
-
-std::unique_ptr<PDBSymbol>
-NativeEnumModules::getChildAtIndex(uint32_t N) const {
- return Session.getSymbolCache().getOrCreateCompiland(N);
-}
-
-std::unique_ptr<PDBSymbol> NativeEnumModules::getNext() {
- if (Index >= getChildCount())
- return nullptr;
- return getChildAtIndex(Index++);
-}
-
-void NativeEnumModules::reset() { Index = 0; }
-
-}
-}
+//==- NativeEnumModules.cpp - Native Symbol Enumerator impl ------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
+
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+
+namespace llvm {
+namespace pdb {
+
+NativeEnumModules::NativeEnumModules(NativeSession &PDBSession, uint32_t Index)
+ : Session(PDBSession), Index(Index) {}
+
+uint32_t NativeEnumModules::getChildCount() const {
+ return Session.getSymbolCache().getNumCompilands();
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumModules::getChildAtIndex(uint32_t N) const {
+ return Session.getSymbolCache().getOrCreateCompiland(N);
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumModules::getNext() {
+ if (Index >= getChildCount())
+ return nullptr;
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumModules::reset() { Index = 0; }
+
+}
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
index ac217df1ee..e4026d865e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeEnumTypes.cpp
@@ -1,70 +1,70 @@
-//==- NativeEnumTypes.cpp - Native Type Enumerator impl ----------*- C++ -*-==//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
-
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
- LazyRandomTypeCollection &Types,
- std::vector<codeview::TypeLeafKind> Kinds)
- : Matches(), Index(0), Session(PDBSession) {
- Optional<TypeIndex> TI = Types.getFirst();
- while (TI) {
- CVType CVT = Types.getType(*TI);
- TypeLeafKind K = CVT.kind();
- if (llvm::is_contained(Kinds, K)) {
- // Don't add forward refs, we'll find those later while enumerating.
- if (!isUdtForwardRef(CVT))
- Matches.push_back(*TI);
- } else if (K == TypeLeafKind::LF_MODIFIER) {
- TypeIndex ModifiedTI = getModifiedType(CVT);
- if (!ModifiedTI.isSimple()) {
- CVType UnmodifiedCVT = Types.getType(ModifiedTI);
- // LF_MODIFIERs point to forward refs, but don't worry about that
- // here. We're pushing the TypeIndex of the LF_MODIFIER itself,
- // so we'll worry about resolving forward refs later.
- if (llvm::is_contained(Kinds, UnmodifiedCVT.kind()))
- Matches.push_back(*TI);
- }
- }
- TI = Types.getNext(*TI);
- }
-}
-
-NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
- std::vector<codeview::TypeIndex> Indices)
- : Matches(std::move(Indices)), Index(0), Session(PDBSession) {}
-
-uint32_t NativeEnumTypes::getChildCount() const {
- return static_cast<uint32_t>(Matches.size());
-}
-
-std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const {
- if (N < Matches.size()) {
- SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]);
- return Session.getSymbolCache().getSymbolById(Id);
- }
- return nullptr;
-}
-
-std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() {
- return getChildAtIndex(Index++);
-}
-
-void NativeEnumTypes::reset() { Index = 0; }
+//==- NativeEnumTypes.cpp - Native Type Enumerator impl ----------*- C++ -*-==//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
+ LazyRandomTypeCollection &Types,
+ std::vector<codeview::TypeLeafKind> Kinds)
+ : Matches(), Index(0), Session(PDBSession) {
+ Optional<TypeIndex> TI = Types.getFirst();
+ while (TI) {
+ CVType CVT = Types.getType(*TI);
+ TypeLeafKind K = CVT.kind();
+ if (llvm::is_contained(Kinds, K)) {
+ // Don't add forward refs, we'll find those later while enumerating.
+ if (!isUdtForwardRef(CVT))
+ Matches.push_back(*TI);
+ } else if (K == TypeLeafKind::LF_MODIFIER) {
+ TypeIndex ModifiedTI = getModifiedType(CVT);
+ if (!ModifiedTI.isSimple()) {
+ CVType UnmodifiedCVT = Types.getType(ModifiedTI);
+ // LF_MODIFIERs point to forward refs, but don't worry about that
+ // here. We're pushing the TypeIndex of the LF_MODIFIER itself,
+ // so we'll worry about resolving forward refs later.
+ if (llvm::is_contained(Kinds, UnmodifiedCVT.kind()))
+ Matches.push_back(*TI);
+ }
+ }
+ TI = Types.getNext(*TI);
+ }
+}
+
+NativeEnumTypes::NativeEnumTypes(NativeSession &PDBSession,
+ std::vector<codeview::TypeIndex> Indices)
+ : Matches(std::move(Indices)), Index(0), Session(PDBSession) {}
+
+uint32_t NativeEnumTypes::getChildCount() const {
+ return static_cast<uint32_t>(Matches.size());
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumTypes::getChildAtIndex(uint32_t N) const {
+ if (N < Matches.size()) {
+ SymIndexId Id = Session.getSymbolCache().findSymbolByTypeIndex(Matches[N]);
+ return Session.getSymbolCache().getSymbolById(Id);
+ }
+ return nullptr;
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumTypes::getNext() {
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumTypes::reset() { Index = 0; }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
index 895f894315..b64aaf2a18 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeExeSymbol.cpp
@@ -1,101 +1,101 @@
-//===- NativeExeSymbol.cpp - native impl for PDBSymbolExe -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-static DbiStream *getDbiStreamPtr(NativeSession &Session) {
- Expected<DbiStream &> DbiS = Session.getPDBFile().getPDBDbiStream();
- if (DbiS)
- return &DbiS.get();
-
- consumeError(DbiS.takeError());
- return nullptr;
-}
-
-NativeExeSymbol::NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId)
- : NativeRawSymbol(Session, PDB_SymType::Exe, SymbolId),
- Dbi(getDbiStreamPtr(Session)) {}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeExeSymbol::findChildren(PDB_SymType Type) const {
- switch (Type) {
- case PDB_SymType::Compiland: {
- return std::unique_ptr<IPDBEnumSymbols>(new NativeEnumModules(Session));
- break;
- }
- case PDB_SymType::ArrayType:
- return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ARRAY);
- case PDB_SymType::Enum:
- return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ENUM);
- case PDB_SymType::PointerType:
- return Session.getSymbolCache().createTypeEnumerator(codeview::LF_POINTER);
- case PDB_SymType::UDT:
- return Session.getSymbolCache().createTypeEnumerator(
- {codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION,
- codeview::LF_INTERFACE});
- case PDB_SymType::VTableShape:
- return Session.getSymbolCache().createTypeEnumerator(codeview::LF_VTSHAPE);
- case PDB_SymType::FunctionSig:
- return Session.getSymbolCache().createTypeEnumerator(
- {codeview::LF_PROCEDURE, codeview::LF_MFUNCTION});
- case PDB_SymType::Typedef:
- return Session.getSymbolCache().createGlobalsEnumerator(codeview::S_UDT);
-
- default:
- break;
- }
- return nullptr;
-}
-
-uint32_t NativeExeSymbol::getAge() const {
- auto IS = Session.getPDBFile().getPDBInfoStream();
- if (IS)
- return IS->getAge();
- consumeError(IS.takeError());
- return 0;
-}
-
-std::string NativeExeSymbol::getSymbolsFileName() const {
- return std::string(Session.getPDBFile().getFilePath());
-}
-
-codeview::GUID NativeExeSymbol::getGuid() const {
- auto IS = Session.getPDBFile().getPDBInfoStream();
- if (IS)
- return IS->getGuid();
- consumeError(IS.takeError());
- return codeview::GUID{{0}};
-}
-
-bool NativeExeSymbol::hasCTypes() const {
- auto Dbi = Session.getPDBFile().getPDBDbiStream();
- if (Dbi)
- return Dbi->hasCTypes();
- consumeError(Dbi.takeError());
- return false;
-}
-
-bool NativeExeSymbol::hasPrivateSymbols() const {
- auto Dbi = Session.getPDBFile().getPDBDbiStream();
- if (Dbi)
- return !Dbi->isStripped();
- consumeError(Dbi.takeError());
- return false;
-}
+//===- NativeExeSymbol.cpp - native impl for PDBSymbolExe -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumModules.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+static DbiStream *getDbiStreamPtr(NativeSession &Session) {
+ Expected<DbiStream &> DbiS = Session.getPDBFile().getPDBDbiStream();
+ if (DbiS)
+ return &DbiS.get();
+
+ consumeError(DbiS.takeError());
+ return nullptr;
+}
+
+NativeExeSymbol::NativeExeSymbol(NativeSession &Session, SymIndexId SymbolId)
+ : NativeRawSymbol(Session, PDB_SymType::Exe, SymbolId),
+ Dbi(getDbiStreamPtr(Session)) {}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeExeSymbol::findChildren(PDB_SymType Type) const {
+ switch (Type) {
+ case PDB_SymType::Compiland: {
+ return std::unique_ptr<IPDBEnumSymbols>(new NativeEnumModules(Session));
+ break;
+ }
+ case PDB_SymType::ArrayType:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ARRAY);
+ case PDB_SymType::Enum:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_ENUM);
+ case PDB_SymType::PointerType:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_POINTER);
+ case PDB_SymType::UDT:
+ return Session.getSymbolCache().createTypeEnumerator(
+ {codeview::LF_STRUCTURE, codeview::LF_CLASS, codeview::LF_UNION,
+ codeview::LF_INTERFACE});
+ case PDB_SymType::VTableShape:
+ return Session.getSymbolCache().createTypeEnumerator(codeview::LF_VTSHAPE);
+ case PDB_SymType::FunctionSig:
+ return Session.getSymbolCache().createTypeEnumerator(
+ {codeview::LF_PROCEDURE, codeview::LF_MFUNCTION});
+ case PDB_SymType::Typedef:
+ return Session.getSymbolCache().createGlobalsEnumerator(codeview::S_UDT);
+
+ default:
+ break;
+ }
+ return nullptr;
+}
+
+uint32_t NativeExeSymbol::getAge() const {
+ auto IS = Session.getPDBFile().getPDBInfoStream();
+ if (IS)
+ return IS->getAge();
+ consumeError(IS.takeError());
+ return 0;
+}
+
+std::string NativeExeSymbol::getSymbolsFileName() const {
+ return std::string(Session.getPDBFile().getFilePath());
+}
+
+codeview::GUID NativeExeSymbol::getGuid() const {
+ auto IS = Session.getPDBFile().getPDBInfoStream();
+ if (IS)
+ return IS->getGuid();
+ consumeError(IS.takeError());
+ return codeview::GUID{{0}};
+}
+
+bool NativeExeSymbol::hasCTypes() const {
+ auto Dbi = Session.getPDBFile().getPDBDbiStream();
+ if (Dbi)
+ return Dbi->hasCTypes();
+ consumeError(Dbi.takeError());
+ return false;
+}
+
+bool NativeExeSymbol::hasPrivateSymbols() const {
+ auto Dbi = Session.getPDBFile().getPDBDbiStream();
+ if (Dbi)
+ return !Dbi->isStripped();
+ consumeError(Dbi.takeError());
+ return false;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
index 7f3b35c297..21d79b95f2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeFunctionSymbol.cpp
@@ -1,60 +1,60 @@
-//===- NativeFunctionSymbol.cpp - info about function symbols----*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
-
+//===- NativeFunctionSymbol.cpp - info about function symbols----*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
+
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,
- SymIndexId Id,
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeFunctionSymbol::NativeFunctionSymbol(NativeSession &Session,
+ SymIndexId Id,
const codeview::ProcSym &Sym,
uint32_t Offset)
: NativeRawSymbol(Session, PDB_SymType::Function, Id), Sym(Sym),
RecordOffset(Offset) {}
-
-NativeFunctionSymbol::~NativeFunctionSymbol() {}
-
-void NativeFunctionSymbol::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
- dumpSymbolField(OS, "name", getName(), Indent);
- dumpSymbolField(OS, "length", getLength(), Indent);
- dumpSymbolField(OS, "offset", getAddressOffset(), Indent);
- dumpSymbolField(OS, "section", getAddressSection(), Indent);
-}
-
-uint32_t NativeFunctionSymbol::getAddressOffset() const {
- return Sym.CodeOffset;
-}
-
-uint32_t NativeFunctionSymbol::getAddressSection() const { return Sym.Segment; }
-std::string NativeFunctionSymbol::getName() const {
- return std::string(Sym.Name);
-}
-
-uint64_t NativeFunctionSymbol::getLength() const { return Sym.CodeSize; }
-
-uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {
- return Session.getRVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
-}
-
-uint64_t NativeFunctionSymbol::getVirtualAddress() const {
- return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
-}
+
+NativeFunctionSymbol::~NativeFunctionSymbol() {}
+
+void NativeFunctionSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "offset", getAddressOffset(), Indent);
+ dumpSymbolField(OS, "section", getAddressSection(), Indent);
+}
+
+uint32_t NativeFunctionSymbol::getAddressOffset() const {
+ return Sym.CodeOffset;
+}
+
+uint32_t NativeFunctionSymbol::getAddressSection() const { return Sym.Segment; }
+std::string NativeFunctionSymbol::getName() const {
+ return std::string(Sym.Name);
+}
+
+uint64_t NativeFunctionSymbol::getLength() const { return Sym.CodeSize; }
+
+uint32_t NativeFunctionSymbol::getRelativeVirtualAddress() const {
+ return Session.getRVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
+}
+
+uint64_t NativeFunctionSymbol::getVirtualAddress() const {
+ return Session.getVAFromSectOffset(Sym.Segment, Sym.CodeOffset);
+}
static bool inlineSiteContainsAddress(InlineSiteSym &IS,
uint32_t OffsetInFunc) {
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
index 155ed0cdb8..685d361c7b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeLineNumber.cpp
@@ -1,51 +1,51 @@
-//===- NativeLineNumber.cpp - Native line number implementation -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-NativeLineNumber::NativeLineNumber(const NativeSession &Session,
- const codeview::LineInfo Line,
- uint32_t ColumnNumber, uint32_t Section,
- uint32_t Offset, uint32_t Length,
+//===- NativeLineNumber.cpp - Native line number implementation -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeLineNumber.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NativeLineNumber::NativeLineNumber(const NativeSession &Session,
+ const codeview::LineInfo Line,
+ uint32_t ColumnNumber, uint32_t Section,
+ uint32_t Offset, uint32_t Length,
uint32_t SrcFileId, uint32_t CompilandId)
- : Session(Session), Line(Line), ColumnNumber(ColumnNumber),
+ : Session(Session), Line(Line), ColumnNumber(ColumnNumber),
Section(Section), Offset(Offset), Length(Length), SrcFileId(SrcFileId),
CompilandId(CompilandId) {}
-
-uint32_t NativeLineNumber::getLineNumber() const { return Line.getStartLine(); }
-
-uint32_t NativeLineNumber::getLineNumberEnd() const {
- return Line.getEndLine();
-}
-
-uint32_t NativeLineNumber::getColumnNumber() const { return ColumnNumber; }
-
-uint32_t NativeLineNumber::getColumnNumberEnd() const { return 0; }
-
-uint32_t NativeLineNumber::getAddressSection() const { return Section; }
-
-uint32_t NativeLineNumber::getAddressOffset() const { return Offset; }
-
-uint32_t NativeLineNumber::getRelativeVirtualAddress() const {
- return Session.getRVAFromSectOffset(Section, Offset);
-}
-
-uint64_t NativeLineNumber::getVirtualAddress() const {
- return Session.getVAFromSectOffset(Section, Offset);
-}
-
-uint32_t NativeLineNumber::getLength() const { return Length; }
-
-uint32_t NativeLineNumber::getSourceFileId() const { return SrcFileId; }
-
+
+uint32_t NativeLineNumber::getLineNumber() const { return Line.getStartLine(); }
+
+uint32_t NativeLineNumber::getLineNumberEnd() const {
+ return Line.getEndLine();
+}
+
+uint32_t NativeLineNumber::getColumnNumber() const { return ColumnNumber; }
+
+uint32_t NativeLineNumber::getColumnNumberEnd() const { return 0; }
+
+uint32_t NativeLineNumber::getAddressSection() const { return Section; }
+
+uint32_t NativeLineNumber::getAddressOffset() const { return Offset; }
+
+uint32_t NativeLineNumber::getRelativeVirtualAddress() const {
+ return Session.getRVAFromSectOffset(Section, Offset);
+}
+
+uint64_t NativeLineNumber::getVirtualAddress() const {
+ return Session.getVAFromSectOffset(Section, Offset);
+}
+
+uint32_t NativeLineNumber::getLength() const { return Length; }
+
+uint32_t NativeLineNumber::getSourceFileId() const { return SrcFileId; }
+
uint32_t NativeLineNumber::getCompilandId() const { return CompilandId; }
-
-bool NativeLineNumber::isStatement() const { return Line.isStatement(); }
+
+bool NativeLineNumber::isStatement() const { return Line.isStatement(); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
index 1265e688b8..f29dc0b5f9 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativePublicSymbol.cpp
@@ -1,48 +1,48 @@
-//===- NativePublicSymbol.cpp - info about public symbols -------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
-
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativePublicSymbol::NativePublicSymbol(NativeSession &Session, SymIndexId Id,
- const codeview::PublicSym32 &Sym)
+//===- NativePublicSymbol.cpp - info about public symbols -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativePublicSymbol::NativePublicSymbol(NativeSession &Session, SymIndexId Id,
+ const codeview::PublicSym32 &Sym)
: NativeRawSymbol(Session, PDB_SymType::PublicSymbol, Id), Sym(Sym) {}
-
-NativePublicSymbol::~NativePublicSymbol() {}
-
-void NativePublicSymbol::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
- dumpSymbolField(OS, "name", getName(), Indent);
- dumpSymbolField(OS, "offset", getAddressOffset(), Indent);
- dumpSymbolField(OS, "section", getAddressSection(), Indent);
-}
-
-uint32_t NativePublicSymbol::getAddressOffset() const { return Sym.Offset; }
-
-uint32_t NativePublicSymbol::getAddressSection() const { return Sym.Segment; }
-
-std::string NativePublicSymbol::getName() const {
- return std::string(Sym.Name);
-}
-
-uint32_t NativePublicSymbol::getRelativeVirtualAddress() const {
- return Session.getRVAFromSectOffset(Sym.Segment, Sym.Offset);
-}
-
-uint64_t NativePublicSymbol::getVirtualAddress() const {
- return Session.getVAFromSectOffset(Sym.Segment, Sym.Offset);
-}
+
+NativePublicSymbol::~NativePublicSymbol() {}
+
+void NativePublicSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolField(OS, "offset", getAddressOffset(), Indent);
+ dumpSymbolField(OS, "section", getAddressSection(), Indent);
+}
+
+uint32_t NativePublicSymbol::getAddressOffset() const { return Sym.Offset; }
+
+uint32_t NativePublicSymbol::getAddressSection() const { return Sym.Segment; }
+
+std::string NativePublicSymbol::getName() const {
+ return std::string(Sym.Name);
+}
+
+uint32_t NativePublicSymbol::getRelativeVirtualAddress() const {
+ return Session.getRVAFromSectOffset(Sym.Segment, Sym.Offset);
+}
+
+uint64_t NativePublicSymbol::getVirtualAddress() const {
+ return Session.getVAFromSectOffset(Sym.Segment, Sym.Offset);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
index 2ad552470b..a3e51c8efd 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeRawSymbol.cpp
@@ -1,734 +1,734 @@
-//===- NativeRawSymbol.cpp - Native implementation of IPDBRawSymbol -------===//
-//
-// 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/NativeRawSymbol.h"
-#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-#include "llvm/Support/FormatVariadic.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag,
- SymIndexId SymbolId)
- : Session(PDBSession), Tag(Tag), SymbolId(SymbolId) {}
-
-void NativeRawSymbol::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- dumpSymbolIdField(OS, "symIndexId", SymbolId, Indent, Session,
- PdbSymbolIdField::SymIndexId, ShowIdFields,
- RecurseIdFields);
- dumpSymbolField(OS, "symTag", Tag, Indent);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findChildren(PDB_SymType Type) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findChildren(PDB_SymType Type, StringRef Name,
- PDB_NameSearchFlags Flags) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
- PDB_NameSearchFlags Flags, uint32_t Section, uint32_t Offset) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
- PDB_NameSearchFlags Flags, uint64_t VA) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
- PDB_NameSearchFlags Flags, uint32_t RVA) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findInlineFramesByAddr(uint32_t Section,
- uint32_t Offset) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeRawSymbol::findInlineFramesByVA(uint64_t VA) const {
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeRawSymbol::findInlineeLines() const {
- return std::make_unique<NullEnumerator<IPDBLineNumber>>();
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeRawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
- uint32_t Length) const {
- return std::make_unique<NullEnumerator<IPDBLineNumber>>();
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeRawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
- return std::make_unique<NullEnumerator<IPDBLineNumber>>();
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeRawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
- return std::make_unique<NullEnumerator<IPDBLineNumber>>();
-}
-
-void NativeRawSymbol::getDataBytes(SmallVector<uint8_t, 32> &bytes) const {
- bytes.clear();
-}
-
-PDB_MemberAccess NativeRawSymbol::getAccess() const {
- return PDB_MemberAccess::Private;
-}
-
-uint32_t NativeRawSymbol::getAddressOffset() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getAddressSection() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getAge() const {
- return 0;
-}
-
-SymIndexId NativeRawSymbol::getArrayIndexTypeId() const { return 0; }
-
-void NativeRawSymbol::getBackEndVersion(VersionInfo &Version) const {
- Version.Major = 0;
- Version.Minor = 0;
- Version.Build = 0;
- Version.QFE = 0;
-}
-
-uint32_t NativeRawSymbol::getBaseDataOffset() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getBaseDataSlot() const {
- return 0;
-}
-
-SymIndexId NativeRawSymbol::getBaseSymbolId() const { return 0; }
-
-PDB_BuiltinType NativeRawSymbol::getBuiltinType() const {
- return PDB_BuiltinType::None;
-}
-
-uint32_t NativeRawSymbol::getBitPosition() const {
- return 0;
-}
-
-PDB_CallingConv NativeRawSymbol::getCallingConvention() const {
- return PDB_CallingConv::FarStdCall;
-}
-
-SymIndexId NativeRawSymbol::getClassParentId() const { return 0; }
-
-std::string NativeRawSymbol::getCompilerName() const {
- return {};
-}
-
-uint32_t NativeRawSymbol::getCount() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getCountLiveRanges() const {
- return 0;
-}
-
-void NativeRawSymbol::getFrontEndVersion(VersionInfo &Version) const {
- Version.Major = 0;
- Version.Minor = 0;
- Version.Build = 0;
- Version.QFE = 0;
-}
-
-PDB_Lang NativeRawSymbol::getLanguage() const {
- return PDB_Lang::Cobol;
-}
-
-SymIndexId NativeRawSymbol::getLexicalParentId() const { return 0; }
-
-std::string NativeRawSymbol::getLibraryName() const {
- return {};
-}
-
-uint32_t NativeRawSymbol::getLiveRangeStartAddressOffset() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getLiveRangeStartAddressSection() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getLiveRangeStartRelativeVirtualAddress() const {
- return 0;
-}
-
-codeview::RegisterId NativeRawSymbol::getLocalBasePointerRegisterId() const {
- return codeview::RegisterId::EAX;
-}
-
-SymIndexId NativeRawSymbol::getLowerBoundId() const { return 0; }
-
-uint32_t NativeRawSymbol::getMemorySpaceKind() const {
- return 0;
-}
-
-std::string NativeRawSymbol::getName() const {
- return {};
-}
-
-uint32_t NativeRawSymbol::getNumberOfAcceleratorPointerTags() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getNumberOfColumns() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getNumberOfModifiers() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getNumberOfRegisterIndices() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getNumberOfRows() const {
- return 0;
-}
-
-std::string NativeRawSymbol::getObjectFileName() const {
- return {};
-}
-
-uint32_t NativeRawSymbol::getOemId() const {
- return 0;
-}
-
-SymIndexId NativeRawSymbol::getOemSymbolId() const { return 0; }
-
-uint32_t NativeRawSymbol::getOffsetInUdt() const {
- return 0;
-}
-
-PDB_Cpu NativeRawSymbol::getPlatform() const {
- return PDB_Cpu::Intel8080;
-}
-
-uint32_t NativeRawSymbol::getRank() const {
- return 0;
-}
-
-codeview::RegisterId NativeRawSymbol::getRegisterId() const {
- return codeview::RegisterId::EAX;
-}
-
-uint32_t NativeRawSymbol::getRegisterType() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getRelativeVirtualAddress() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getSamplerSlot() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getSignature() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getSizeInUdt() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getSlot() const {
- return 0;
-}
-
-std::string NativeRawSymbol::getSourceFileName() const {
- return {};
-}
-
-std::unique_ptr<IPDBLineNumber>
-NativeRawSymbol::getSrcLineOnTypeDefn() const {
- return nullptr;
-}
-
-uint32_t NativeRawSymbol::getStride() const {
- return 0;
-}
-
-SymIndexId NativeRawSymbol::getSubTypeId() const { return 0; }
-
-std::string NativeRawSymbol::getSymbolsFileName() const { return {}; }
-
-SymIndexId NativeRawSymbol::getSymIndexId() const { return SymbolId; }
-
-uint32_t NativeRawSymbol::getTargetOffset() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getTargetRelativeVirtualAddress() const {
- return 0;
-}
-
-uint64_t NativeRawSymbol::getTargetVirtualAddress() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getTargetSection() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getTextureSlot() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getTimeStamp() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getToken() const {
- return 0;
-}
-
-SymIndexId NativeRawSymbol::getTypeId() const { return 0; }
-
-uint32_t NativeRawSymbol::getUavSlot() const {
- return 0;
-}
-
-std::string NativeRawSymbol::getUndecoratedName() const {
- return {};
-}
-
-std::string NativeRawSymbol::getUndecoratedNameEx(
- PDB_UndnameFlags Flags) const {
- return {};
-}
-
-SymIndexId NativeRawSymbol::getUnmodifiedTypeId() const { return 0; }
-
-SymIndexId NativeRawSymbol::getUpperBoundId() const { return 0; }
-
-Variant NativeRawSymbol::getValue() const {
- return Variant();
-}
-
-uint32_t NativeRawSymbol::getVirtualBaseDispIndex() const {
- return 0;
-}
-
-uint32_t NativeRawSymbol::getVirtualBaseOffset() const {
- return 0;
-}
-
-SymIndexId NativeRawSymbol::getVirtualTableShapeId() const { return 0; }
-
-std::unique_ptr<PDBSymbolTypeBuiltin>
-NativeRawSymbol::getVirtualBaseTableType() const {
- return nullptr;
-}
-
-PDB_DataKind NativeRawSymbol::getDataKind() const {
- return PDB_DataKind::Unknown;
-}
-
-PDB_SymType NativeRawSymbol::getSymTag() const { return Tag; }
-
-codeview::GUID NativeRawSymbol::getGuid() const { return codeview::GUID{{0}}; }
-
-int32_t NativeRawSymbol::getOffset() const {
- return 0;
-}
-
-int32_t NativeRawSymbol::getThisAdjust() const {
- return 0;
-}
-
-int32_t NativeRawSymbol::getVirtualBasePointerOffset() const {
- return 0;
-}
-
-PDB_LocType NativeRawSymbol::getLocationType() const {
- return PDB_LocType::Null;
-}
-
-PDB_Machine NativeRawSymbol::getMachineType() const {
- return PDB_Machine::Invalid;
-}
-
-codeview::ThunkOrdinal NativeRawSymbol::getThunkOrdinal() const {
- return codeview::ThunkOrdinal::Standard;
-}
-
-uint64_t NativeRawSymbol::getLength() const {
- return 0;
-}
-
-uint64_t NativeRawSymbol::getLiveRangeLength() const {
- return 0;
-}
-
-uint64_t NativeRawSymbol::getVirtualAddress() const {
- return 0;
-}
-
-PDB_UdtType NativeRawSymbol::getUdtKind() const {
- return PDB_UdtType::Struct;
-}
-
-bool NativeRawSymbol::hasConstructor() const {
- return false;
-}
-
-bool NativeRawSymbol::hasCustomCallingConvention() const {
- return false;
-}
-
-bool NativeRawSymbol::hasFarReturn() const {
- return false;
-}
-
-bool NativeRawSymbol::isCode() const {
- return false;
-}
-
-bool NativeRawSymbol::isCompilerGenerated() const {
- return false;
-}
-
-bool NativeRawSymbol::isConstType() const {
- return false;
-}
-
-bool NativeRawSymbol::isEditAndContinueEnabled() const {
- return false;
-}
-
-bool NativeRawSymbol::isFunction() const {
- return false;
-}
-
-bool NativeRawSymbol::getAddressTaken() const {
- return false;
-}
-
-bool NativeRawSymbol::getNoStackOrdering() const {
- return false;
-}
-
-bool NativeRawSymbol::hasAlloca() const {
- return false;
-}
-
-bool NativeRawSymbol::hasAssignmentOperator() const {
- return false;
-}
-
-bool NativeRawSymbol::hasCTypes() const {
- return false;
-}
-
-bool NativeRawSymbol::hasCastOperator() const {
- return false;
-}
-
-bool NativeRawSymbol::hasDebugInfo() const {
- return false;
-}
-
-bool NativeRawSymbol::hasEH() const {
- return false;
-}
-
-bool NativeRawSymbol::hasEHa() const {
- return false;
-}
-
-bool NativeRawSymbol::hasInlAsm() const {
- return false;
-}
-
-bool NativeRawSymbol::hasInlineAttribute() const {
- return false;
-}
-
-bool NativeRawSymbol::hasInterruptReturn() const {
- return false;
-}
-
-bool NativeRawSymbol::hasFramePointer() const {
- return false;
-}
-
-bool NativeRawSymbol::hasLongJump() const {
- return false;
-}
-
-bool NativeRawSymbol::hasManagedCode() const {
- return false;
-}
-
-bool NativeRawSymbol::hasNestedTypes() const {
- return false;
-}
-
-bool NativeRawSymbol::hasNoInlineAttribute() const {
- return false;
-}
-
-bool NativeRawSymbol::hasNoReturnAttribute() const {
- return false;
-}
-
-bool NativeRawSymbol::hasOptimizedCodeDebugInfo() const {
- return false;
-}
-
-bool NativeRawSymbol::hasOverloadedOperator() const {
- return false;
-}
-
-bool NativeRawSymbol::hasSEH() const {
- return false;
-}
-
-bool NativeRawSymbol::hasSecurityChecks() const {
- return false;
-}
-
-bool NativeRawSymbol::hasSetJump() const {
- return false;
-}
-
-bool NativeRawSymbol::hasStrictGSCheck() const {
- return false;
-}
-
-bool NativeRawSymbol::isAcceleratorGroupSharedLocal() const {
- return false;
-}
-
-bool NativeRawSymbol::isAcceleratorPointerTagLiveRange() const {
- return false;
-}
-
-bool NativeRawSymbol::isAcceleratorStubFunction() const {
- return false;
-}
-
-bool NativeRawSymbol::isAggregated() const {
- return false;
-}
-
-bool NativeRawSymbol::isIntroVirtualFunction() const {
- return false;
-}
-
-bool NativeRawSymbol::isCVTCIL() const {
- return false;
-}
-
-bool NativeRawSymbol::isConstructorVirtualBase() const {
- return false;
-}
-
-bool NativeRawSymbol::isCxxReturnUdt() const {
- return false;
-}
-
-bool NativeRawSymbol::isDataAligned() const {
- return false;
-}
-
-bool NativeRawSymbol::isHLSLData() const {
- return false;
-}
-
-bool NativeRawSymbol::isHotpatchable() const {
- return false;
-}
-
-bool NativeRawSymbol::isIndirectVirtualBaseClass() const {
- return false;
-}
-
-bool NativeRawSymbol::isInterfaceUdt() const {
- return false;
-}
-
-bool NativeRawSymbol::isIntrinsic() const {
- return false;
-}
-
-bool NativeRawSymbol::isLTCG() const {
- return false;
-}
-
-bool NativeRawSymbol::isLocationControlFlowDependent() const {
- return false;
-}
-
-bool NativeRawSymbol::isMSILNetmodule() const {
- return false;
-}
-
-bool NativeRawSymbol::isMatrixRowMajor() const {
- return false;
-}
-
-bool NativeRawSymbol::isManagedCode() const {
- return false;
-}
-
-bool NativeRawSymbol::isMSILCode() const {
- return false;
-}
-
-bool NativeRawSymbol::isMultipleInheritance() const {
- return false;
-}
-
-bool NativeRawSymbol::isNaked() const {
- return false;
-}
-
-bool NativeRawSymbol::isNested() const {
- return false;
-}
-
-bool NativeRawSymbol::isOptimizedAway() const {
- return false;
-}
-
-bool NativeRawSymbol::isPacked() const {
- return false;
-}
-
-bool NativeRawSymbol::isPointerBasedOnSymbolValue() const {
- return false;
-}
-
-bool NativeRawSymbol::isPointerToDataMember() const {
- return false;
-}
-
-bool NativeRawSymbol::isPointerToMemberFunction() const {
- return false;
-}
-
-bool NativeRawSymbol::isPureVirtual() const {
- return false;
-}
-
-bool NativeRawSymbol::isRValueReference() const {
- return false;
-}
-
-bool NativeRawSymbol::isRefUdt() const {
- return false;
-}
-
-bool NativeRawSymbol::isReference() const {
- return false;
-}
-
-bool NativeRawSymbol::isRestrictedType() const {
- return false;
-}
-
-bool NativeRawSymbol::isReturnValue() const {
- return false;
-}
-
-bool NativeRawSymbol::isSafeBuffers() const {
- return false;
-}
-
-bool NativeRawSymbol::isScoped() const {
- return false;
-}
-
-bool NativeRawSymbol::isSdl() const {
- return false;
-}
-
-bool NativeRawSymbol::isSingleInheritance() const {
- return false;
-}
-
-bool NativeRawSymbol::isSplitted() const {
- return false;
-}
-
-bool NativeRawSymbol::isStatic() const {
- return false;
-}
-
-bool NativeRawSymbol::hasPrivateSymbols() const {
- return false;
-}
-
-bool NativeRawSymbol::isUnalignedType() const {
- return false;
-}
-
-bool NativeRawSymbol::isUnreached() const {
- return false;
-}
-
-bool NativeRawSymbol::isValueUdt() const {
- return false;
-}
-
-bool NativeRawSymbol::isVirtual() const {
- return false;
-}
-
-bool NativeRawSymbol::isVirtualBaseClass() const {
- return false;
-}
-
-bool NativeRawSymbol::isVirtualInheritance() const {
- return false;
-}
-
-bool NativeRawSymbol::isVolatileType() const {
- return false;
-}
-
-bool NativeRawSymbol::wasInlined() const {
- return false;
-}
-
-std::string NativeRawSymbol::getUnused() const {
- return {};
-}
+//===- NativeRawSymbol.cpp - Native implementation of IPDBRawSymbol -------===//
+//
+// 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/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NativeRawSymbol::NativeRawSymbol(NativeSession &PDBSession, PDB_SymType Tag,
+ SymIndexId SymbolId)
+ : Session(PDBSession), Tag(Tag), SymbolId(SymbolId) {}
+
+void NativeRawSymbol::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ dumpSymbolIdField(OS, "symIndexId", SymbolId, Indent, Session,
+ PdbSymbolIdField::SymIndexId, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "symTag", Tag, Indent);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildren(PDB_SymType Type) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildren(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildrenByAddr(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags, uint32_t Section, uint32_t Offset) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildrenByVA(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags, uint64_t VA) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags, uint32_t RVA) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findInlineFramesByAddr(uint32_t Section,
+ uint32_t Offset) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findInlineFramesByRVA(uint32_t RVA) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeRawSymbol::findInlineFramesByVA(uint64_t VA) const {
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeRawSymbol::findInlineeLines() const {
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeRawSymbol::findInlineeLinesByAddr(uint32_t Section, uint32_t Offset,
+ uint32_t Length) const {
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeRawSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeRawSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
+ return std::make_unique<NullEnumerator<IPDBLineNumber>>();
+}
+
+void NativeRawSymbol::getDataBytes(SmallVector<uint8_t, 32> &bytes) const {
+ bytes.clear();
+}
+
+PDB_MemberAccess NativeRawSymbol::getAccess() const {
+ return PDB_MemberAccess::Private;
+}
+
+uint32_t NativeRawSymbol::getAddressOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getAddressSection() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getAge() const {
+ return 0;
+}
+
+SymIndexId NativeRawSymbol::getArrayIndexTypeId() const { return 0; }
+
+void NativeRawSymbol::getBackEndVersion(VersionInfo &Version) const {
+ Version.Major = 0;
+ Version.Minor = 0;
+ Version.Build = 0;
+ Version.QFE = 0;
+}
+
+uint32_t NativeRawSymbol::getBaseDataOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getBaseDataSlot() const {
+ return 0;
+}
+
+SymIndexId NativeRawSymbol::getBaseSymbolId() const { return 0; }
+
+PDB_BuiltinType NativeRawSymbol::getBuiltinType() const {
+ return PDB_BuiltinType::None;
+}
+
+uint32_t NativeRawSymbol::getBitPosition() const {
+ return 0;
+}
+
+PDB_CallingConv NativeRawSymbol::getCallingConvention() const {
+ return PDB_CallingConv::FarStdCall;
+}
+
+SymIndexId NativeRawSymbol::getClassParentId() const { return 0; }
+
+std::string NativeRawSymbol::getCompilerName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getCount() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getCountLiveRanges() const {
+ return 0;
+}
+
+void NativeRawSymbol::getFrontEndVersion(VersionInfo &Version) const {
+ Version.Major = 0;
+ Version.Minor = 0;
+ Version.Build = 0;
+ Version.QFE = 0;
+}
+
+PDB_Lang NativeRawSymbol::getLanguage() const {
+ return PDB_Lang::Cobol;
+}
+
+SymIndexId NativeRawSymbol::getLexicalParentId() const { return 0; }
+
+std::string NativeRawSymbol::getLibraryName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getLiveRangeStartAddressOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getLiveRangeStartAddressSection() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getLiveRangeStartRelativeVirtualAddress() const {
+ return 0;
+}
+
+codeview::RegisterId NativeRawSymbol::getLocalBasePointerRegisterId() const {
+ return codeview::RegisterId::EAX;
+}
+
+SymIndexId NativeRawSymbol::getLowerBoundId() const { return 0; }
+
+uint32_t NativeRawSymbol::getMemorySpaceKind() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getNumberOfAcceleratorPointerTags() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfColumns() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfModifiers() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfRegisterIndices() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getNumberOfRows() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getObjectFileName() const {
+ return {};
+}
+
+uint32_t NativeRawSymbol::getOemId() const {
+ return 0;
+}
+
+SymIndexId NativeRawSymbol::getOemSymbolId() const { return 0; }
+
+uint32_t NativeRawSymbol::getOffsetInUdt() const {
+ return 0;
+}
+
+PDB_Cpu NativeRawSymbol::getPlatform() const {
+ return PDB_Cpu::Intel8080;
+}
+
+uint32_t NativeRawSymbol::getRank() const {
+ return 0;
+}
+
+codeview::RegisterId NativeRawSymbol::getRegisterId() const {
+ return codeview::RegisterId::EAX;
+}
+
+uint32_t NativeRawSymbol::getRegisterType() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getRelativeVirtualAddress() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSamplerSlot() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSignature() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSizeInUdt() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getSlot() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getSourceFileName() const {
+ return {};
+}
+
+std::unique_ptr<IPDBLineNumber>
+NativeRawSymbol::getSrcLineOnTypeDefn() const {
+ return nullptr;
+}
+
+uint32_t NativeRawSymbol::getStride() const {
+ return 0;
+}
+
+SymIndexId NativeRawSymbol::getSubTypeId() const { return 0; }
+
+std::string NativeRawSymbol::getSymbolsFileName() const { return {}; }
+
+SymIndexId NativeRawSymbol::getSymIndexId() const { return SymbolId; }
+
+uint32_t NativeRawSymbol::getTargetOffset() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTargetRelativeVirtualAddress() const {
+ return 0;
+}
+
+uint64_t NativeRawSymbol::getTargetVirtualAddress() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTargetSection() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTextureSlot() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getTimeStamp() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getToken() const {
+ return 0;
+}
+
+SymIndexId NativeRawSymbol::getTypeId() const { return 0; }
+
+uint32_t NativeRawSymbol::getUavSlot() const {
+ return 0;
+}
+
+std::string NativeRawSymbol::getUndecoratedName() const {
+ return {};
+}
+
+std::string NativeRawSymbol::getUndecoratedNameEx(
+ PDB_UndnameFlags Flags) const {
+ return {};
+}
+
+SymIndexId NativeRawSymbol::getUnmodifiedTypeId() const { return 0; }
+
+SymIndexId NativeRawSymbol::getUpperBoundId() const { return 0; }
+
+Variant NativeRawSymbol::getValue() const {
+ return Variant();
+}
+
+uint32_t NativeRawSymbol::getVirtualBaseDispIndex() const {
+ return 0;
+}
+
+uint32_t NativeRawSymbol::getVirtualBaseOffset() const {
+ return 0;
+}
+
+SymIndexId NativeRawSymbol::getVirtualTableShapeId() const { return 0; }
+
+std::unique_ptr<PDBSymbolTypeBuiltin>
+NativeRawSymbol::getVirtualBaseTableType() const {
+ return nullptr;
+}
+
+PDB_DataKind NativeRawSymbol::getDataKind() const {
+ return PDB_DataKind::Unknown;
+}
+
+PDB_SymType NativeRawSymbol::getSymTag() const { return Tag; }
+
+codeview::GUID NativeRawSymbol::getGuid() const { return codeview::GUID{{0}}; }
+
+int32_t NativeRawSymbol::getOffset() const {
+ return 0;
+}
+
+int32_t NativeRawSymbol::getThisAdjust() const {
+ return 0;
+}
+
+int32_t NativeRawSymbol::getVirtualBasePointerOffset() const {
+ return 0;
+}
+
+PDB_LocType NativeRawSymbol::getLocationType() const {
+ return PDB_LocType::Null;
+}
+
+PDB_Machine NativeRawSymbol::getMachineType() const {
+ return PDB_Machine::Invalid;
+}
+
+codeview::ThunkOrdinal NativeRawSymbol::getThunkOrdinal() const {
+ return codeview::ThunkOrdinal::Standard;
+}
+
+uint64_t NativeRawSymbol::getLength() const {
+ return 0;
+}
+
+uint64_t NativeRawSymbol::getLiveRangeLength() const {
+ return 0;
+}
+
+uint64_t NativeRawSymbol::getVirtualAddress() const {
+ return 0;
+}
+
+PDB_UdtType NativeRawSymbol::getUdtKind() const {
+ return PDB_UdtType::Struct;
+}
+
+bool NativeRawSymbol::hasConstructor() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasCustomCallingConvention() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasFarReturn() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCompilerGenerated() const {
+ return false;
+}
+
+bool NativeRawSymbol::isConstType() const {
+ return false;
+}
+
+bool NativeRawSymbol::isEditAndContinueEnabled() const {
+ return false;
+}
+
+bool NativeRawSymbol::isFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::getAddressTaken() const {
+ return false;
+}
+
+bool NativeRawSymbol::getNoStackOrdering() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasAlloca() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasAssignmentOperator() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasCTypes() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasCastOperator() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasDebugInfo() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasEH() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasEHa() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasInlAsm() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasInlineAttribute() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasInterruptReturn() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasFramePointer() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasLongJump() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasManagedCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasNestedTypes() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasNoInlineAttribute() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasNoReturnAttribute() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasOptimizedCodeDebugInfo() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasOverloadedOperator() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasSEH() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasSecurityChecks() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasSetJump() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasStrictGSCheck() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAcceleratorGroupSharedLocal() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAcceleratorPointerTagLiveRange() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAcceleratorStubFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::isAggregated() const {
+ return false;
+}
+
+bool NativeRawSymbol::isIntroVirtualFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCVTCIL() const {
+ return false;
+}
+
+bool NativeRawSymbol::isConstructorVirtualBase() const {
+ return false;
+}
+
+bool NativeRawSymbol::isCxxReturnUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isDataAligned() const {
+ return false;
+}
+
+bool NativeRawSymbol::isHLSLData() const {
+ return false;
+}
+
+bool NativeRawSymbol::isHotpatchable() const {
+ return false;
+}
+
+bool NativeRawSymbol::isIndirectVirtualBaseClass() const {
+ return false;
+}
+
+bool NativeRawSymbol::isInterfaceUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isIntrinsic() const {
+ return false;
+}
+
+bool NativeRawSymbol::isLTCG() const {
+ return false;
+}
+
+bool NativeRawSymbol::isLocationControlFlowDependent() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMSILNetmodule() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMatrixRowMajor() const {
+ return false;
+}
+
+bool NativeRawSymbol::isManagedCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMSILCode() const {
+ return false;
+}
+
+bool NativeRawSymbol::isMultipleInheritance() const {
+ return false;
+}
+
+bool NativeRawSymbol::isNaked() const {
+ return false;
+}
+
+bool NativeRawSymbol::isNested() const {
+ return false;
+}
+
+bool NativeRawSymbol::isOptimizedAway() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPacked() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPointerBasedOnSymbolValue() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPointerToDataMember() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPointerToMemberFunction() const {
+ return false;
+}
+
+bool NativeRawSymbol::isPureVirtual() const {
+ return false;
+}
+
+bool NativeRawSymbol::isRValueReference() const {
+ return false;
+}
+
+bool NativeRawSymbol::isRefUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isReference() const {
+ return false;
+}
+
+bool NativeRawSymbol::isRestrictedType() const {
+ return false;
+}
+
+bool NativeRawSymbol::isReturnValue() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSafeBuffers() const {
+ return false;
+}
+
+bool NativeRawSymbol::isScoped() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSdl() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSingleInheritance() const {
+ return false;
+}
+
+bool NativeRawSymbol::isSplitted() const {
+ return false;
+}
+
+bool NativeRawSymbol::isStatic() const {
+ return false;
+}
+
+bool NativeRawSymbol::hasPrivateSymbols() const {
+ return false;
+}
+
+bool NativeRawSymbol::isUnalignedType() const {
+ return false;
+}
+
+bool NativeRawSymbol::isUnreached() const {
+ return false;
+}
+
+bool NativeRawSymbol::isValueUdt() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVirtual() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVirtualBaseClass() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVirtualInheritance() const {
+ return false;
+}
+
+bool NativeRawSymbol::isVolatileType() const {
+ return false;
+}
+
+bool NativeRawSymbol::wasInlined() const {
+ return false;
+}
+
+std::string NativeRawSymbol::getUnused() const {
+ return {};
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp
index 5d7946cdc2..bfefe41a00 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSession.cpp
@@ -1,395 +1,395 @@
-//===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+//===- NativeSession.cpp - Native implementation of IPDBSession -*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.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"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/ErrorOr.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-
-#include <algorithm>
-#include <cassert>
-#include <memory>
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-static DbiStream *getDbiStreamPtr(PDBFile &File) {
- Expected<DbiStream &> DbiS = File.getPDBDbiStream();
- if (DbiS)
- return &DbiS.get();
-
- consumeError(DbiS.takeError());
- return nullptr;
-}
-
-NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
- std::unique_ptr<BumpPtrAllocator> Allocator)
- : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
+#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"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+
+#include <algorithm>
+#include <cassert>
+#include <memory>
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+static DbiStream *getDbiStreamPtr(PDBFile &File) {
+ Expected<DbiStream &> DbiS = File.getPDBDbiStream();
+ if (DbiS)
+ return &DbiS.get();
+
+ consumeError(DbiS.takeError());
+ return nullptr;
+}
+
+NativeSession::NativeSession(std::unique_ptr<PDBFile> PdbFile,
+ std::unique_ptr<BumpPtrAllocator> Allocator)
+ : Pdb(std::move(PdbFile)), Allocator(std::move(Allocator)),
Cache(*this, getDbiStreamPtr(*Pdb)), AddrToModuleIndex(IMapAllocator) {}
-
-NativeSession::~NativeSession() = default;
-
-Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
- std::unique_ptr<IPDBSession> &Session) {
- StringRef Path = Buffer->getBufferIdentifier();
- auto Stream = std::make_unique<MemoryBufferByteStream>(
- std::move(Buffer), llvm::support::little);
-
- auto Allocator = std::make_unique<BumpPtrAllocator>();
- auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
- if (auto EC = File->parseFileHeaders())
- return EC;
- if (auto EC = File->parseStreamData())
- return EC;
-
- Session =
- std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
-
- return Error::success();
-}
-
-static Expected<std::unique_ptr<PDBFile>>
-loadPdbFile(StringRef PdbPath, std::unique_ptr<BumpPtrAllocator> &Allocator) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
- MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
- /*RequiresNullTerminator=*/false);
- if (!ErrorOrBuffer)
- return make_error<RawError>(ErrorOrBuffer.getError());
- std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
-
- PdbPath = Buffer->getBufferIdentifier();
- file_magic Magic;
- auto EC = identify_magic(PdbPath, Magic);
- if (EC || Magic != file_magic::pdb)
- return make_error<RawError>(EC);
-
- auto Stream = std::make_unique<MemoryBufferByteStream>(std::move(Buffer),
- llvm::support::little);
-
- auto File = std::make_unique<PDBFile>(PdbPath, std::move(Stream), *Allocator);
- if (auto EC = File->parseFileHeaders())
- return std::move(EC);
-
- if (auto EC = File->parseStreamData())
- return std::move(EC);
-
- return std::move(File);
-}
-
-Error NativeSession::createFromPdbPath(StringRef PdbPath,
- std::unique_ptr<IPDBSession> &Session) {
- auto Allocator = std::make_unique<BumpPtrAllocator>();
- auto PdbFile = loadPdbFile(PdbPath, Allocator);
- if (!PdbFile)
- return PdbFile.takeError();
-
- Session = std::make_unique<NativeSession>(std::move(PdbFile.get()),
- std::move(Allocator));
- return Error::success();
-}
-
-static Expected<std::string> getPdbPathFromExe(StringRef ExePath) {
- Expected<object::OwningBinary<object::Binary>> BinaryFile =
- object::createBinary(ExePath);
- if (!BinaryFile)
- return BinaryFile.takeError();
-
- const object::COFFObjectFile *ObjFile =
- dyn_cast<object::COFFObjectFile>(BinaryFile->getBinary());
- if (!ObjFile)
- return make_error<RawError>(raw_error_code::invalid_format);
-
- StringRef PdbPath;
- const llvm::codeview::DebugInfo *PdbInfo = nullptr;
- if (Error E = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
- return std::move(E);
-
- return std::string(PdbPath);
-}
-
-Error NativeSession::createFromExe(StringRef ExePath,
- std::unique_ptr<IPDBSession> &Session) {
- Expected<std::string> PdbPath = getPdbPathFromExe(ExePath);
- if (!PdbPath)
- return PdbPath.takeError();
-
- file_magic Magic;
- auto EC = identify_magic(PdbPath.get(), Magic);
- if (EC || Magic != file_magic::pdb)
- return make_error<RawError>(EC);
-
- auto Allocator = std::make_unique<BumpPtrAllocator>();
- auto File = loadPdbFile(PdbPath.get(), Allocator);
- if (!File)
- return File.takeError();
-
- Session = std::make_unique<NativeSession>(std::move(File.get()),
- std::move(Allocator));
-
- return Error::success();
-}
-
-Expected<std::string>
-NativeSession::searchForPdb(const PdbSearchOptions &Opts) {
- Expected<std::string> PathOrErr = getPdbPathFromExe(Opts.ExePath);
- if (!PathOrErr)
- return PathOrErr.takeError();
- StringRef PathFromExe = PathOrErr.get();
- sys::path::Style Style = PathFromExe.startswith("/")
- ? sys::path::Style::posix
- : sys::path::Style::windows;
- StringRef PdbName = sys::path::filename(PathFromExe, Style);
-
- // Check if pdb exists in the executable directory.
- SmallString<128> PdbPath = StringRef(Opts.ExePath);
- sys::path::remove_filename(PdbPath);
- sys::path::append(PdbPath, PdbName);
-
- auto Allocator = std::make_unique<BumpPtrAllocator>();
-
- if (auto File = loadPdbFile(PdbPath, Allocator))
- return std::string(PdbPath);
- else
- consumeError(File.takeError());
-
- // Check path that was in the executable.
- if (auto File = loadPdbFile(PathFromExe, Allocator))
- return std::string(PathFromExe);
- else
- return File.takeError();
-
- return make_error<RawError>("PDB not found");
-}
-
-uint64_t NativeSession::getLoadAddress() const { return LoadAddress; }
-
-bool NativeSession::setLoadAddress(uint64_t Address) {
- LoadAddress = Address;
- return true;
-}
-
-std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
- return PDBSymbol::createAs<PDBSymbolExe>(*this, getNativeGlobalScope());
-}
-
-std::unique_ptr<PDBSymbol>
-NativeSession::getSymbolById(SymIndexId SymbolId) const {
- return Cache.getSymbolById(SymbolId);
-}
-
-bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section,
- uint32_t &Offset) const {
- uint32_t RVA = VA - getLoadAddress();
- return addressForRVA(RVA, Section, Offset);
-}
-
-bool NativeSession::addressForRVA(uint32_t RVA, uint32_t &Section,
- uint32_t &Offset) const {
- Section = 0;
- Offset = 0;
-
- auto Dbi = Pdb->getPDBDbiStream();
- if (!Dbi)
- return false;
-
- if ((int32_t)RVA < 0)
- return true;
-
- Offset = RVA;
- for (; Section < Dbi->getSectionHeaders().size(); ++Section) {
- auto &Sec = Dbi->getSectionHeaders()[Section];
- if (RVA < Sec.VirtualAddress)
- return true;
- Offset = RVA - Sec.VirtualAddress;
- }
- return true;
-}
-
-std::unique_ptr<PDBSymbol>
-NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) {
- uint32_t Section;
- uint32_t Offset;
- addressForVA(Address, Section, Offset);
- return findSymbolBySectOffset(Section, Offset, Type);
-}
-
-std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
- PDB_SymType Type) {
- uint32_t Section;
- uint32_t Offset;
- addressForRVA(RVA, Section, Offset);
- return findSymbolBySectOffset(Section, Offset, Type);
-}
-
-std::unique_ptr<PDBSymbol>
-NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
- PDB_SymType Type) {
+
+NativeSession::~NativeSession() = default;
+
+Error NativeSession::createFromPdb(std::unique_ptr<MemoryBuffer> Buffer,
+ std::unique_ptr<IPDBSession> &Session) {
+ StringRef Path = Buffer->getBufferIdentifier();
+ auto Stream = std::make_unique<MemoryBufferByteStream>(
+ std::move(Buffer), llvm::support::little);
+
+ auto Allocator = std::make_unique<BumpPtrAllocator>();
+ auto File = std::make_unique<PDBFile>(Path, std::move(Stream), *Allocator);
+ if (auto EC = File->parseFileHeaders())
+ return EC;
+ if (auto EC = File->parseStreamData())
+ return EC;
+
+ Session =
+ std::make_unique<NativeSession>(std::move(File), std::move(Allocator));
+
+ return Error::success();
+}
+
+static Expected<std::unique_ptr<PDBFile>>
+loadPdbFile(StringRef PdbPath, std::unique_ptr<BumpPtrAllocator> &Allocator) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorOrBuffer =
+ MemoryBuffer::getFile(PdbPath, /*FileSize=*/-1,
+ /*RequiresNullTerminator=*/false);
+ if (!ErrorOrBuffer)
+ return make_error<RawError>(ErrorOrBuffer.getError());
+ std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(*ErrorOrBuffer);
+
+ PdbPath = Buffer->getBufferIdentifier();
+ file_magic Magic;
+ auto EC = identify_magic(PdbPath, Magic);
+ if (EC || Magic != file_magic::pdb)
+ return make_error<RawError>(EC);
+
+ auto Stream = std::make_unique<MemoryBufferByteStream>(std::move(Buffer),
+ llvm::support::little);
+
+ auto File = std::make_unique<PDBFile>(PdbPath, std::move(Stream), *Allocator);
+ if (auto EC = File->parseFileHeaders())
+ return std::move(EC);
+
+ if (auto EC = File->parseStreamData())
+ return std::move(EC);
+
+ return std::move(File);
+}
+
+Error NativeSession::createFromPdbPath(StringRef PdbPath,
+ std::unique_ptr<IPDBSession> &Session) {
+ auto Allocator = std::make_unique<BumpPtrAllocator>();
+ auto PdbFile = loadPdbFile(PdbPath, Allocator);
+ if (!PdbFile)
+ return PdbFile.takeError();
+
+ Session = std::make_unique<NativeSession>(std::move(PdbFile.get()),
+ std::move(Allocator));
+ return Error::success();
+}
+
+static Expected<std::string> getPdbPathFromExe(StringRef ExePath) {
+ Expected<object::OwningBinary<object::Binary>> BinaryFile =
+ object::createBinary(ExePath);
+ if (!BinaryFile)
+ return BinaryFile.takeError();
+
+ const object::COFFObjectFile *ObjFile =
+ dyn_cast<object::COFFObjectFile>(BinaryFile->getBinary());
+ if (!ObjFile)
+ return make_error<RawError>(raw_error_code::invalid_format);
+
+ StringRef PdbPath;
+ const llvm::codeview::DebugInfo *PdbInfo = nullptr;
+ if (Error E = ObjFile->getDebugPDBInfo(PdbInfo, PdbPath))
+ return std::move(E);
+
+ return std::string(PdbPath);
+}
+
+Error NativeSession::createFromExe(StringRef ExePath,
+ std::unique_ptr<IPDBSession> &Session) {
+ Expected<std::string> PdbPath = getPdbPathFromExe(ExePath);
+ if (!PdbPath)
+ return PdbPath.takeError();
+
+ file_magic Magic;
+ auto EC = identify_magic(PdbPath.get(), Magic);
+ if (EC || Magic != file_magic::pdb)
+ return make_error<RawError>(EC);
+
+ auto Allocator = std::make_unique<BumpPtrAllocator>();
+ auto File = loadPdbFile(PdbPath.get(), Allocator);
+ if (!File)
+ return File.takeError();
+
+ Session = std::make_unique<NativeSession>(std::move(File.get()),
+ std::move(Allocator));
+
+ return Error::success();
+}
+
+Expected<std::string>
+NativeSession::searchForPdb(const PdbSearchOptions &Opts) {
+ Expected<std::string> PathOrErr = getPdbPathFromExe(Opts.ExePath);
+ if (!PathOrErr)
+ return PathOrErr.takeError();
+ StringRef PathFromExe = PathOrErr.get();
+ sys::path::Style Style = PathFromExe.startswith("/")
+ ? sys::path::Style::posix
+ : sys::path::Style::windows;
+ StringRef PdbName = sys::path::filename(PathFromExe, Style);
+
+ // Check if pdb exists in the executable directory.
+ SmallString<128> PdbPath = StringRef(Opts.ExePath);
+ sys::path::remove_filename(PdbPath);
+ sys::path::append(PdbPath, PdbName);
+
+ auto Allocator = std::make_unique<BumpPtrAllocator>();
+
+ if (auto File = loadPdbFile(PdbPath, Allocator))
+ return std::string(PdbPath);
+ else
+ consumeError(File.takeError());
+
+ // Check path that was in the executable.
+ if (auto File = loadPdbFile(PathFromExe, Allocator))
+ return std::string(PathFromExe);
+ else
+ return File.takeError();
+
+ return make_error<RawError>("PDB not found");
+}
+
+uint64_t NativeSession::getLoadAddress() const { return LoadAddress; }
+
+bool NativeSession::setLoadAddress(uint64_t Address) {
+ LoadAddress = Address;
+ return true;
+}
+
+std::unique_ptr<PDBSymbolExe> NativeSession::getGlobalScope() {
+ return PDBSymbol::createAs<PDBSymbolExe>(*this, getNativeGlobalScope());
+}
+
+std::unique_ptr<PDBSymbol>
+NativeSession::getSymbolById(SymIndexId SymbolId) const {
+ return Cache.getSymbolById(SymbolId);
+}
+
+bool NativeSession::addressForVA(uint64_t VA, uint32_t &Section,
+ uint32_t &Offset) const {
+ uint32_t RVA = VA - getLoadAddress();
+ return addressForRVA(RVA, Section, Offset);
+}
+
+bool NativeSession::addressForRVA(uint32_t RVA, uint32_t &Section,
+ uint32_t &Offset) const {
+ Section = 0;
+ Offset = 0;
+
+ auto Dbi = Pdb->getPDBDbiStream();
+ if (!Dbi)
+ return false;
+
+ if ((int32_t)RVA < 0)
+ return true;
+
+ Offset = RVA;
+ for (; Section < Dbi->getSectionHeaders().size(); ++Section) {
+ auto &Sec = Dbi->getSectionHeaders()[Section];
+ if (RVA < Sec.VirtualAddress)
+ return true;
+ Offset = RVA - Sec.VirtualAddress;
+ }
+ return true;
+}
+
+std::unique_ptr<PDBSymbol>
+NativeSession::findSymbolByAddress(uint64_t Address, PDB_SymType Type) {
+ uint32_t Section;
+ uint32_t Offset;
+ addressForVA(Address, Section, Offset);
+ return findSymbolBySectOffset(Section, Offset, Type);
+}
+
+std::unique_ptr<PDBSymbol> NativeSession::findSymbolByRVA(uint32_t RVA,
+ PDB_SymType Type) {
+ uint32_t Section;
+ uint32_t Offset;
+ addressForRVA(RVA, Section, Offset);
+ return findSymbolBySectOffset(Section, Offset, Type);
+}
+
+std::unique_ptr<PDBSymbol>
+NativeSession::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
+ PDB_SymType Type) {
if (AddrToModuleIndex.empty())
parseSectionContribs();
- return Cache.findSymbolBySectOffset(Sect, Offset, Type);
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
- const IPDBSourceFile &File) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeSession::findLineNumbersByAddress(uint64_t Address,
- uint32_t Length) const {
- return Cache.findLineNumbersByVA(Address, Length);
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
+ return Cache.findSymbolBySectOffset(Sect, Offset, Type);
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeSession::findLineNumbers(const PDBSymbolCompiland &Compiland,
+ const IPDBSourceFile &File) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeSession::findLineNumbersByAddress(uint64_t Address,
+ uint32_t Length) const {
+ return Cache.findLineNumbersByVA(Address, Length);
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeSession::findLineNumbersByRVA(uint32_t RVA, uint32_t Length) const {
return Cache.findLineNumbersByVA(getLoadAddress() + RVA, Length);
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
- uint32_t Length) const {
- uint64_t VA = getVAFromSectOffset(Section, Offset);
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+NativeSession::findLineNumbersBySectOffset(uint32_t Section, uint32_t Offset,
+ uint32_t Length) const {
+ uint64_t VA = getVAFromSectOffset(Section, Offset);
return Cache.findLineNumbersByVA(VA, Length);
-}
-
-std::unique_ptr<IPDBEnumSourceFiles>
-NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
- StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBSourceFile>
-NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
- StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
-NativeSession::findCompilandsForSourceFile(StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<PDBSymbolCompiland>
-NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
- PDB_NameSearchFlags Flags) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
- const PDBSymbolCompiland &Compiland) const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBSourceFile>
-NativeSession::getSourceFileById(uint32_t FileId) const {
- return Cache.getSourceFileById(FileId);
-}
-
-std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumInjectedSources>
-NativeSession::getInjectedSources() const {
- auto ISS = Pdb->getInjectedSourceStream();
- if (!ISS) {
- consumeError(ISS.takeError());
- return nullptr;
- }
- auto Strings = Pdb->getStringTable();
- if (!Strings) {
- consumeError(Strings.takeError());
- return nullptr;
- }
- return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
-}
-
-std::unique_ptr<IPDBEnumSectionContribs>
-NativeSession::getSectionContribs() const {
- return nullptr;
-}
-
-std::unique_ptr<IPDBEnumFrameData>
-NativeSession::getFrameData() const {
- return nullptr;
-}
-
-void NativeSession::initializeExeSymbol() {
- if (ExeSymbol == 0)
- ExeSymbol = Cache.createSymbol<NativeExeSymbol>();
-}
-
-NativeExeSymbol &NativeSession::getNativeGlobalScope() const {
- const_cast<NativeSession &>(*this).initializeExeSymbol();
-
- return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);
-}
-
-uint32_t NativeSession::getRVAFromSectOffset(uint32_t Section,
- uint32_t Offset) const {
- if (Section <= 0)
- return 0;
-
- auto Dbi = getDbiStreamPtr(*Pdb);
- if (!Dbi)
- return 0;
-
- uint32_t MaxSection = Dbi->getSectionHeaders().size();
- if (Section > MaxSection + 1)
- Section = MaxSection + 1;
- auto &Sec = Dbi->getSectionHeaders()[Section - 1];
- return Sec.VirtualAddress + Offset;
-}
-
-uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
- uint32_t Offset) const {
- return LoadAddress + getRVAFromSectOffset(Section, Offset);
-}
+}
+
+std::unique_ptr<IPDBEnumSourceFiles>
+NativeSession::findSourceFiles(const PDBSymbolCompiland *Compiland,
+ StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBSourceFile>
+NativeSession::findOneSourceFile(const PDBSymbolCompiland *Compiland,
+ StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+NativeSession::findCompilandsForSourceFile(StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<PDBSymbolCompiland>
+NativeSession::findOneCompilandForSourceFile(StringRef Pattern,
+ PDB_NameSearchFlags Flags) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getAllSourceFiles() const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumSourceFiles> NativeSession::getSourceFilesForCompiland(
+ const PDBSymbolCompiland &Compiland) const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBSourceFile>
+NativeSession::getSourceFileById(uint32_t FileId) const {
+ return Cache.getSourceFileById(FileId);
+}
+
+std::unique_ptr<IPDBEnumDataStreams> NativeSession::getDebugStreams() const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumTables> NativeSession::getEnumTables() const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumInjectedSources>
+NativeSession::getInjectedSources() const {
+ auto ISS = Pdb->getInjectedSourceStream();
+ if (!ISS) {
+ consumeError(ISS.takeError());
+ return nullptr;
+ }
+ auto Strings = Pdb->getStringTable();
+ if (!Strings) {
+ consumeError(Strings.takeError());
+ return nullptr;
+ }
+ return std::make_unique<NativeEnumInjectedSources>(*Pdb, *ISS, *Strings);
+}
+
+std::unique_ptr<IPDBEnumSectionContribs>
+NativeSession::getSectionContribs() const {
+ return nullptr;
+}
+
+std::unique_ptr<IPDBEnumFrameData>
+NativeSession::getFrameData() const {
+ return nullptr;
+}
+
+void NativeSession::initializeExeSymbol() {
+ if (ExeSymbol == 0)
+ ExeSymbol = Cache.createSymbol<NativeExeSymbol>();
+}
+
+NativeExeSymbol &NativeSession::getNativeGlobalScope() const {
+ const_cast<NativeSession &>(*this).initializeExeSymbol();
+
+ return Cache.getNativeSymbolById<NativeExeSymbol>(ExeSymbol);
+}
+
+uint32_t NativeSession::getRVAFromSectOffset(uint32_t Section,
+ uint32_t Offset) const {
+ if (Section <= 0)
+ return 0;
+
+ auto Dbi = getDbiStreamPtr(*Pdb);
+ if (!Dbi)
+ return 0;
+
+ uint32_t MaxSection = Dbi->getSectionHeaders().size();
+ if (Section > MaxSection + 1)
+ Section = MaxSection + 1;
+ auto &Sec = Dbi->getSectionHeaders()[Section - 1];
+ return Sec.VirtualAddress + Offset;
+}
+
+uint64_t NativeSession::getVAFromSectOffset(uint32_t Section,
+ uint32_t Offset) const {
+ return LoadAddress + getRVAFromSectOffset(Section, Offset);
+}
bool NativeSession::moduleIndexForVA(uint64_t VA, uint16_t &ModuleIndex) const {
ModuleIndex = 0;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
index fd813dee6b..9ce65bbdd1 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSourceFile.cpp
@@ -1,47 +1,47 @@
//===- NativeSourceFile.cpp - Native line number implementation -*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeSourceFile.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-NativeSourceFile::NativeSourceFile(NativeSession &Session, uint32_t FileId,
- const codeview::FileChecksumEntry &Checksum)
- : Session(Session), FileId(FileId), Checksum(Checksum) {}
-
-std::string NativeSourceFile::getFileName() const {
- auto ST = Session.getPDBFile().getStringTable();
- if (!ST) {
- consumeError(ST.takeError());
- return "";
- }
- auto FileName = ST->getStringTable().getString(Checksum.FileNameOffset);
- if (!FileName) {
- consumeError(FileName.takeError());
- return "";
- }
-
- return std::string(FileName.get());
-}
-
-uint32_t NativeSourceFile::getUniqueId() const { return FileId; }
-
-std::string NativeSourceFile::getChecksum() const {
- return toStringRef(Checksum.Checksum).str();
-}
-
-PDB_Checksum NativeSourceFile::getChecksumType() const {
- return static_cast<PDB_Checksum>(Checksum.Kind);
-}
-
-std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
-NativeSourceFile::getCompilands() const {
- return nullptr;
-}
+//
+// 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/NativeSourceFile.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+NativeSourceFile::NativeSourceFile(NativeSession &Session, uint32_t FileId,
+ const codeview::FileChecksumEntry &Checksum)
+ : Session(Session), FileId(FileId), Checksum(Checksum) {}
+
+std::string NativeSourceFile::getFileName() const {
+ auto ST = Session.getPDBFile().getStringTable();
+ if (!ST) {
+ consumeError(ST.takeError());
+ return "";
+ }
+ auto FileName = ST->getStringTable().getString(Checksum.FileNameOffset);
+ if (!FileName) {
+ consumeError(FileName.takeError());
+ return "";
+ }
+
+ return std::string(FileName.get());
+}
+
+uint32_t NativeSourceFile::getUniqueId() const { return FileId; }
+
+std::string NativeSourceFile::getChecksum() const {
+ return toStringRef(Checksum.Checksum).str();
+}
+
+PDB_Checksum NativeSourceFile::getChecksumType() const {
+ return static_cast<PDB_Checksum>(Checksum.Kind);
+}
+
+std::unique_ptr<IPDBEnumChildren<PDBSymbolCompiland>>
+NativeSourceFile::getCompilands() const {
+ return nullptr;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
index e5f1dcaf80..1d262b506c 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeSymbolEnumerator.cpp
@@ -1,124 +1,124 @@
-//===- NativeSymbolEnumerator.cpp - info about enumerators ------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
-
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeSymbolEnumerator::NativeSymbolEnumerator(
- NativeSession &Session, SymIndexId Id, const NativeTypeEnum &Parent,
- codeview::EnumeratorRecord Record)
- : NativeRawSymbol(Session, PDB_SymType::Data, Id), Parent(Parent),
- Record(std::move(Record)) {}
-
-NativeSymbolEnumerator::~NativeSymbolEnumerator() {}
-
-void NativeSymbolEnumerator::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
- dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session,
- PdbSymbolIdField::ClassParent, ShowIdFields,
- RecurseIdFields);
- dumpSymbolIdField(OS, "lexicalParentId", getLexicalParentId(), Indent,
- Session, PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
- dumpSymbolField(OS, "name", getName(), Indent);
- dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
- PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
- dumpSymbolField(OS, "dataKind", getDataKind(), Indent);
- dumpSymbolField(OS, "locationType", getLocationType(), Indent);
- dumpSymbolField(OS, "constType", isConstType(), Indent);
- dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
- dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
- dumpSymbolField(OS, "value", getValue(), Indent);
-}
-
-SymIndexId NativeSymbolEnumerator::getClassParentId() const {
- return Parent.getSymIndexId();
-}
-
-SymIndexId NativeSymbolEnumerator::getLexicalParentId() const { return 0; }
-
-std::string NativeSymbolEnumerator::getName() const {
- return std::string(Record.Name);
-}
-
-SymIndexId NativeSymbolEnumerator::getTypeId() const {
- return Parent.getTypeId();
-}
-
-PDB_DataKind NativeSymbolEnumerator::getDataKind() const {
- return PDB_DataKind::Constant;
-}
-
-PDB_LocType NativeSymbolEnumerator::getLocationType() const {
- return PDB_LocType::Constant;
-}
-
-bool NativeSymbolEnumerator::isConstType() const { return false; }
-
-bool NativeSymbolEnumerator::isVolatileType() const { return false; }
-
-bool NativeSymbolEnumerator::isUnalignedType() const { return false; }
-
-Variant NativeSymbolEnumerator::getValue() const {
- const NativeTypeBuiltin &BT = Parent.getUnderlyingBuiltinType();
-
- switch (BT.getBuiltinType()) {
- case PDB_BuiltinType::Int:
- case PDB_BuiltinType::Long:
- case PDB_BuiltinType::Char: {
- assert(Record.Value.isSignedIntN(BT.getLength() * 8));
- int64_t N = Record.Value.getSExtValue();
- switch (BT.getLength()) {
- case 1:
- return Variant{static_cast<int8_t>(N)};
- case 2:
- return Variant{static_cast<int16_t>(N)};
- case 4:
- return Variant{static_cast<int32_t>(N)};
- case 8:
- return Variant{static_cast<int64_t>(N)};
- }
- break;
- }
- case PDB_BuiltinType::UInt:
- case PDB_BuiltinType::ULong: {
- assert(Record.Value.isIntN(BT.getLength() * 8));
- uint64_t U = Record.Value.getZExtValue();
- switch (BT.getLength()) {
- case 1:
- return Variant{static_cast<uint8_t>(U)};
- case 2:
- return Variant{static_cast<uint16_t>(U)};
- case 4:
- return Variant{static_cast<uint32_t>(U)};
- case 8:
- return Variant{static_cast<uint64_t>(U)};
- }
- break;
- }
- case PDB_BuiltinType::Bool: {
- assert(Record.Value.isIntN(BT.getLength() * 8));
- uint64_t U = Record.Value.getZExtValue();
- return Variant{static_cast<bool>(U)};
- }
- default:
- assert(false && "Invalid enumeration type");
- break;
- }
-
- return Variant{Record.Value.getSExtValue()};
-}
+//===- NativeSymbolEnumerator.cpp - info about enumerators ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeSymbolEnumerator::NativeSymbolEnumerator(
+ NativeSession &Session, SymIndexId Id, const NativeTypeEnum &Parent,
+ codeview::EnumeratorRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::Data, Id), Parent(Parent),
+ Record(std::move(Record)) {}
+
+NativeSymbolEnumerator::~NativeSymbolEnumerator() {}
+
+void NativeSymbolEnumerator::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session,
+ PdbSymbolIdField::ClassParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolIdField(OS, "lexicalParentId", getLexicalParentId(), Indent,
+ Session, PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "dataKind", getDataKind(), Indent);
+ dumpSymbolField(OS, "locationType", getLocationType(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+ dumpSymbolField(OS, "value", getValue(), Indent);
+}
+
+SymIndexId NativeSymbolEnumerator::getClassParentId() const {
+ return Parent.getSymIndexId();
+}
+
+SymIndexId NativeSymbolEnumerator::getLexicalParentId() const { return 0; }
+
+std::string NativeSymbolEnumerator::getName() const {
+ return std::string(Record.Name);
+}
+
+SymIndexId NativeSymbolEnumerator::getTypeId() const {
+ return Parent.getTypeId();
+}
+
+PDB_DataKind NativeSymbolEnumerator::getDataKind() const {
+ return PDB_DataKind::Constant;
+}
+
+PDB_LocType NativeSymbolEnumerator::getLocationType() const {
+ return PDB_LocType::Constant;
+}
+
+bool NativeSymbolEnumerator::isConstType() const { return false; }
+
+bool NativeSymbolEnumerator::isVolatileType() const { return false; }
+
+bool NativeSymbolEnumerator::isUnalignedType() const { return false; }
+
+Variant NativeSymbolEnumerator::getValue() const {
+ const NativeTypeBuiltin &BT = Parent.getUnderlyingBuiltinType();
+
+ switch (BT.getBuiltinType()) {
+ case PDB_BuiltinType::Int:
+ case PDB_BuiltinType::Long:
+ case PDB_BuiltinType::Char: {
+ assert(Record.Value.isSignedIntN(BT.getLength() * 8));
+ int64_t N = Record.Value.getSExtValue();
+ switch (BT.getLength()) {
+ case 1:
+ return Variant{static_cast<int8_t>(N)};
+ case 2:
+ return Variant{static_cast<int16_t>(N)};
+ case 4:
+ return Variant{static_cast<int32_t>(N)};
+ case 8:
+ return Variant{static_cast<int64_t>(N)};
+ }
+ break;
+ }
+ case PDB_BuiltinType::UInt:
+ case PDB_BuiltinType::ULong: {
+ assert(Record.Value.isIntN(BT.getLength() * 8));
+ uint64_t U = Record.Value.getZExtValue();
+ switch (BT.getLength()) {
+ case 1:
+ return Variant{static_cast<uint8_t>(U)};
+ case 2:
+ return Variant{static_cast<uint16_t>(U)};
+ case 4:
+ return Variant{static_cast<uint32_t>(U)};
+ case 8:
+ return Variant{static_cast<uint64_t>(U)};
+ }
+ break;
+ }
+ case PDB_BuiltinType::Bool: {
+ assert(Record.Value.isIntN(BT.getLength() * 8));
+ uint64_t U = Record.Value.getZExtValue();
+ return Variant{static_cast<bool>(U)};
+ }
+ default:
+ assert(false && "Invalid enumeration type");
+ break;
+ }
+
+ return Variant{Record.Value.getSExtValue()};
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
index 63ac9fae0e..a8e7ac2e8d 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeArray.cpp
@@ -1,66 +1,66 @@
-//===- NativeTypeArray.cpp - info about arrays ------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
-
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeTypeArray::NativeTypeArray(NativeSession &Session, SymIndexId Id,
- codeview::TypeIndex TI,
- codeview::ArrayRecord Record)
- : NativeRawSymbol(Session, PDB_SymType::ArrayType, Id), Record(Record),
- Index(TI) {}
-NativeTypeArray::~NativeTypeArray() {}
-
-void NativeTypeArray::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- dumpSymbolField(OS, "arrayIndexTypeId", getArrayIndexTypeId(), Indent);
- dumpSymbolIdField(OS, "elementTypeId", getTypeId(), Indent, Session,
- PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
-
- dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
- PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
- dumpSymbolField(OS, "length", getLength(), Indent);
- dumpSymbolField(OS, "count", getCount(), Indent);
- dumpSymbolField(OS, "constType", isConstType(), Indent);
- dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
- dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
-}
-
-SymIndexId NativeTypeArray::getArrayIndexTypeId() const {
- return Session.getSymbolCache().findSymbolByTypeIndex(Record.getIndexType());
-}
-
-bool NativeTypeArray::isConstType() const { return false; }
-
-bool NativeTypeArray::isUnalignedType() const { return false; }
-
-bool NativeTypeArray::isVolatileType() const { return false; }
-
-uint32_t NativeTypeArray::getCount() const {
- NativeRawSymbol &Element =
- Session.getSymbolCache().getNativeSymbolById(getTypeId());
- return getLength() / Element.getLength();
-}
-
-SymIndexId NativeTypeArray::getTypeId() const {
- return Session.getSymbolCache().findSymbolByTypeIndex(
- Record.getElementType());
-}
-
-uint64_t NativeTypeArray::getLength() const { return Record.Size; }
+//===- NativeTypeArray.cpp - info about arrays ------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
+
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeArray::NativeTypeArray(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI,
+ codeview::ArrayRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::ArrayType, Id), Record(Record),
+ Index(TI) {}
+NativeTypeArray::~NativeTypeArray() {}
+
+void NativeTypeArray::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolField(OS, "arrayIndexTypeId", getArrayIndexTypeId(), Indent);
+ dumpSymbolIdField(OS, "elementTypeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "count", getCount(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+SymIndexId NativeTypeArray::getArrayIndexTypeId() const {
+ return Session.getSymbolCache().findSymbolByTypeIndex(Record.getIndexType());
+}
+
+bool NativeTypeArray::isConstType() const { return false; }
+
+bool NativeTypeArray::isUnalignedType() const { return false; }
+
+bool NativeTypeArray::isVolatileType() const { return false; }
+
+uint32_t NativeTypeArray::getCount() const {
+ NativeRawSymbol &Element =
+ Session.getSymbolCache().getNativeSymbolById(getTypeId());
+ return getLength() / Element.getLength();
+}
+
+SymIndexId NativeTypeArray::getTypeId() const {
+ return Session.getSymbolCache().findSymbolByTypeIndex(
+ Record.getElementType());
+}
+
+uint64_t NativeTypeArray::getLength() const { return Record.Size; }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
index a08663aa91..533a5ab254 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeBuiltin.cpp
@@ -1,46 +1,46 @@
-//===- NativeTypeBuiltin.cpp -------------------------------------- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/Support/FormatVariadic.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeTypeBuiltin::NativeTypeBuiltin(NativeSession &PDBSession, SymIndexId Id,
- ModifierOptions Mods, PDB_BuiltinType T,
- uint64_t L)
- : NativeRawSymbol(PDBSession, PDB_SymType::BuiltinType, Id),
- Session(PDBSession), Mods(Mods), Type(T), Length(L) {}
-
-NativeTypeBuiltin::~NativeTypeBuiltin() {}
-
-void NativeTypeBuiltin::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {}
-
-PDB_SymType NativeTypeBuiltin::getSymTag() const {
- return PDB_SymType::BuiltinType;
-}
-
-PDB_BuiltinType NativeTypeBuiltin::getBuiltinType() const { return Type; }
-
-bool NativeTypeBuiltin::isConstType() const {
- return (Mods & ModifierOptions::Const) != ModifierOptions::None;
-}
-
-uint64_t NativeTypeBuiltin::getLength() const { return Length; }
-
-bool NativeTypeBuiltin::isUnalignedType() const {
- return (Mods & ModifierOptions::Unaligned) != ModifierOptions::None;
-}
-
-bool NativeTypeBuiltin::isVolatileType() const {
- return (Mods & ModifierOptions::Volatile) != ModifierOptions::None;
-}
+//===- NativeTypeBuiltin.cpp -------------------------------------- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeBuiltin::NativeTypeBuiltin(NativeSession &PDBSession, SymIndexId Id,
+ ModifierOptions Mods, PDB_BuiltinType T,
+ uint64_t L)
+ : NativeRawSymbol(PDBSession, PDB_SymType::BuiltinType, Id),
+ Session(PDBSession), Mods(Mods), Type(T), Length(L) {}
+
+NativeTypeBuiltin::~NativeTypeBuiltin() {}
+
+void NativeTypeBuiltin::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {}
+
+PDB_SymType NativeTypeBuiltin::getSymTag() const {
+ return PDB_SymType::BuiltinType;
+}
+
+PDB_BuiltinType NativeTypeBuiltin::getBuiltinType() const { return Type; }
+
+bool NativeTypeBuiltin::isConstType() const {
+ return (Mods & ModifierOptions::Const) != ModifierOptions::None;
+}
+
+uint64_t NativeTypeBuiltin::getLength() const { return Length; }
+
+bool NativeTypeBuiltin::isUnalignedType() const {
+ return (Mods & ModifierOptions::Unaligned) != ModifierOptions::None;
+}
+
+bool NativeTypeBuiltin::isVolatileType() const {
+ return (Mods & ModifierOptions::Volatile) != ModifierOptions::None;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
index aaec3a5e7c..15816cf604 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeEnum.cpp
@@ -1,381 +1,381 @@
-//===- NativeTypeEnum.cpp - info about enum type ----------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-
-#include "llvm/Support/FormatVariadic.h"
-
-#include <cassert>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-namespace {
-// Yea, this is a pretty terrible class name. But if we have an enum:
-//
-// enum Foo {
-// A,
-// B
-// };
-//
-// then A and B are the "enumerators" of the "enum" Foo. And we need
-// to enumerate them.
-class NativeEnumEnumEnumerators : public IPDBEnumSymbols, TypeVisitorCallbacks {
-public:
- NativeEnumEnumEnumerators(NativeSession &Session,
- const NativeTypeEnum &ClassParent);
-
- uint32_t getChildCount() const override;
- std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
- std::unique_ptr<PDBSymbol> getNext() override;
- void reset() override;
-
-private:
- Error visitKnownMember(CVMemberRecord &CVM,
- EnumeratorRecord &Record) override;
- Error visitKnownMember(CVMemberRecord &CVM,
- ListContinuationRecord &Record) override;
-
- NativeSession &Session;
- const NativeTypeEnum &ClassParent;
- std::vector<EnumeratorRecord> Enumerators;
- Optional<TypeIndex> ContinuationIndex;
- uint32_t Index = 0;
-};
-} // namespace
-
-NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
- NativeSession &Session, const NativeTypeEnum &ClassParent)
- : Session(Session), ClassParent(ClassParent) {
- TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
- LazyRandomTypeCollection &Types = Tpi.typeCollection();
-
- ContinuationIndex = ClassParent.getEnumRecord().FieldList;
- while (ContinuationIndex) {
- CVType FieldList = Types.getType(*ContinuationIndex);
- assert(FieldList.kind() == LF_FIELDLIST);
- ContinuationIndex.reset();
- cantFail(visitMemberRecordStream(FieldList.data(), *this));
- }
-}
-
-Error NativeEnumEnumEnumerators::visitKnownMember(CVMemberRecord &CVM,
- EnumeratorRecord &Record) {
- Enumerators.push_back(Record);
- return Error::success();
-}
-
-Error NativeEnumEnumEnumerators::visitKnownMember(
- CVMemberRecord &CVM, ListContinuationRecord &Record) {
- ContinuationIndex = Record.ContinuationIndex;
- return Error::success();
-}
-
-uint32_t NativeEnumEnumEnumerators::getChildCount() const {
- return Enumerators.size();
-}
-
-std::unique_ptr<PDBSymbol>
-NativeEnumEnumEnumerators::getChildAtIndex(uint32_t Index) const {
- if (Index >= getChildCount())
- return nullptr;
-
- SymIndexId Id = Session.getSymbolCache()
- .getOrCreateFieldListMember<NativeSymbolEnumerator>(
- ClassParent.getEnumRecord().FieldList, Index,
- ClassParent, Enumerators[Index]);
- return Session.getSymbolCache().getSymbolById(Id);
-}
-
-std::unique_ptr<PDBSymbol> NativeEnumEnumEnumerators::getNext() {
- if (Index >= getChildCount())
- return nullptr;
-
- return getChildAtIndex(Index++);
-}
-
-void NativeEnumEnumEnumerators::reset() { Index = 0; }
-
-NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
- TypeIndex Index, EnumRecord Record)
- : NativeRawSymbol(Session, PDB_SymType::Enum, Id), Index(Index),
- Record(std::move(Record)) {}
-
-NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
- NativeTypeEnum &UnmodifiedType,
- codeview::ModifierRecord Modifier)
- : NativeRawSymbol(Session, PDB_SymType::Enum, Id),
- UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
-
-NativeTypeEnum::~NativeTypeEnum() {}
-
-void NativeTypeEnum::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- dumpSymbolField(OS, "baseType", static_cast<uint32_t>(getBuiltinType()),
- Indent);
- dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
- PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
- dumpSymbolField(OS, "name", getName(), Indent);
- dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
- PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
- if (Modifiers.hasValue())
- dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
- Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
- RecurseIdFields);
- dumpSymbolField(OS, "length", getLength(), Indent);
- dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
- dumpSymbolField(OS, "constType", isConstType(), Indent);
- dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
- dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
- dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
- dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
- dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
- dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
- dumpSymbolField(OS, "nested", isNested(), Indent);
- dumpSymbolField(OS, "packed", isPacked(), Indent);
- dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
- dumpSymbolField(OS, "scoped", isScoped(), Indent);
- dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
- dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
- dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeTypeEnum::findChildren(PDB_SymType Type) const {
- if (Type != PDB_SymType::Data)
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-
- const NativeTypeEnum *ClassParent = nullptr;
- if (!Modifiers)
- ClassParent = this;
- else
- ClassParent = UnmodifiedType;
- return std::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
-}
-
-PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
-
-PDB_BuiltinType NativeTypeEnum::getBuiltinType() const {
- if (UnmodifiedType)
- return UnmodifiedType->getBuiltinType();
-
- Session.getSymbolCache().findSymbolByTypeIndex(Record->getUnderlyingType());
-
- codeview::TypeIndex Underlying = Record->getUnderlyingType();
-
- // This indicates a corrupt record.
- if (!Underlying.isSimple() ||
- Underlying.getSimpleMode() != SimpleTypeMode::Direct) {
- return PDB_BuiltinType::None;
- }
-
- switch (Underlying.getSimpleKind()) {
- case SimpleTypeKind::Boolean128:
- case SimpleTypeKind::Boolean64:
- case SimpleTypeKind::Boolean32:
- case SimpleTypeKind::Boolean16:
- case SimpleTypeKind::Boolean8:
- return PDB_BuiltinType::Bool;
- case SimpleTypeKind::NarrowCharacter:
- case SimpleTypeKind::UnsignedCharacter:
- case SimpleTypeKind::SignedCharacter:
- return PDB_BuiltinType::Char;
- case SimpleTypeKind::WideCharacter:
- return PDB_BuiltinType::WCharT;
- case SimpleTypeKind::Character16:
- return PDB_BuiltinType::Char16;
- case SimpleTypeKind::Character32:
- return PDB_BuiltinType::Char32;
- case SimpleTypeKind::Int128:
- case SimpleTypeKind::Int128Oct:
- case SimpleTypeKind::Int16:
- case SimpleTypeKind::Int16Short:
- case SimpleTypeKind::Int32:
- case SimpleTypeKind::Int32Long:
- case SimpleTypeKind::Int64:
- case SimpleTypeKind::Int64Quad:
- return PDB_BuiltinType::Int;
- case SimpleTypeKind::UInt128:
- case SimpleTypeKind::UInt128Oct:
- case SimpleTypeKind::UInt16:
- case SimpleTypeKind::UInt16Short:
- case SimpleTypeKind::UInt32:
- case SimpleTypeKind::UInt32Long:
- case SimpleTypeKind::UInt64:
- case SimpleTypeKind::UInt64Quad:
- return PDB_BuiltinType::UInt;
- case SimpleTypeKind::HResult:
- return PDB_BuiltinType::HResult;
- case SimpleTypeKind::Complex16:
- case SimpleTypeKind::Complex32:
- case SimpleTypeKind::Complex32PartialPrecision:
- case SimpleTypeKind::Complex64:
- case SimpleTypeKind::Complex80:
- case SimpleTypeKind::Complex128:
- return PDB_BuiltinType::Complex;
- case SimpleTypeKind::Float16:
- case SimpleTypeKind::Float32:
- case SimpleTypeKind::Float32PartialPrecision:
- case SimpleTypeKind::Float48:
- case SimpleTypeKind::Float64:
- case SimpleTypeKind::Float80:
- case SimpleTypeKind::Float128:
- return PDB_BuiltinType::Float;
- default:
- return PDB_BuiltinType::None;
- }
- llvm_unreachable("Unreachable");
-}
-
-SymIndexId NativeTypeEnum::getUnmodifiedTypeId() const {
- return UnmodifiedType ? UnmodifiedType->getSymIndexId() : 0;
-}
-
-bool NativeTypeEnum::hasConstructor() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasConstructor();
-
- return bool(Record->getOptions() &
- codeview::ClassOptions::HasConstructorOrDestructor);
-}
-
-bool NativeTypeEnum::hasAssignmentOperator() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasAssignmentOperator();
-
- return bool(Record->getOptions() &
- codeview::ClassOptions::HasOverloadedAssignmentOperator);
-}
-
-bool NativeTypeEnum::hasNestedTypes() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasNestedTypes();
-
- return bool(Record->getOptions() &
- codeview::ClassOptions::ContainsNestedClass);
-}
-
-bool NativeTypeEnum::isIntrinsic() const {
- if (UnmodifiedType)
- return UnmodifiedType->isIntrinsic();
-
- return bool(Record->getOptions() & codeview::ClassOptions::Intrinsic);
-}
-
-bool NativeTypeEnum::hasCastOperator() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasCastOperator();
-
- return bool(Record->getOptions() &
- codeview::ClassOptions::HasConversionOperator);
-}
-
-uint64_t NativeTypeEnum::getLength() const {
- if (UnmodifiedType)
- return UnmodifiedType->getLength();
-
- const auto Id = Session.getSymbolCache().findSymbolByTypeIndex(
- Record->getUnderlyingType());
- const auto UnderlyingType =
- Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id);
- return UnderlyingType ? UnderlyingType->getLength() : 0;
-}
-
-std::string NativeTypeEnum::getName() const {
- if (UnmodifiedType)
- return UnmodifiedType->getName();
-
- return std::string(Record->getName());
-}
-
-bool NativeTypeEnum::isNested() const {
- if (UnmodifiedType)
- return UnmodifiedType->isNested();
-
- return bool(Record->getOptions() & codeview::ClassOptions::Nested);
-}
-
-bool NativeTypeEnum::hasOverloadedOperator() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasOverloadedOperator();
-
- return bool(Record->getOptions() &
- codeview::ClassOptions::HasOverloadedOperator);
-}
-
-bool NativeTypeEnum::isPacked() const {
- if (UnmodifiedType)
- return UnmodifiedType->isPacked();
-
- return bool(Record->getOptions() & codeview::ClassOptions::Packed);
-}
-
-bool NativeTypeEnum::isScoped() const {
- if (UnmodifiedType)
- return UnmodifiedType->isScoped();
-
- return bool(Record->getOptions() & codeview::ClassOptions::Scoped);
-}
-
-SymIndexId NativeTypeEnum::getTypeId() const {
- if (UnmodifiedType)
- return UnmodifiedType->getTypeId();
-
- return Session.getSymbolCache().findSymbolByTypeIndex(
- Record->getUnderlyingType());
-}
-
-bool NativeTypeEnum::isRefUdt() const { return false; }
-
-bool NativeTypeEnum::isValueUdt() const { return false; }
-
-bool NativeTypeEnum::isInterfaceUdt() const { return false; }
-
-bool NativeTypeEnum::isConstType() const {
- if (!Modifiers)
- return false;
- return ((Modifiers->getModifiers() & ModifierOptions::Const) !=
- ModifierOptions::None);
-}
-
-bool NativeTypeEnum::isVolatileType() const {
- if (!Modifiers)
- return false;
- return ((Modifiers->getModifiers() & ModifierOptions::Volatile) !=
- ModifierOptions::None);
-}
-
-bool NativeTypeEnum::isUnalignedType() const {
- if (!Modifiers)
- return false;
- return ((Modifiers->getModifiers() & ModifierOptions::Unaligned) !=
- ModifierOptions::None);
-}
-
-const NativeTypeBuiltin &NativeTypeEnum::getUnderlyingBuiltinType() const {
- if (UnmodifiedType)
- return UnmodifiedType->getUnderlyingBuiltinType();
-
- return Session.getSymbolCache().getNativeSymbolById<NativeTypeBuiltin>(
- getTypeId());
-}
+//===- NativeTypeEnum.cpp - info about enum type ----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+
+#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+
+#include "llvm/Support/FormatVariadic.h"
+
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+namespace {
+// Yea, this is a pretty terrible class name. But if we have an enum:
+//
+// enum Foo {
+// A,
+// B
+// };
+//
+// then A and B are the "enumerators" of the "enum" Foo. And we need
+// to enumerate them.
+class NativeEnumEnumEnumerators : public IPDBEnumSymbols, TypeVisitorCallbacks {
+public:
+ NativeEnumEnumEnumerators(NativeSession &Session,
+ const NativeTypeEnum &ClassParent);
+
+ uint32_t getChildCount() const override;
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override;
+ std::unique_ptr<PDBSymbol> getNext() override;
+ void reset() override;
+
+private:
+ Error visitKnownMember(CVMemberRecord &CVM,
+ EnumeratorRecord &Record) override;
+ Error visitKnownMember(CVMemberRecord &CVM,
+ ListContinuationRecord &Record) override;
+
+ NativeSession &Session;
+ const NativeTypeEnum &ClassParent;
+ std::vector<EnumeratorRecord> Enumerators;
+ Optional<TypeIndex> ContinuationIndex;
+ uint32_t Index = 0;
+};
+} // namespace
+
+NativeEnumEnumEnumerators::NativeEnumEnumEnumerators(
+ NativeSession &Session, const NativeTypeEnum &ClassParent)
+ : Session(Session), ClassParent(ClassParent) {
+ TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
+ LazyRandomTypeCollection &Types = Tpi.typeCollection();
+
+ ContinuationIndex = ClassParent.getEnumRecord().FieldList;
+ while (ContinuationIndex) {
+ CVType FieldList = Types.getType(*ContinuationIndex);
+ assert(FieldList.kind() == LF_FIELDLIST);
+ ContinuationIndex.reset();
+ cantFail(visitMemberRecordStream(FieldList.data(), *this));
+ }
+}
+
+Error NativeEnumEnumEnumerators::visitKnownMember(CVMemberRecord &CVM,
+ EnumeratorRecord &Record) {
+ Enumerators.push_back(Record);
+ return Error::success();
+}
+
+Error NativeEnumEnumEnumerators::visitKnownMember(
+ CVMemberRecord &CVM, ListContinuationRecord &Record) {
+ ContinuationIndex = Record.ContinuationIndex;
+ return Error::success();
+}
+
+uint32_t NativeEnumEnumEnumerators::getChildCount() const {
+ return Enumerators.size();
+}
+
+std::unique_ptr<PDBSymbol>
+NativeEnumEnumEnumerators::getChildAtIndex(uint32_t Index) const {
+ if (Index >= getChildCount())
+ return nullptr;
+
+ SymIndexId Id = Session.getSymbolCache()
+ .getOrCreateFieldListMember<NativeSymbolEnumerator>(
+ ClassParent.getEnumRecord().FieldList, Index,
+ ClassParent, Enumerators[Index]);
+ return Session.getSymbolCache().getSymbolById(Id);
+}
+
+std::unique_ptr<PDBSymbol> NativeEnumEnumEnumerators::getNext() {
+ if (Index >= getChildCount())
+ return nullptr;
+
+ return getChildAtIndex(Index++);
+}
+
+void NativeEnumEnumEnumerators::reset() { Index = 0; }
+
+NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
+ TypeIndex Index, EnumRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::Enum, Id), Index(Index),
+ Record(std::move(Record)) {}
+
+NativeTypeEnum::NativeTypeEnum(NativeSession &Session, SymIndexId Id,
+ NativeTypeEnum &UnmodifiedType,
+ codeview::ModifierRecord Modifier)
+ : NativeRawSymbol(Session, PDB_SymType::Enum, Id),
+ UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
+
+NativeTypeEnum::~NativeTypeEnum() {}
+
+void NativeTypeEnum::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolField(OS, "baseType", static_cast<uint32_t>(getBuiltinType()),
+ Indent);
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ if (Modifiers.hasValue())
+ dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
+ Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
+ dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
+ dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
+ dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
+ dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
+ dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
+ dumpSymbolField(OS, "nested", isNested(), Indent);
+ dumpSymbolField(OS, "packed", isPacked(), Indent);
+ dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
+ dumpSymbolField(OS, "scoped", isScoped(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeTypeEnum::findChildren(PDB_SymType Type) const {
+ if (Type != PDB_SymType::Data)
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+
+ const NativeTypeEnum *ClassParent = nullptr;
+ if (!Modifiers)
+ ClassParent = this;
+ else
+ ClassParent = UnmodifiedType;
+ return std::make_unique<NativeEnumEnumEnumerators>(Session, *ClassParent);
+}
+
+PDB_SymType NativeTypeEnum::getSymTag() const { return PDB_SymType::Enum; }
+
+PDB_BuiltinType NativeTypeEnum::getBuiltinType() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getBuiltinType();
+
+ Session.getSymbolCache().findSymbolByTypeIndex(Record->getUnderlyingType());
+
+ codeview::TypeIndex Underlying = Record->getUnderlyingType();
+
+ // This indicates a corrupt record.
+ if (!Underlying.isSimple() ||
+ Underlying.getSimpleMode() != SimpleTypeMode::Direct) {
+ return PDB_BuiltinType::None;
+ }
+
+ switch (Underlying.getSimpleKind()) {
+ case SimpleTypeKind::Boolean128:
+ case SimpleTypeKind::Boolean64:
+ case SimpleTypeKind::Boolean32:
+ case SimpleTypeKind::Boolean16:
+ case SimpleTypeKind::Boolean8:
+ return PDB_BuiltinType::Bool;
+ case SimpleTypeKind::NarrowCharacter:
+ case SimpleTypeKind::UnsignedCharacter:
+ case SimpleTypeKind::SignedCharacter:
+ return PDB_BuiltinType::Char;
+ case SimpleTypeKind::WideCharacter:
+ return PDB_BuiltinType::WCharT;
+ case SimpleTypeKind::Character16:
+ return PDB_BuiltinType::Char16;
+ case SimpleTypeKind::Character32:
+ return PDB_BuiltinType::Char32;
+ case SimpleTypeKind::Int128:
+ case SimpleTypeKind::Int128Oct:
+ case SimpleTypeKind::Int16:
+ case SimpleTypeKind::Int16Short:
+ case SimpleTypeKind::Int32:
+ case SimpleTypeKind::Int32Long:
+ case SimpleTypeKind::Int64:
+ case SimpleTypeKind::Int64Quad:
+ return PDB_BuiltinType::Int;
+ case SimpleTypeKind::UInt128:
+ case SimpleTypeKind::UInt128Oct:
+ case SimpleTypeKind::UInt16:
+ case SimpleTypeKind::UInt16Short:
+ case SimpleTypeKind::UInt32:
+ case SimpleTypeKind::UInt32Long:
+ case SimpleTypeKind::UInt64:
+ case SimpleTypeKind::UInt64Quad:
+ return PDB_BuiltinType::UInt;
+ case SimpleTypeKind::HResult:
+ return PDB_BuiltinType::HResult;
+ case SimpleTypeKind::Complex16:
+ case SimpleTypeKind::Complex32:
+ case SimpleTypeKind::Complex32PartialPrecision:
+ case SimpleTypeKind::Complex64:
+ case SimpleTypeKind::Complex80:
+ case SimpleTypeKind::Complex128:
+ return PDB_BuiltinType::Complex;
+ case SimpleTypeKind::Float16:
+ case SimpleTypeKind::Float32:
+ case SimpleTypeKind::Float32PartialPrecision:
+ case SimpleTypeKind::Float48:
+ case SimpleTypeKind::Float64:
+ case SimpleTypeKind::Float80:
+ case SimpleTypeKind::Float128:
+ return PDB_BuiltinType::Float;
+ default:
+ return PDB_BuiltinType::None;
+ }
+ llvm_unreachable("Unreachable");
+}
+
+SymIndexId NativeTypeEnum::getUnmodifiedTypeId() const {
+ return UnmodifiedType ? UnmodifiedType->getSymIndexId() : 0;
+}
+
+bool NativeTypeEnum::hasConstructor() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasConstructor();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasConstructorOrDestructor);
+}
+
+bool NativeTypeEnum::hasAssignmentOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasAssignmentOperator();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasOverloadedAssignmentOperator);
+}
+
+bool NativeTypeEnum::hasNestedTypes() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasNestedTypes();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::ContainsNestedClass);
+}
+
+bool NativeTypeEnum::isIntrinsic() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isIntrinsic();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Intrinsic);
+}
+
+bool NativeTypeEnum::hasCastOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasCastOperator();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasConversionOperator);
+}
+
+uint64_t NativeTypeEnum::getLength() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getLength();
+
+ const auto Id = Session.getSymbolCache().findSymbolByTypeIndex(
+ Record->getUnderlyingType());
+ const auto UnderlyingType =
+ Session.getConcreteSymbolById<PDBSymbolTypeBuiltin>(Id);
+ return UnderlyingType ? UnderlyingType->getLength() : 0;
+}
+
+std::string NativeTypeEnum::getName() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getName();
+
+ return std::string(Record->getName());
+}
+
+bool NativeTypeEnum::isNested() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isNested();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Nested);
+}
+
+bool NativeTypeEnum::hasOverloadedOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasOverloadedOperator();
+
+ return bool(Record->getOptions() &
+ codeview::ClassOptions::HasOverloadedOperator);
+}
+
+bool NativeTypeEnum::isPacked() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isPacked();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Packed);
+}
+
+bool NativeTypeEnum::isScoped() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isScoped();
+
+ return bool(Record->getOptions() & codeview::ClassOptions::Scoped);
+}
+
+SymIndexId NativeTypeEnum::getTypeId() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getTypeId();
+
+ return Session.getSymbolCache().findSymbolByTypeIndex(
+ Record->getUnderlyingType());
+}
+
+bool NativeTypeEnum::isRefUdt() const { return false; }
+
+bool NativeTypeEnum::isValueUdt() const { return false; }
+
+bool NativeTypeEnum::isInterfaceUdt() const { return false; }
+
+bool NativeTypeEnum::isConstType() const {
+ if (!Modifiers)
+ return false;
+ return ((Modifiers->getModifiers() & ModifierOptions::Const) !=
+ ModifierOptions::None);
+}
+
+bool NativeTypeEnum::isVolatileType() const {
+ if (!Modifiers)
+ return false;
+ return ((Modifiers->getModifiers() & ModifierOptions::Volatile) !=
+ ModifierOptions::None);
+}
+
+bool NativeTypeEnum::isUnalignedType() const {
+ if (!Modifiers)
+ return false;
+ return ((Modifiers->getModifiers() & ModifierOptions::Unaligned) !=
+ ModifierOptions::None);
+}
+
+const NativeTypeBuiltin &NativeTypeEnum::getUnderlyingBuiltinType() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getUnderlyingBuiltinType();
+
+ return Session.getSymbolCache().getNativeSymbolById<NativeTypeBuiltin>(
+ getTypeId());
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
index f98a4c3043..d8daab006a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeFunctionSig.cpp
@@ -1,199 +1,199 @@
-//===- NativeTypeFunctionSig.cpp - info about function signature -*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
-
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
-#include "llvm/DebugInfo/PDB/PDBExtras.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-namespace {
-// This is kind of a silly class, hence why we keep it private to the file.
-// It's only purpose is to wrap the real type record. I guess this is so that
-// we can have the lexical parent point to the function instead of the global
-// scope.
-class NativeTypeFunctionArg : public NativeRawSymbol {
-public:
- NativeTypeFunctionArg(NativeSession &Session,
- std::unique_ptr<PDBSymbol> RealType)
- : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0),
- RealType(std::move(RealType)) {}
-
- void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const override {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
- PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
- }
-
- SymIndexId getTypeId() const override { return RealType->getSymIndexId(); }
-
- std::unique_ptr<PDBSymbol> RealType;
-};
-
-class NativeEnumFunctionArgs : public IPDBEnumChildren<PDBSymbol> {
-public:
- NativeEnumFunctionArgs(NativeSession &Session,
- std::unique_ptr<NativeEnumTypes> TypeEnumerator)
- : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {}
-
- uint32_t getChildCount() const override {
- return TypeEnumerator->getChildCount();
- }
- std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
- return wrap(TypeEnumerator->getChildAtIndex(Index));
- }
- std::unique_ptr<PDBSymbol> getNext() override {
- return wrap(TypeEnumerator->getNext());
- }
-
- void reset() override { TypeEnumerator->reset(); }
-
-private:
- std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
- if (!S)
- return nullptr;
- auto NTFA = std::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
- return PDBSymbol::create(Session, std::move(NTFA));
- }
- NativeSession &Session;
- std::unique_ptr<NativeEnumTypes> TypeEnumerator;
-};
-} // namespace
-
-NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session,
- SymIndexId Id,
- codeview::TypeIndex Index,
- codeview::ProcedureRecord Proc)
- : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
- Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {}
-
-NativeTypeFunctionSig::NativeTypeFunctionSig(
- NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index,
- codeview::MemberFunctionRecord MemberFunc)
- : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
- MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {}
-
-void NativeTypeFunctionSig::initialize() {
- if (IsMemberFunction) {
- ClassParentId =
- Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType);
- initializeArgList(MemberFunc.ArgumentList);
- } else {
- initializeArgList(Proc.ArgumentList);
- }
-}
-
-NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
-
-void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
- TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
- CVType CVT = Tpi.typeCollection().getType(ArgListTI);
-
- cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList));
-}
-
-void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
-
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
- PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
-
- dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent);
- dumpSymbolField(OS, "count", getCount(), Indent);
- dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
- PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
- if (IsMemberFunction)
- dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent);
- dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
- dumpSymbolField(OS, "constType", isConstType(), Indent);
- dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(),
- Indent);
- dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent);
- dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
- dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
- if (Type != PDB_SymType::FunctionArg)
- return std::make_unique<NullEnumerator<PDBSymbol>>();
-
- auto NET = std::make_unique<NativeEnumTypes>(Session,
- /* copy */ ArgList.ArgIndices);
- return std::unique_ptr<IPDBEnumSymbols>(
- new NativeEnumFunctionArgs(Session, std::move(NET)));
-}
-
-SymIndexId NativeTypeFunctionSig::getClassParentId() const {
- if (!IsMemberFunction)
- return 0;
-
- return ClassParentId;
-}
-
-PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const {
- return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv;
-}
-
-uint32_t NativeTypeFunctionSig::getCount() const {
- return IsMemberFunction ? (1 + MemberFunc.getParameterCount())
- : Proc.getParameterCount();
-}
-
-SymIndexId NativeTypeFunctionSig::getTypeId() const {
- TypeIndex ReturnTI =
- IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
-
- SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
- return Result;
-}
-
-int32_t NativeTypeFunctionSig::getThisAdjust() const {
- return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0;
-}
-
-bool NativeTypeFunctionSig::hasConstructor() const {
- if (!IsMemberFunction)
- return false;
-
- return (MemberFunc.getOptions() & FunctionOptions::Constructor) !=
- FunctionOptions::None;
-}
-
-bool NativeTypeFunctionSig::isConstType() const { return false; }
-
-bool NativeTypeFunctionSig::isConstructorVirtualBase() const {
- if (!IsMemberFunction)
- return false;
-
- return (MemberFunc.getOptions() &
- FunctionOptions::ConstructorWithVirtualBases) !=
- FunctionOptions::None;
-}
-
-bool NativeTypeFunctionSig::isCxxReturnUdt() const {
- FunctionOptions Options =
- IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions();
- return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None;
-}
-
-bool NativeTypeFunctionSig::isUnalignedType() const { return false; }
-
-bool NativeTypeFunctionSig::isVolatileType() const { return false; }
+//===- NativeTypeFunctionSig.cpp - info about function signature -*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
+
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+namespace {
+// This is kind of a silly class, hence why we keep it private to the file.
+// It's only purpose is to wrap the real type record. I guess this is so that
+// we can have the lexical parent point to the function instead of the global
+// scope.
+class NativeTypeFunctionArg : public NativeRawSymbol {
+public:
+ NativeTypeFunctionArg(NativeSession &Session,
+ std::unique_ptr<PDBSymbol> RealType)
+ : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0),
+ RealType(std::move(RealType)) {}
+
+ void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const override {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ }
+
+ SymIndexId getTypeId() const override { return RealType->getSymIndexId(); }
+
+ std::unique_ptr<PDBSymbol> RealType;
+};
+
+class NativeEnumFunctionArgs : public IPDBEnumChildren<PDBSymbol> {
+public:
+ NativeEnumFunctionArgs(NativeSession &Session,
+ std::unique_ptr<NativeEnumTypes> TypeEnumerator)
+ : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {}
+
+ uint32_t getChildCount() const override {
+ return TypeEnumerator->getChildCount();
+ }
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
+ return wrap(TypeEnumerator->getChildAtIndex(Index));
+ }
+ std::unique_ptr<PDBSymbol> getNext() override {
+ return wrap(TypeEnumerator->getNext());
+ }
+
+ void reset() override { TypeEnumerator->reset(); }
+
+private:
+ std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
+ if (!S)
+ return nullptr;
+ auto NTFA = std::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
+ return PDBSymbol::create(Session, std::move(NTFA));
+ }
+ NativeSession &Session;
+ std::unique_ptr<NativeEnumTypes> TypeEnumerator;
+};
+} // namespace
+
+NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session,
+ SymIndexId Id,
+ codeview::TypeIndex Index,
+ codeview::ProcedureRecord Proc)
+ : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
+ Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {}
+
+NativeTypeFunctionSig::NativeTypeFunctionSig(
+ NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index,
+ codeview::MemberFunctionRecord MemberFunc)
+ : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
+ MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {}
+
+void NativeTypeFunctionSig::initialize() {
+ if (IsMemberFunction) {
+ ClassParentId =
+ Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType);
+ initializeArgList(MemberFunc.ArgumentList);
+ } else {
+ initializeArgList(Proc.ArgumentList);
+ }
+}
+
+NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
+
+void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
+ TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
+ CVType CVT = Tpi.typeCollection().getType(ArgListTI);
+
+ cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList));
+}
+
+void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+
+ dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent);
+ dumpSymbolField(OS, "count", getCount(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ if (IsMemberFunction)
+ dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent);
+ dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(),
+ Indent);
+ dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
+ if (Type != PDB_SymType::FunctionArg)
+ return std::make_unique<NullEnumerator<PDBSymbol>>();
+
+ auto NET = std::make_unique<NativeEnumTypes>(Session,
+ /* copy */ ArgList.ArgIndices);
+ return std::unique_ptr<IPDBEnumSymbols>(
+ new NativeEnumFunctionArgs(Session, std::move(NET)));
+}
+
+SymIndexId NativeTypeFunctionSig::getClassParentId() const {
+ if (!IsMemberFunction)
+ return 0;
+
+ return ClassParentId;
+}
+
+PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const {
+ return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv;
+}
+
+uint32_t NativeTypeFunctionSig::getCount() const {
+ return IsMemberFunction ? (1 + MemberFunc.getParameterCount())
+ : Proc.getParameterCount();
+}
+
+SymIndexId NativeTypeFunctionSig::getTypeId() const {
+ TypeIndex ReturnTI =
+ IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
+
+ SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
+ return Result;
+}
+
+int32_t NativeTypeFunctionSig::getThisAdjust() const {
+ return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0;
+}
+
+bool NativeTypeFunctionSig::hasConstructor() const {
+ if (!IsMemberFunction)
+ return false;
+
+ return (MemberFunc.getOptions() & FunctionOptions::Constructor) !=
+ FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isConstType() const { return false; }
+
+bool NativeTypeFunctionSig::isConstructorVirtualBase() const {
+ if (!IsMemberFunction)
+ return false;
+
+ return (MemberFunc.getOptions() &
+ FunctionOptions::ConstructorWithVirtualBases) !=
+ FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isCxxReturnUdt() const {
+ FunctionOptions Options =
+ IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions();
+ return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None;
+}
+
+bool NativeTypeFunctionSig::isUnalignedType() const { return false; }
+
+bool NativeTypeFunctionSig::isVolatileType() const { return false; }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
index 32dcfc2359..03a4f6cc91 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypePointer.cpp
@@ -1,193 +1,193 @@
-//===- NativeTypePointer.cpp - info about pointer type ----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
-
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-
-#include <cassert>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
- codeview::TypeIndex TI)
- : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI) {
- assert(TI.isSimple());
- assert(TI.getSimpleMode() != SimpleTypeMode::Direct);
-}
-
-NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
- codeview::TypeIndex TI,
- codeview::PointerRecord Record)
- : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI),
- Record(std::move(Record)) {}
-
-NativeTypePointer::~NativeTypePointer() {}
-
-void NativeTypePointer::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- if (isMemberPointer()) {
- dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session,
- PdbSymbolIdField::ClassParent, ShowIdFields,
- RecurseIdFields);
- }
- dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
- PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
- dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
- PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
- dumpSymbolField(OS, "length", getLength(), Indent);
- dumpSymbolField(OS, "constType", isConstType(), Indent);
- dumpSymbolField(OS, "isPointerToDataMember", isPointerToDataMember(), Indent);
- dumpSymbolField(OS, "isPointerToMemberFunction", isPointerToMemberFunction(),
- Indent);
- dumpSymbolField(OS, "RValueReference", isRValueReference(), Indent);
- dumpSymbolField(OS, "reference", isReference(), Indent);
- dumpSymbolField(OS, "restrictedType", isRestrictedType(), Indent);
- if (isMemberPointer()) {
- if (isSingleInheritance())
- dumpSymbolField(OS, "isSingleInheritance", 1, Indent);
- else if (isMultipleInheritance())
- dumpSymbolField(OS, "isMultipleInheritance", 1, Indent);
- else if (isVirtualInheritance())
- dumpSymbolField(OS, "isVirtualInheritance", 1, Indent);
- }
- dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
- dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
-}
-
-SymIndexId NativeTypePointer::getClassParentId() const {
- if (!isMemberPointer())
- return 0;
-
- assert(Record);
- const MemberPointerInfo &MPI = Record->getMemberInfo();
- return Session.getSymbolCache().findSymbolByTypeIndex(MPI.ContainingType);
-}
-
-uint64_t NativeTypePointer::getLength() const {
- if (Record)
- return Record->getSize();
-
- switch (TI.getSimpleMode()) {
- case SimpleTypeMode::NearPointer:
- case SimpleTypeMode::FarPointer:
- case SimpleTypeMode::HugePointer:
- return 2;
- case SimpleTypeMode::NearPointer32:
- case SimpleTypeMode::FarPointer32:
- return 4;
- case SimpleTypeMode::NearPointer64:
- return 8;
- case SimpleTypeMode::NearPointer128:
- return 16;
- default:
- assert(false && "invalid simple type mode!");
- }
- return 0;
-}
-
-SymIndexId NativeTypePointer::getTypeId() const {
- // This is the pointee SymIndexId.
- TypeIndex Referent = Record ? Record->ReferentType : TI.makeDirect();
-
- return Session.getSymbolCache().findSymbolByTypeIndex(Referent);
-}
-
-bool NativeTypePointer::isReference() const {
- if (!Record)
- return false;
- return Record->getMode() == PointerMode::LValueReference;
-}
-
-bool NativeTypePointer::isRValueReference() const {
- if (!Record)
- return false;
- return Record->getMode() == PointerMode::RValueReference;
-}
-
-bool NativeTypePointer::isPointerToDataMember() const {
- if (!Record)
- return false;
- return Record->getMode() == PointerMode::PointerToDataMember;
-}
-
-bool NativeTypePointer::isPointerToMemberFunction() const {
- if (!Record)
- return false;
- return Record->getMode() == PointerMode::PointerToMemberFunction;
-}
-
-bool NativeTypePointer::isConstType() const {
- if (!Record)
- return false;
- return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None;
-}
-
-bool NativeTypePointer::isRestrictedType() const {
- if (!Record)
- return false;
- return (Record->getOptions() & PointerOptions::Restrict) !=
- PointerOptions::None;
-}
-
-bool NativeTypePointer::isVolatileType() const {
- if (!Record)
- return false;
- return (Record->getOptions() & PointerOptions::Volatile) !=
- PointerOptions::None;
-}
-
-bool NativeTypePointer::isUnalignedType() const {
- if (!Record)
- return false;
- return (Record->getOptions() & PointerOptions::Unaligned) !=
- PointerOptions::None;
-}
-
-static inline bool isInheritanceKind(const MemberPointerInfo &MPI,
- PointerToMemberRepresentation P1,
- PointerToMemberRepresentation P2) {
- return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2);
-}
-
-bool NativeTypePointer::isSingleInheritance() const {
- if (!isMemberPointer())
- return false;
- return isInheritanceKind(
- Record->getMemberInfo(),
- PointerToMemberRepresentation::SingleInheritanceData,
- PointerToMemberRepresentation::SingleInheritanceFunction);
-}
-
-bool NativeTypePointer::isMultipleInheritance() const {
- if (!isMemberPointer())
- return false;
- return isInheritanceKind(
- Record->getMemberInfo(),
- PointerToMemberRepresentation::MultipleInheritanceData,
- PointerToMemberRepresentation::MultipleInheritanceFunction);
-}
-
-bool NativeTypePointer::isVirtualInheritance() const {
- if (!isMemberPointer())
- return false;
- return isInheritanceKind(
- Record->getMemberInfo(),
- PointerToMemberRepresentation::VirtualInheritanceData,
- PointerToMemberRepresentation::VirtualInheritanceFunction);
-}
-
-bool NativeTypePointer::isMemberPointer() const {
- return isPointerToDataMember() || isPointerToMemberFunction();
-}
+//===- NativeTypePointer.cpp - info about pointer type ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI)
+ : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI) {
+ assert(TI.isSimple());
+ assert(TI.getSimpleMode() != SimpleTypeMode::Direct);
+}
+
+NativeTypePointer::NativeTypePointer(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI,
+ codeview::PointerRecord Record)
+ : NativeRawSymbol(Session, PDB_SymType::PointerType, Id), TI(TI),
+ Record(std::move(Record)) {}
+
+NativeTypePointer::~NativeTypePointer() {}
+
+void NativeTypePointer::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ if (isMemberPointer()) {
+ dumpSymbolIdField(OS, "classParentId", getClassParentId(), Indent, Session,
+ PdbSymbolIdField::ClassParent, ShowIdFields,
+ RecurseIdFields);
+ }
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "isPointerToDataMember", isPointerToDataMember(), Indent);
+ dumpSymbolField(OS, "isPointerToMemberFunction", isPointerToMemberFunction(),
+ Indent);
+ dumpSymbolField(OS, "RValueReference", isRValueReference(), Indent);
+ dumpSymbolField(OS, "reference", isReference(), Indent);
+ dumpSymbolField(OS, "restrictedType", isRestrictedType(), Indent);
+ if (isMemberPointer()) {
+ if (isSingleInheritance())
+ dumpSymbolField(OS, "isSingleInheritance", 1, Indent);
+ else if (isMultipleInheritance())
+ dumpSymbolField(OS, "isMultipleInheritance", 1, Indent);
+ else if (isVirtualInheritance())
+ dumpSymbolField(OS, "isVirtualInheritance", 1, Indent);
+ }
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+SymIndexId NativeTypePointer::getClassParentId() const {
+ if (!isMemberPointer())
+ return 0;
+
+ assert(Record);
+ const MemberPointerInfo &MPI = Record->getMemberInfo();
+ return Session.getSymbolCache().findSymbolByTypeIndex(MPI.ContainingType);
+}
+
+uint64_t NativeTypePointer::getLength() const {
+ if (Record)
+ return Record->getSize();
+
+ switch (TI.getSimpleMode()) {
+ case SimpleTypeMode::NearPointer:
+ case SimpleTypeMode::FarPointer:
+ case SimpleTypeMode::HugePointer:
+ return 2;
+ case SimpleTypeMode::NearPointer32:
+ case SimpleTypeMode::FarPointer32:
+ return 4;
+ case SimpleTypeMode::NearPointer64:
+ return 8;
+ case SimpleTypeMode::NearPointer128:
+ return 16;
+ default:
+ assert(false && "invalid simple type mode!");
+ }
+ return 0;
+}
+
+SymIndexId NativeTypePointer::getTypeId() const {
+ // This is the pointee SymIndexId.
+ TypeIndex Referent = Record ? Record->ReferentType : TI.makeDirect();
+
+ return Session.getSymbolCache().findSymbolByTypeIndex(Referent);
+}
+
+bool NativeTypePointer::isReference() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::LValueReference;
+}
+
+bool NativeTypePointer::isRValueReference() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::RValueReference;
+}
+
+bool NativeTypePointer::isPointerToDataMember() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::PointerToDataMember;
+}
+
+bool NativeTypePointer::isPointerToMemberFunction() const {
+ if (!Record)
+ return false;
+ return Record->getMode() == PointerMode::PointerToMemberFunction;
+}
+
+bool NativeTypePointer::isConstType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Const) != PointerOptions::None;
+}
+
+bool NativeTypePointer::isRestrictedType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Restrict) !=
+ PointerOptions::None;
+}
+
+bool NativeTypePointer::isVolatileType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Volatile) !=
+ PointerOptions::None;
+}
+
+bool NativeTypePointer::isUnalignedType() const {
+ if (!Record)
+ return false;
+ return (Record->getOptions() & PointerOptions::Unaligned) !=
+ PointerOptions::None;
+}
+
+static inline bool isInheritanceKind(const MemberPointerInfo &MPI,
+ PointerToMemberRepresentation P1,
+ PointerToMemberRepresentation P2) {
+ return (MPI.getRepresentation() == P1 || MPI.getRepresentation() == P2);
+}
+
+bool NativeTypePointer::isSingleInheritance() const {
+ if (!isMemberPointer())
+ return false;
+ return isInheritanceKind(
+ Record->getMemberInfo(),
+ PointerToMemberRepresentation::SingleInheritanceData,
+ PointerToMemberRepresentation::SingleInheritanceFunction);
+}
+
+bool NativeTypePointer::isMultipleInheritance() const {
+ if (!isMemberPointer())
+ return false;
+ return isInheritanceKind(
+ Record->getMemberInfo(),
+ PointerToMemberRepresentation::MultipleInheritanceData,
+ PointerToMemberRepresentation::MultipleInheritanceFunction);
+}
+
+bool NativeTypePointer::isVirtualInheritance() const {
+ if (!isMemberPointer())
+ return false;
+ return isInheritanceKind(
+ Record->getMemberInfo(),
+ PointerToMemberRepresentation::VirtualInheritanceData,
+ PointerToMemberRepresentation::VirtualInheritanceFunction);
+}
+
+bool NativeTypePointer::isMemberPointer() const {
+ return isPointerToDataMember() || isPointerToMemberFunction();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
index 72964a9e0d..2b25e8a9a8 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeTypedef.cpp
@@ -1,29 +1,29 @@
-#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeTypeTypedef::NativeTypeTypedef(NativeSession &Session, SymIndexId Id,
- codeview::UDTSym Typedef)
- : NativeRawSymbol(Session, PDB_SymType::Typedef, Id),
- Record(std::move(Typedef)) {}
-
-NativeTypeTypedef::~NativeTypeTypedef() {}
-
-void NativeTypeTypedef::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
- dumpSymbolField(OS, "name", getName(), Indent);
- dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
- PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
-}
-
-std::string NativeTypeTypedef::getName() const {
- return std::string(Record.Name);
-}
-
-SymIndexId NativeTypeTypedef::getTypeId() const {
- return Session.getSymbolCache().findSymbolByTypeIndex(Record.Type);
-}
+#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeTypedef::NativeTypeTypedef(NativeSession &Session, SymIndexId Id,
+ codeview::UDTSym Typedef)
+ : NativeRawSymbol(Session, PDB_SymType::Typedef, Id),
+ Record(std::move(Typedef)) {}
+
+NativeTypeTypedef::~NativeTypeTypedef() {}
+
+void NativeTypeTypedef::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
+ PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
+}
+
+std::string NativeTypeTypedef::getName() const {
+ return std::string(Record.Name);
+}
+
+SymIndexId NativeTypeTypedef::getTypeId() const {
+ return Session.getSymbolCache().findSymbolByTypeIndex(Record.Type);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
index 917ec14e58..84ca5d0bea 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeUDT.cpp
@@ -1,220 +1,220 @@
-//===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
-
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-
-#include <cassert>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
- codeview::TypeIndex TI, codeview::ClassRecord CR)
- : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
- Class(std::move(CR)), Tag(Class.getPointer()) {}
-
-NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
- codeview::TypeIndex TI, codeview::UnionRecord UR)
- : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
- Union(std::move(UR)), Tag(Union.getPointer()) {}
-
-NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
- NativeTypeUDT &UnmodifiedType,
- codeview::ModifierRecord Modifier)
- : NativeRawSymbol(Session, PDB_SymType::UDT, Id),
- UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
-
-NativeTypeUDT::~NativeTypeUDT() {}
-
-void NativeTypeUDT::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
-
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- dumpSymbolField(OS, "name", getName(), Indent);
- dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
- PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
- if (Modifiers.hasValue())
- dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
- Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
- RecurseIdFields);
- if (getUdtKind() != PDB_UdtType::Union)
- dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(),
- Indent);
- dumpSymbolField(OS, "length", getLength(), Indent);
- dumpSymbolField(OS, "udtKind", getUdtKind(), Indent);
- dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
- dumpSymbolField(OS, "constType", isConstType(), Indent);
- dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
- dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
- dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
- dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
- dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
- dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
- dumpSymbolField(OS, "nested", isNested(), Indent);
- dumpSymbolField(OS, "packed", isPacked(), Indent);
- dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
- dumpSymbolField(OS, "scoped", isScoped(), Indent);
- dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
- dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
- dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
-}
-
-std::string NativeTypeUDT::getName() const {
- if (UnmodifiedType)
- return UnmodifiedType->getName();
-
- return std::string(Tag->getName());
-}
-
-SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; }
-
-SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const {
- if (UnmodifiedType)
- return UnmodifiedType->getSymIndexId();
-
- return 0;
-}
-
-SymIndexId NativeTypeUDT::getVirtualTableShapeId() const {
- if (UnmodifiedType)
- return UnmodifiedType->getVirtualTableShapeId();
-
- if (Class)
- return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape);
-
- return 0;
-}
-
-uint64_t NativeTypeUDT::getLength() const {
- if (UnmodifiedType)
- return UnmodifiedType->getLength();
-
- if (Class)
- return Class->getSize();
-
- return Union->getSize();
-}
-
-PDB_UdtType NativeTypeUDT::getUdtKind() const {
- if (UnmodifiedType)
- return UnmodifiedType->getUdtKind();
-
- switch (Tag->Kind) {
- case TypeRecordKind::Class:
- return PDB_UdtType::Class;
- case TypeRecordKind::Union:
- return PDB_UdtType::Union;
- case TypeRecordKind::Struct:
- return PDB_UdtType::Struct;
- case TypeRecordKind::Interface:
- return PDB_UdtType::Interface;
- default:
+//===- NativeTypeUDT.cpp - info about class/struct type ---------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+
+#include <cassert>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI, codeview::ClassRecord CR)
+ : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
+ Class(std::move(CR)), Tag(Class.getPointer()) {}
+
+NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI, codeview::UnionRecord UR)
+ : NativeRawSymbol(Session, PDB_SymType::UDT, Id), Index(TI),
+ Union(std::move(UR)), Tag(Union.getPointer()) {}
+
+NativeTypeUDT::NativeTypeUDT(NativeSession &Session, SymIndexId Id,
+ NativeTypeUDT &UnmodifiedType,
+ codeview::ModifierRecord Modifier)
+ : NativeRawSymbol(Session, PDB_SymType::UDT, Id),
+ UnmodifiedType(&UnmodifiedType), Modifiers(std::move(Modifier)) {}
+
+NativeTypeUDT::~NativeTypeUDT() {}
+
+void NativeTypeUDT::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolField(OS, "name", getName(), Indent);
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ if (Modifiers.hasValue())
+ dumpSymbolIdField(OS, "unmodifiedTypeId", getUnmodifiedTypeId(), Indent,
+ Session, PdbSymbolIdField::UnmodifiedType, ShowIdFields,
+ RecurseIdFields);
+ if (getUdtKind() != PDB_UdtType::Union)
+ dumpSymbolField(OS, "virtualTableShapeId", getVirtualTableShapeId(),
+ Indent);
+ dumpSymbolField(OS, "length", getLength(), Indent);
+ dumpSymbolField(OS, "udtKind", getUdtKind(), Indent);
+ dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "hasAssignmentOperator", hasAssignmentOperator(), Indent);
+ dumpSymbolField(OS, "hasCastOperator", hasCastOperator(), Indent);
+ dumpSymbolField(OS, "hasNestedTypes", hasNestedTypes(), Indent);
+ dumpSymbolField(OS, "overloadedOperator", hasOverloadedOperator(), Indent);
+ dumpSymbolField(OS, "isInterfaceUdt", isInterfaceUdt(), Indent);
+ dumpSymbolField(OS, "intrinsic", isIntrinsic(), Indent);
+ dumpSymbolField(OS, "nested", isNested(), Indent);
+ dumpSymbolField(OS, "packed", isPacked(), Indent);
+ dumpSymbolField(OS, "isRefUdt", isRefUdt(), Indent);
+ dumpSymbolField(OS, "scoped", isScoped(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "isValueUdt", isValueUdt(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+std::string NativeTypeUDT::getName() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getName();
+
+ return std::string(Tag->getName());
+}
+
+SymIndexId NativeTypeUDT::getLexicalParentId() const { return 0; }
+
+SymIndexId NativeTypeUDT::getUnmodifiedTypeId() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getSymIndexId();
+
+ return 0;
+}
+
+SymIndexId NativeTypeUDT::getVirtualTableShapeId() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getVirtualTableShapeId();
+
+ if (Class)
+ return Session.getSymbolCache().findSymbolByTypeIndex(Class->VTableShape);
+
+ return 0;
+}
+
+uint64_t NativeTypeUDT::getLength() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getLength();
+
+ if (Class)
+ return Class->getSize();
+
+ return Union->getSize();
+}
+
+PDB_UdtType NativeTypeUDT::getUdtKind() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->getUdtKind();
+
+ switch (Tag->Kind) {
+ case TypeRecordKind::Class:
+ return PDB_UdtType::Class;
+ case TypeRecordKind::Union:
+ return PDB_UdtType::Union;
+ case TypeRecordKind::Struct:
+ return PDB_UdtType::Struct;
+ case TypeRecordKind::Interface:
+ return PDB_UdtType::Interface;
+ default:
llvm_unreachable("Unexpected udt kind");
- }
-}
-
-bool NativeTypeUDT::hasConstructor() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasConstructor();
-
- return (Tag->Options & ClassOptions::HasConstructorOrDestructor) !=
- ClassOptions::None;
-}
-
-bool NativeTypeUDT::isConstType() const {
- if (!Modifiers)
- return false;
- return (Modifiers->Modifiers & ModifierOptions::Const) !=
- ModifierOptions::None;
-}
-
-bool NativeTypeUDT::hasAssignmentOperator() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasAssignmentOperator();
-
- return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) !=
- ClassOptions::None;
-}
-
-bool NativeTypeUDT::hasCastOperator() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasCastOperator();
-
- return (Tag->Options & ClassOptions::HasConversionOperator) !=
- ClassOptions::None;
-}
-
-bool NativeTypeUDT::hasNestedTypes() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasNestedTypes();
-
- return (Tag->Options & ClassOptions::ContainsNestedClass) !=
- ClassOptions::None;
-}
-
-bool NativeTypeUDT::hasOverloadedOperator() const {
- if (UnmodifiedType)
- return UnmodifiedType->hasOverloadedOperator();
-
- return (Tag->Options & ClassOptions::HasOverloadedOperator) !=
- ClassOptions::None;
-}
-
-bool NativeTypeUDT::isInterfaceUdt() const { return false; }
-
-bool NativeTypeUDT::isIntrinsic() const {
- if (UnmodifiedType)
- return UnmodifiedType->isIntrinsic();
-
- return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None;
-}
-
-bool NativeTypeUDT::isNested() const {
- if (UnmodifiedType)
- return UnmodifiedType->isNested();
-
- return (Tag->Options & ClassOptions::Nested) != ClassOptions::None;
-}
-
-bool NativeTypeUDT::isPacked() const {
- if (UnmodifiedType)
- return UnmodifiedType->isPacked();
-
- return (Tag->Options & ClassOptions::Packed) != ClassOptions::None;
-}
-
-bool NativeTypeUDT::isRefUdt() const { return false; }
-
-bool NativeTypeUDT::isScoped() const {
- if (UnmodifiedType)
- return UnmodifiedType->isScoped();
-
- return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None;
-}
-
-bool NativeTypeUDT::isValueUdt() const { return false; }
-
-bool NativeTypeUDT::isUnalignedType() const {
- if (!Modifiers)
- return false;
- return (Modifiers->Modifiers & ModifierOptions::Unaligned) !=
- ModifierOptions::None;
-}
-
-bool NativeTypeUDT::isVolatileType() const {
- if (!Modifiers)
- return false;
- return (Modifiers->Modifiers & ModifierOptions::Volatile) !=
- ModifierOptions::None;
-}
+ }
+}
+
+bool NativeTypeUDT::hasConstructor() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasConstructor();
+
+ return (Tag->Options & ClassOptions::HasConstructorOrDestructor) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::isConstType() const {
+ if (!Modifiers)
+ return false;
+ return (Modifiers->Modifiers & ModifierOptions::Const) !=
+ ModifierOptions::None;
+}
+
+bool NativeTypeUDT::hasAssignmentOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasAssignmentOperator();
+
+ return (Tag->Options & ClassOptions::HasOverloadedAssignmentOperator) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::hasCastOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasCastOperator();
+
+ return (Tag->Options & ClassOptions::HasConversionOperator) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::hasNestedTypes() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasNestedTypes();
+
+ return (Tag->Options & ClassOptions::ContainsNestedClass) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::hasOverloadedOperator() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->hasOverloadedOperator();
+
+ return (Tag->Options & ClassOptions::HasOverloadedOperator) !=
+ ClassOptions::None;
+}
+
+bool NativeTypeUDT::isInterfaceUdt() const { return false; }
+
+bool NativeTypeUDT::isIntrinsic() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isIntrinsic();
+
+ return (Tag->Options & ClassOptions::Intrinsic) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isNested() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isNested();
+
+ return (Tag->Options & ClassOptions::Nested) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isPacked() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isPacked();
+
+ return (Tag->Options & ClassOptions::Packed) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isRefUdt() const { return false; }
+
+bool NativeTypeUDT::isScoped() const {
+ if (UnmodifiedType)
+ return UnmodifiedType->isScoped();
+
+ return (Tag->Options & ClassOptions::Scoped) != ClassOptions::None;
+}
+
+bool NativeTypeUDT::isValueUdt() const { return false; }
+
+bool NativeTypeUDT::isUnalignedType() const {
+ if (!Modifiers)
+ return false;
+ return (Modifiers->Modifiers & ModifierOptions::Unaligned) !=
+ ModifierOptions::None;
+}
+
+bool NativeTypeUDT::isVolatileType() const {
+ if (!Modifiers)
+ return false;
+ return (Modifiers->Modifiers & ModifierOptions::Volatile) !=
+ ModifierOptions::None;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
index 837fe19ec8..eb7bf8fa0f 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/NativeTypeVTShape.cpp
@@ -1,35 +1,35 @@
-#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-// Create a pointer record for a non-simple type.
-NativeTypeVTShape::NativeTypeVTShape(NativeSession &Session, SymIndexId Id,
- codeview::TypeIndex TI,
- codeview::VFTableShapeRecord SR)
- : NativeRawSymbol(Session, PDB_SymType::VTableShape, Id), TI(TI),
- Record(std::move(SR)) {}
-
-NativeTypeVTShape::~NativeTypeVTShape() {}
-
-void NativeTypeVTShape::dump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowIdFields,
- PdbSymbolIdField RecurseIdFields) const {
- NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
-
- dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
- PdbSymbolIdField::LexicalParent, ShowIdFields,
- RecurseIdFields);
- dumpSymbolField(OS, "count", getCount(), Indent);
- dumpSymbolField(OS, "constType", isConstType(), Indent);
- dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
- dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
-}
-
-bool NativeTypeVTShape::isConstType() const { return false; }
-
-bool NativeTypeVTShape::isVolatileType() const { return false; }
-
-bool NativeTypeVTShape::isUnalignedType() const { return false; }
-
-uint32_t NativeTypeVTShape::getCount() const { return Record.Slots.size(); }
+#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+// Create a pointer record for a non-simple type.
+NativeTypeVTShape::NativeTypeVTShape(NativeSession &Session, SymIndexId Id,
+ codeview::TypeIndex TI,
+ codeview::VFTableShapeRecord SR)
+ : NativeRawSymbol(Session, PDB_SymType::VTableShape, Id), TI(TI),
+ Record(std::move(SR)) {}
+
+NativeTypeVTShape::~NativeTypeVTShape() {}
+
+void NativeTypeVTShape::dump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowIdFields,
+ PdbSymbolIdField RecurseIdFields) const {
+ NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
+
+ dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
+ PdbSymbolIdField::LexicalParent, ShowIdFields,
+ RecurseIdFields);
+ dumpSymbolField(OS, "count", getCount(), Indent);
+ dumpSymbolField(OS, "constType", isConstType(), Indent);
+ dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
+ dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
+}
+
+bool NativeTypeVTShape::isConstType() const { return false; }
+
+bool NativeTypeVTShape::isVolatileType() const { return false; }
+
+bool NativeTypeVTShape::isUnalignedType() const { return false; }
+
+uint32_t NativeTypeVTShape::getCount() const { return Record.Slots.size(); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFile.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFile.cpp
index cde6452368..112b5c9fed 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFile.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFile.cpp
@@ -1,508 +1,508 @@
-//===- PDBFile.cpp - Low level interface to a PDB file ----------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/MSF/MSFCommon.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#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"
-#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
-#include "llvm/Support/BinaryStream.h"
-#include "llvm/Support/BinaryStreamArray.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/Path.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-namespace {
-typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
-} // end anonymous namespace
-
-PDBFile::PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer,
- BumpPtrAllocator &Allocator)
- : FilePath(std::string(Path)), Allocator(Allocator),
- Buffer(std::move(PdbFileBuffer)) {}
-
-PDBFile::~PDBFile() = default;
-
-StringRef PDBFile::getFilePath() const { return FilePath; }
-
-StringRef PDBFile::getFileDirectory() const {
- return sys::path::parent_path(FilePath);
-}
-
-uint32_t PDBFile::getBlockSize() const { return ContainerLayout.SB->BlockSize; }
-
-uint32_t PDBFile::getFreeBlockMapBlock() const {
- return ContainerLayout.SB->FreeBlockMapBlock;
-}
-
-uint32_t PDBFile::getBlockCount() const {
- return ContainerLayout.SB->NumBlocks;
-}
-
-uint32_t PDBFile::getNumDirectoryBytes() const {
- return ContainerLayout.SB->NumDirectoryBytes;
-}
-
-uint32_t PDBFile::getBlockMapIndex() const {
- return ContainerLayout.SB->BlockMapAddr;
-}
-
-uint32_t PDBFile::getUnknown1() const { return ContainerLayout.SB->Unknown1; }
-
-uint32_t PDBFile::getNumDirectoryBlocks() const {
- return msf::bytesToBlocks(ContainerLayout.SB->NumDirectoryBytes,
- ContainerLayout.SB->BlockSize);
-}
-
-uint64_t PDBFile::getBlockMapOffset() const {
- return (uint64_t)ContainerLayout.SB->BlockMapAddr *
- ContainerLayout.SB->BlockSize;
-}
-
-uint32_t PDBFile::getNumStreams() const {
- return ContainerLayout.StreamSizes.size();
-}
-
-uint32_t PDBFile::getMaxStreamSize() const {
- return *std::max_element(ContainerLayout.StreamSizes.begin(),
- ContainerLayout.StreamSizes.end());
-}
-
-uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
- return ContainerLayout.StreamSizes[StreamIndex];
-}
-
-ArrayRef<support::ulittle32_t>
-PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
- return ContainerLayout.StreamMap[StreamIndex];
-}
-
-uint32_t PDBFile::getFileSize() const { return Buffer->getLength(); }
-
-Expected<ArrayRef<uint8_t>> PDBFile::getBlockData(uint32_t BlockIndex,
- uint32_t NumBytes) const {
- uint64_t StreamBlockOffset = msf::blockToOffset(BlockIndex, getBlockSize());
-
- ArrayRef<uint8_t> Result;
- if (auto EC = Buffer->readBytes(StreamBlockOffset, NumBytes, Result))
- return std::move(EC);
- return Result;
-}
-
-Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
- ArrayRef<uint8_t> Data) const {
- return make_error<RawError>(raw_error_code::not_writable,
- "PDBFile is immutable");
-}
-
-Error PDBFile::parseFileHeaders() {
- BinaryStreamReader Reader(*Buffer);
-
- // Initialize SB.
- const msf::SuperBlock *SB = nullptr;
- if (auto EC = Reader.readObject(SB)) {
- consumeError(std::move(EC));
- return make_error<RawError>(raw_error_code::corrupt_file,
- "MSF superblock is missing");
- }
-
- if (auto EC = msf::validateSuperBlock(*SB))
- return EC;
-
- if (Buffer->getLength() % SB->BlockSize != 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "File size is not a multiple of block size");
- ContainerLayout.SB = SB;
-
- // Initialize Free Page Map.
- ContainerLayout.FreePageMap.resize(SB->NumBlocks);
- // The Fpm exists either at block 1 or block 2 of the MSF. However, this
- // allows for a maximum of getBlockSize() * 8 blocks bits in the Fpm, and
- // thusly an equal number of total blocks in the file. For a block size
- // of 4KiB (very common), this would yield 32KiB total blocks in file, for a
- // maximum file size of 32KiB * 4KiB = 128MiB. Obviously this won't do, so
- // the Fpm is split across the file at `getBlockSize()` intervals. As a
- // result, every block whose index is of the form |{1,2} + getBlockSize() * k|
- // for any non-negative integer k is an Fpm block. In theory, we only really
- // need to reserve blocks of the form |{1,2} + getBlockSize() * 8 * k|, but
- // current versions of the MSF format already expect the Fpm to be arranged
- // at getBlockSize() intervals, so we have to be compatible.
- // See the function fpmPn() for more information:
- // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/msf/msf.cpp#L489
- auto FpmStream =
- MappedBlockStream::createFpmStream(ContainerLayout, *Buffer, Allocator);
- BinaryStreamReader FpmReader(*FpmStream);
- ArrayRef<uint8_t> FpmBytes;
- if (auto EC = FpmReader.readBytes(FpmBytes, FpmReader.bytesRemaining()))
- return EC;
- uint32_t BlocksRemaining = getBlockCount();
- uint32_t BI = 0;
- for (auto Byte : FpmBytes) {
- uint32_t BlocksThisByte = std::min(BlocksRemaining, 8U);
- for (uint32_t I = 0; I < BlocksThisByte; ++I) {
- if (Byte & (1 << I))
- ContainerLayout.FreePageMap[BI] = true;
- --BlocksRemaining;
- ++BI;
- }
- }
-
- Reader.setOffset(getBlockMapOffset());
- if (auto EC = Reader.readArray(ContainerLayout.DirectoryBlocks,
- getNumDirectoryBlocks()))
- return EC;
-
- return Error::success();
-}
-
-Error PDBFile::parseStreamData() {
- assert(ContainerLayout.SB);
- if (DirectoryStream)
- return Error::success();
-
- uint32_t NumStreams = 0;
-
- // Normally you can't use a MappedBlockStream without having fully parsed the
- // PDB file, because it accesses the directory and various other things, which
- // is exactly what we are attempting to parse. By specifying a custom
- // subclass of IPDBStreamData which only accesses the fields that have already
- // been parsed, we can avoid this and reuse MappedBlockStream.
- auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer,
- Allocator);
- BinaryStreamReader Reader(*DS);
- if (auto EC = Reader.readInteger(NumStreams))
- return EC;
-
- if (auto EC = Reader.readArray(ContainerLayout.StreamSizes, NumStreams))
- return EC;
- for (uint32_t I = 0; I < NumStreams; ++I) {
- uint32_t StreamSize = getStreamByteSize(I);
- // FIXME: What does StreamSize ~0U mean?
- uint64_t NumExpectedStreamBlocks =
- StreamSize == UINT32_MAX
- ? 0
- : msf::bytesToBlocks(StreamSize, ContainerLayout.SB->BlockSize);
-
- // For convenience, we store the block array contiguously. This is because
- // if someone calls setStreamMap(), it is more convenient to be able to call
- // it with an ArrayRef instead of setting up a StreamRef. Since the
- // DirectoryStream is cached in the class and thus lives for the life of the
- // class, we can be guaranteed that readArray() will return a stable
- // reference, even if it has to allocate from its internal pool.
- ArrayRef<support::ulittle32_t> Blocks;
- if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
- return EC;
- for (uint32_t Block : Blocks) {
- uint64_t BlockEndOffset =
- (uint64_t)(Block + 1) * ContainerLayout.SB->BlockSize;
- if (BlockEndOffset > getFileSize())
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Stream block map is corrupt.");
- }
- ContainerLayout.StreamMap.push_back(Blocks);
- }
-
- // We should have read exactly SB->NumDirectoryBytes bytes.
- assert(Reader.bytesRemaining() == 0);
- DirectoryStream = std::move(DS);
- return Error::success();
-}
-
-ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
- return ContainerLayout.DirectoryBlocks;
-}
-
-std::unique_ptr<MappedBlockStream>
-PDBFile::createIndexedStream(uint16_t SN) const {
- if (SN == kInvalidStreamIndex)
- return nullptr;
- return MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer, SN,
- Allocator);
-}
-
-MSFStreamLayout PDBFile::getStreamLayout(uint32_t StreamIdx) const {
- MSFStreamLayout Result;
- auto Blocks = getStreamBlockList(StreamIdx);
- Result.Blocks.assign(Blocks.begin(), Blocks.end());
- Result.Length = getStreamByteSize(StreamIdx);
- return Result;
-}
-
-msf::MSFStreamLayout PDBFile::getFpmStreamLayout() const {
- return msf::getFpmStreamLayout(ContainerLayout);
-}
-
-Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
- if (!Globals) {
- auto DbiS = getPDBDbiStream();
- if (!DbiS)
- return DbiS.takeError();
-
- auto GlobalS =
- safelyCreateIndexedStream(DbiS->getGlobalSymbolStreamIndex());
- if (!GlobalS)
- return GlobalS.takeError();
- auto TempGlobals = std::make_unique<GlobalsStream>(std::move(*GlobalS));
- if (auto EC = TempGlobals->reload())
- return std::move(EC);
- Globals = std::move(TempGlobals);
- }
- return *Globals;
-}
-
-Expected<InfoStream &> PDBFile::getPDBInfoStream() {
- if (!Info) {
- auto InfoS = safelyCreateIndexedStream(StreamPDB);
- if (!InfoS)
- return InfoS.takeError();
- auto TempInfo = std::make_unique<InfoStream>(std::move(*InfoS));
- if (auto EC = TempInfo->reload())
- return std::move(EC);
- Info = std::move(TempInfo);
- }
- return *Info;
-}
-
-Expected<DbiStream &> PDBFile::getPDBDbiStream() {
- if (!Dbi) {
- auto DbiS = safelyCreateIndexedStream(StreamDBI);
- if (!DbiS)
- return DbiS.takeError();
- auto TempDbi = std::make_unique<DbiStream>(std::move(*DbiS));
- if (auto EC = TempDbi->reload(this))
- return std::move(EC);
- Dbi = std::move(TempDbi);
- }
- return *Dbi;
-}
-
-Expected<TpiStream &> PDBFile::getPDBTpiStream() {
- if (!Tpi) {
- auto TpiS = safelyCreateIndexedStream(StreamTPI);
- if (!TpiS)
- return TpiS.takeError();
- auto TempTpi = std::make_unique<TpiStream>(*this, std::move(*TpiS));
- if (auto EC = TempTpi->reload())
- return std::move(EC);
- Tpi = std::move(TempTpi);
- }
- return *Tpi;
-}
-
-Expected<TpiStream &> PDBFile::getPDBIpiStream() {
- if (!Ipi) {
- if (!hasPDBIpiStream())
- return make_error<RawError>(raw_error_code::no_stream);
-
- auto IpiS = safelyCreateIndexedStream(StreamIPI);
- if (!IpiS)
- return IpiS.takeError();
- auto TempIpi = std::make_unique<TpiStream>(*this, std::move(*IpiS));
- if (auto EC = TempIpi->reload())
- return std::move(EC);
- Ipi = std::move(TempIpi);
- }
- return *Ipi;
-}
-
-Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
- if (!Publics) {
- auto DbiS = getPDBDbiStream();
- if (!DbiS)
- return DbiS.takeError();
-
- auto PublicS =
- safelyCreateIndexedStream(DbiS->getPublicSymbolStreamIndex());
- if (!PublicS)
- return PublicS.takeError();
- auto TempPublics = std::make_unique<PublicsStream>(std::move(*PublicS));
- if (auto EC = TempPublics->reload())
- return std::move(EC);
- Publics = std::move(TempPublics);
- }
- return *Publics;
-}
-
-Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
- if (!Symbols) {
- auto DbiS = getPDBDbiStream();
- if (!DbiS)
- return DbiS.takeError();
-
- uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
- auto SymbolS = safelyCreateIndexedStream(SymbolStreamNum);
- if (!SymbolS)
- return SymbolS.takeError();
-
- auto TempSymbols = std::make_unique<SymbolStream>(std::move(*SymbolS));
- if (auto EC = TempSymbols->reload())
- return std::move(EC);
- Symbols = std::move(TempSymbols);
- }
- return *Symbols;
-}
-
-Expected<PDBStringTable &> PDBFile::getStringTable() {
- if (!Strings) {
- auto NS = safelyCreateNamedStream("/names");
- if (!NS)
- return NS.takeError();
-
- auto N = std::make_unique<PDBStringTable>();
- BinaryStreamReader Reader(**NS);
- if (auto EC = N->reload(Reader))
- return std::move(EC);
- assert(Reader.bytesRemaining() == 0);
- StringTableStream = std::move(*NS);
- Strings = std::move(N);
- }
- 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 = std::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)
- return 0;
- PDB_Machine Machine = DbiS->getMachineType();
- if (Machine == PDB_Machine::Amd64)
- return 8;
- return 4;
-}
-
-bool PDBFile::hasPDBDbiStream() const {
- return StreamDBI < getNumStreams() && getStreamByteSize(StreamDBI) > 0;
-}
-
-bool PDBFile::hasPDBGlobalsStream() {
- auto DbiS = getPDBDbiStream();
- if (!DbiS) {
- consumeError(DbiS.takeError());
- return false;
- }
-
- return DbiS->getGlobalSymbolStreamIndex() < getNumStreams();
-}
-
-bool PDBFile::hasPDBInfoStream() const { return StreamPDB < getNumStreams(); }
-
-bool PDBFile::hasPDBIpiStream() const {
- if (!hasPDBInfoStream())
- return false;
-
- if (StreamIPI >= getNumStreams())
- return false;
-
- auto &InfoStream = cantFail(const_cast<PDBFile *>(this)->getPDBInfoStream());
- return InfoStream.containsIdStream();
-}
-
-bool PDBFile::hasPDBPublicsStream() {
- auto DbiS = getPDBDbiStream();
- if (!DbiS) {
- consumeError(DbiS.takeError());
- return false;
- }
- return DbiS->getPublicSymbolStreamIndex() < getNumStreams();
-}
-
-bool PDBFile::hasPDBSymbolStream() {
- auto DbiS = getPDBDbiStream();
- if (!DbiS)
- return false;
- return DbiS->getSymRecordStreamIndex() < getNumStreams();
-}
-
-bool PDBFile::hasPDBTpiStream() const { return StreamTPI < getNumStreams(); }
-
-bool PDBFile::hasPDBStringTable() {
- auto IS = getPDBInfoStream();
- if (!IS)
- return false;
- Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names");
- if (!ExpectedNSI) {
- consumeError(ExpectedNSI.takeError());
- return false;
- }
- assert(*ExpectedNSI < getNumStreams());
- 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(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 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);
-}
+//===- PDBFile.cpp - Low level interface to a PDB file ----------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#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"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/Path.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+namespace {
+typedef FixedStreamArray<support::ulittle32_t> ulittle_array;
+} // end anonymous namespace
+
+PDBFile::PDBFile(StringRef Path, std::unique_ptr<BinaryStream> PdbFileBuffer,
+ BumpPtrAllocator &Allocator)
+ : FilePath(std::string(Path)), Allocator(Allocator),
+ Buffer(std::move(PdbFileBuffer)) {}
+
+PDBFile::~PDBFile() = default;
+
+StringRef PDBFile::getFilePath() const { return FilePath; }
+
+StringRef PDBFile::getFileDirectory() const {
+ return sys::path::parent_path(FilePath);
+}
+
+uint32_t PDBFile::getBlockSize() const { return ContainerLayout.SB->BlockSize; }
+
+uint32_t PDBFile::getFreeBlockMapBlock() const {
+ return ContainerLayout.SB->FreeBlockMapBlock;
+}
+
+uint32_t PDBFile::getBlockCount() const {
+ return ContainerLayout.SB->NumBlocks;
+}
+
+uint32_t PDBFile::getNumDirectoryBytes() const {
+ return ContainerLayout.SB->NumDirectoryBytes;
+}
+
+uint32_t PDBFile::getBlockMapIndex() const {
+ return ContainerLayout.SB->BlockMapAddr;
+}
+
+uint32_t PDBFile::getUnknown1() const { return ContainerLayout.SB->Unknown1; }
+
+uint32_t PDBFile::getNumDirectoryBlocks() const {
+ return msf::bytesToBlocks(ContainerLayout.SB->NumDirectoryBytes,
+ ContainerLayout.SB->BlockSize);
+}
+
+uint64_t PDBFile::getBlockMapOffset() const {
+ return (uint64_t)ContainerLayout.SB->BlockMapAddr *
+ ContainerLayout.SB->BlockSize;
+}
+
+uint32_t PDBFile::getNumStreams() const {
+ return ContainerLayout.StreamSizes.size();
+}
+
+uint32_t PDBFile::getMaxStreamSize() const {
+ return *std::max_element(ContainerLayout.StreamSizes.begin(),
+ ContainerLayout.StreamSizes.end());
+}
+
+uint32_t PDBFile::getStreamByteSize(uint32_t StreamIndex) const {
+ return ContainerLayout.StreamSizes[StreamIndex];
+}
+
+ArrayRef<support::ulittle32_t>
+PDBFile::getStreamBlockList(uint32_t StreamIndex) const {
+ return ContainerLayout.StreamMap[StreamIndex];
+}
+
+uint32_t PDBFile::getFileSize() const { return Buffer->getLength(); }
+
+Expected<ArrayRef<uint8_t>> PDBFile::getBlockData(uint32_t BlockIndex,
+ uint32_t NumBytes) const {
+ uint64_t StreamBlockOffset = msf::blockToOffset(BlockIndex, getBlockSize());
+
+ ArrayRef<uint8_t> Result;
+ if (auto EC = Buffer->readBytes(StreamBlockOffset, NumBytes, Result))
+ return std::move(EC);
+ return Result;
+}
+
+Error PDBFile::setBlockData(uint32_t BlockIndex, uint32_t Offset,
+ ArrayRef<uint8_t> Data) const {
+ return make_error<RawError>(raw_error_code::not_writable,
+ "PDBFile is immutable");
+}
+
+Error PDBFile::parseFileHeaders() {
+ BinaryStreamReader Reader(*Buffer);
+
+ // Initialize SB.
+ const msf::SuperBlock *SB = nullptr;
+ if (auto EC = Reader.readObject(SB)) {
+ consumeError(std::move(EC));
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "MSF superblock is missing");
+ }
+
+ if (auto EC = msf::validateSuperBlock(*SB))
+ return EC;
+
+ if (Buffer->getLength() % SB->BlockSize != 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "File size is not a multiple of block size");
+ ContainerLayout.SB = SB;
+
+ // Initialize Free Page Map.
+ ContainerLayout.FreePageMap.resize(SB->NumBlocks);
+ // The Fpm exists either at block 1 or block 2 of the MSF. However, this
+ // allows for a maximum of getBlockSize() * 8 blocks bits in the Fpm, and
+ // thusly an equal number of total blocks in the file. For a block size
+ // of 4KiB (very common), this would yield 32KiB total blocks in file, for a
+ // maximum file size of 32KiB * 4KiB = 128MiB. Obviously this won't do, so
+ // the Fpm is split across the file at `getBlockSize()` intervals. As a
+ // result, every block whose index is of the form |{1,2} + getBlockSize() * k|
+ // for any non-negative integer k is an Fpm block. In theory, we only really
+ // need to reserve blocks of the form |{1,2} + getBlockSize() * 8 * k|, but
+ // current versions of the MSF format already expect the Fpm to be arranged
+ // at getBlockSize() intervals, so we have to be compatible.
+ // See the function fpmPn() for more information:
+ // https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/msf/msf.cpp#L489
+ auto FpmStream =
+ MappedBlockStream::createFpmStream(ContainerLayout, *Buffer, Allocator);
+ BinaryStreamReader FpmReader(*FpmStream);
+ ArrayRef<uint8_t> FpmBytes;
+ if (auto EC = FpmReader.readBytes(FpmBytes, FpmReader.bytesRemaining()))
+ return EC;
+ uint32_t BlocksRemaining = getBlockCount();
+ uint32_t BI = 0;
+ for (auto Byte : FpmBytes) {
+ uint32_t BlocksThisByte = std::min(BlocksRemaining, 8U);
+ for (uint32_t I = 0; I < BlocksThisByte; ++I) {
+ if (Byte & (1 << I))
+ ContainerLayout.FreePageMap[BI] = true;
+ --BlocksRemaining;
+ ++BI;
+ }
+ }
+
+ Reader.setOffset(getBlockMapOffset());
+ if (auto EC = Reader.readArray(ContainerLayout.DirectoryBlocks,
+ getNumDirectoryBlocks()))
+ return EC;
+
+ return Error::success();
+}
+
+Error PDBFile::parseStreamData() {
+ assert(ContainerLayout.SB);
+ if (DirectoryStream)
+ return Error::success();
+
+ uint32_t NumStreams = 0;
+
+ // Normally you can't use a MappedBlockStream without having fully parsed the
+ // PDB file, because it accesses the directory and various other things, which
+ // is exactly what we are attempting to parse. By specifying a custom
+ // subclass of IPDBStreamData which only accesses the fields that have already
+ // been parsed, we can avoid this and reuse MappedBlockStream.
+ auto DS = MappedBlockStream::createDirectoryStream(ContainerLayout, *Buffer,
+ Allocator);
+ BinaryStreamReader Reader(*DS);
+ if (auto EC = Reader.readInteger(NumStreams))
+ return EC;
+
+ if (auto EC = Reader.readArray(ContainerLayout.StreamSizes, NumStreams))
+ return EC;
+ for (uint32_t I = 0; I < NumStreams; ++I) {
+ uint32_t StreamSize = getStreamByteSize(I);
+ // FIXME: What does StreamSize ~0U mean?
+ uint64_t NumExpectedStreamBlocks =
+ StreamSize == UINT32_MAX
+ ? 0
+ : msf::bytesToBlocks(StreamSize, ContainerLayout.SB->BlockSize);
+
+ // For convenience, we store the block array contiguously. This is because
+ // if someone calls setStreamMap(), it is more convenient to be able to call
+ // it with an ArrayRef instead of setting up a StreamRef. Since the
+ // DirectoryStream is cached in the class and thus lives for the life of the
+ // class, we can be guaranteed that readArray() will return a stable
+ // reference, even if it has to allocate from its internal pool.
+ ArrayRef<support::ulittle32_t> Blocks;
+ if (auto EC = Reader.readArray(Blocks, NumExpectedStreamBlocks))
+ return EC;
+ for (uint32_t Block : Blocks) {
+ uint64_t BlockEndOffset =
+ (uint64_t)(Block + 1) * ContainerLayout.SB->BlockSize;
+ if (BlockEndOffset > getFileSize())
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Stream block map is corrupt.");
+ }
+ ContainerLayout.StreamMap.push_back(Blocks);
+ }
+
+ // We should have read exactly SB->NumDirectoryBytes bytes.
+ assert(Reader.bytesRemaining() == 0);
+ DirectoryStream = std::move(DS);
+ return Error::success();
+}
+
+ArrayRef<support::ulittle32_t> PDBFile::getDirectoryBlockArray() const {
+ return ContainerLayout.DirectoryBlocks;
+}
+
+std::unique_ptr<MappedBlockStream>
+PDBFile::createIndexedStream(uint16_t SN) const {
+ if (SN == kInvalidStreamIndex)
+ return nullptr;
+ return MappedBlockStream::createIndexedStream(ContainerLayout, *Buffer, SN,
+ Allocator);
+}
+
+MSFStreamLayout PDBFile::getStreamLayout(uint32_t StreamIdx) const {
+ MSFStreamLayout Result;
+ auto Blocks = getStreamBlockList(StreamIdx);
+ Result.Blocks.assign(Blocks.begin(), Blocks.end());
+ Result.Length = getStreamByteSize(StreamIdx);
+ return Result;
+}
+
+msf::MSFStreamLayout PDBFile::getFpmStreamLayout() const {
+ return msf::getFpmStreamLayout(ContainerLayout);
+}
+
+Expected<GlobalsStream &> PDBFile::getPDBGlobalsStream() {
+ if (!Globals) {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS)
+ return DbiS.takeError();
+
+ auto GlobalS =
+ safelyCreateIndexedStream(DbiS->getGlobalSymbolStreamIndex());
+ if (!GlobalS)
+ return GlobalS.takeError();
+ auto TempGlobals = std::make_unique<GlobalsStream>(std::move(*GlobalS));
+ if (auto EC = TempGlobals->reload())
+ return std::move(EC);
+ Globals = std::move(TempGlobals);
+ }
+ return *Globals;
+}
+
+Expected<InfoStream &> PDBFile::getPDBInfoStream() {
+ if (!Info) {
+ auto InfoS = safelyCreateIndexedStream(StreamPDB);
+ if (!InfoS)
+ return InfoS.takeError();
+ auto TempInfo = std::make_unique<InfoStream>(std::move(*InfoS));
+ if (auto EC = TempInfo->reload())
+ return std::move(EC);
+ Info = std::move(TempInfo);
+ }
+ return *Info;
+}
+
+Expected<DbiStream &> PDBFile::getPDBDbiStream() {
+ if (!Dbi) {
+ auto DbiS = safelyCreateIndexedStream(StreamDBI);
+ if (!DbiS)
+ return DbiS.takeError();
+ auto TempDbi = std::make_unique<DbiStream>(std::move(*DbiS));
+ if (auto EC = TempDbi->reload(this))
+ return std::move(EC);
+ Dbi = std::move(TempDbi);
+ }
+ return *Dbi;
+}
+
+Expected<TpiStream &> PDBFile::getPDBTpiStream() {
+ if (!Tpi) {
+ auto TpiS = safelyCreateIndexedStream(StreamTPI);
+ if (!TpiS)
+ return TpiS.takeError();
+ auto TempTpi = std::make_unique<TpiStream>(*this, std::move(*TpiS));
+ if (auto EC = TempTpi->reload())
+ return std::move(EC);
+ Tpi = std::move(TempTpi);
+ }
+ return *Tpi;
+}
+
+Expected<TpiStream &> PDBFile::getPDBIpiStream() {
+ if (!Ipi) {
+ if (!hasPDBIpiStream())
+ return make_error<RawError>(raw_error_code::no_stream);
+
+ auto IpiS = safelyCreateIndexedStream(StreamIPI);
+ if (!IpiS)
+ return IpiS.takeError();
+ auto TempIpi = std::make_unique<TpiStream>(*this, std::move(*IpiS));
+ if (auto EC = TempIpi->reload())
+ return std::move(EC);
+ Ipi = std::move(TempIpi);
+ }
+ return *Ipi;
+}
+
+Expected<PublicsStream &> PDBFile::getPDBPublicsStream() {
+ if (!Publics) {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS)
+ return DbiS.takeError();
+
+ auto PublicS =
+ safelyCreateIndexedStream(DbiS->getPublicSymbolStreamIndex());
+ if (!PublicS)
+ return PublicS.takeError();
+ auto TempPublics = std::make_unique<PublicsStream>(std::move(*PublicS));
+ if (auto EC = TempPublics->reload())
+ return std::move(EC);
+ Publics = std::move(TempPublics);
+ }
+ return *Publics;
+}
+
+Expected<SymbolStream &> PDBFile::getPDBSymbolStream() {
+ if (!Symbols) {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS)
+ return DbiS.takeError();
+
+ uint32_t SymbolStreamNum = DbiS->getSymRecordStreamIndex();
+ auto SymbolS = safelyCreateIndexedStream(SymbolStreamNum);
+ if (!SymbolS)
+ return SymbolS.takeError();
+
+ auto TempSymbols = std::make_unique<SymbolStream>(std::move(*SymbolS));
+ if (auto EC = TempSymbols->reload())
+ return std::move(EC);
+ Symbols = std::move(TempSymbols);
+ }
+ return *Symbols;
+}
+
+Expected<PDBStringTable &> PDBFile::getStringTable() {
+ if (!Strings) {
+ auto NS = safelyCreateNamedStream("/names");
+ if (!NS)
+ return NS.takeError();
+
+ auto N = std::make_unique<PDBStringTable>();
+ BinaryStreamReader Reader(**NS);
+ if (auto EC = N->reload(Reader))
+ return std::move(EC);
+ assert(Reader.bytesRemaining() == 0);
+ StringTableStream = std::move(*NS);
+ Strings = std::move(N);
+ }
+ 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 = std::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)
+ return 0;
+ PDB_Machine Machine = DbiS->getMachineType();
+ if (Machine == PDB_Machine::Amd64)
+ return 8;
+ return 4;
+}
+
+bool PDBFile::hasPDBDbiStream() const {
+ return StreamDBI < getNumStreams() && getStreamByteSize(StreamDBI) > 0;
+}
+
+bool PDBFile::hasPDBGlobalsStream() {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS) {
+ consumeError(DbiS.takeError());
+ return false;
+ }
+
+ return DbiS->getGlobalSymbolStreamIndex() < getNumStreams();
+}
+
+bool PDBFile::hasPDBInfoStream() const { return StreamPDB < getNumStreams(); }
+
+bool PDBFile::hasPDBIpiStream() const {
+ if (!hasPDBInfoStream())
+ return false;
+
+ if (StreamIPI >= getNumStreams())
+ return false;
+
+ auto &InfoStream = cantFail(const_cast<PDBFile *>(this)->getPDBInfoStream());
+ return InfoStream.containsIdStream();
+}
+
+bool PDBFile::hasPDBPublicsStream() {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS) {
+ consumeError(DbiS.takeError());
+ return false;
+ }
+ return DbiS->getPublicSymbolStreamIndex() < getNumStreams();
+}
+
+bool PDBFile::hasPDBSymbolStream() {
+ auto DbiS = getPDBDbiStream();
+ if (!DbiS)
+ return false;
+ return DbiS->getSymRecordStreamIndex() < getNumStreams();
+}
+
+bool PDBFile::hasPDBTpiStream() const { return StreamTPI < getNumStreams(); }
+
+bool PDBFile::hasPDBStringTable() {
+ auto IS = getPDBInfoStream();
+ if (!IS)
+ return false;
+ Expected<uint32_t> ExpectedNSI = IS->getNamedStreamIndex("/names");
+ if (!ExpectedNSI) {
+ consumeError(ExpectedNSI.takeError());
+ return false;
+ }
+ assert(*ExpectedNSI < getNumStreams());
+ 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(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 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/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
index deb0f201a7..cc89a4ae9d 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
@@ -1,356 +1,356 @@
-//===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
-#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
-#include "llvm/Support/BinaryStream.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/CRC.h"
-#include "llvm/Support/Chrono.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/xxhash.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-using namespace llvm::support;
-
-PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
- : Allocator(Allocator), InjectedSourceHashTraits(Strings),
- InjectedSourceTable(2) {}
-
-PDBFileBuilder::~PDBFileBuilder() {}
-
-Error PDBFileBuilder::initialize(uint32_t BlockSize) {
- auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
- if (!ExpectedMsf)
- return ExpectedMsf.takeError();
- Msf = std::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
- return Error::success();
-}
-
-MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
-
-InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
- if (!Info)
- Info = std::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
- return *Info;
-}
-
-DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
- if (!Dbi)
- Dbi = std::make_unique<DbiStreamBuilder>(*Msf);
- return *Dbi;
-}
-
-TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
- if (!Tpi)
- Tpi = std::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
- return *Tpi;
-}
-
-TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
- if (!Ipi)
- Ipi = std::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
- return *Ipi;
-}
-
-PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
- return Strings;
-}
-
-GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() {
- if (!Gsi)
- Gsi = std::make_unique<GSIStreamBuilder>(*Msf);
- return *Gsi;
-}
-
-Expected<uint32_t> PDBFileBuilder::allocateNamedStream(StringRef Name,
- uint32_t Size) {
- auto ExpectedStream = Msf->addStream(Size);
- if (ExpectedStream)
- NamedStreams.set(Name, *ExpectedStream);
- return ExpectedStream;
-}
-
-Error PDBFileBuilder::addNamedStream(StringRef Name, StringRef Data) {
- Expected<uint32_t> ExpectedIndex = allocateNamedStream(Name, Data.size());
- if (!ExpectedIndex)
- return ExpectedIndex.takeError();
- assert(NamedStreamData.count(*ExpectedIndex) == 0);
- NamedStreamData[*ExpectedIndex] = std::string(Data);
- return Error::success();
-}
-
-void PDBFileBuilder::addInjectedSource(StringRef Name,
- std::unique_ptr<MemoryBuffer> Buffer) {
- // Stream names must be exact matches, since they get looked up in a hash
- // table and the hash value is dependent on the exact contents of the string.
- // link.exe lowercases a path and converts / to \, so we must do the same.
- SmallString<64> VName;
- sys::path::native(Name.lower(), VName);
-
- uint32_t NI = getStringTableBuilder().insert(Name);
- uint32_t VNI = getStringTableBuilder().insert(VName);
-
- InjectedSourceDescriptor Desc;
- Desc.Content = std::move(Buffer);
- Desc.NameIndex = NI;
- Desc.VNameIndex = VNI;
- Desc.StreamName = "/src/files/";
-
- Desc.StreamName += VName;
-
- InjectedSources.push_back(std::move(Desc));
-}
-
-Error PDBFileBuilder::finalizeMsfLayout() {
-
- if (Ipi && Ipi->getRecordCount() > 0) {
- // In theory newer PDBs always have an ID stream, but by saying that we're
- // only going to *really* have an ID stream if there is at least one ID
- // record, we leave open the opportunity to test older PDBs such as those
- // that don't have an ID stream.
- auto &Info = getInfoBuilder();
- Info.addFeature(PdbRaw_FeatureSig::VC140);
- }
-
- uint32_t StringsLen = Strings.calculateSerializedSize();
-
- Expected<uint32_t> SN = allocateNamedStream("/LinkInfo", 0);
- if (!SN)
- return SN.takeError();
-
- if (Gsi) {
- if (auto EC = Gsi->finalizeMsfLayout())
- return EC;
- if (Dbi) {
- Dbi->setPublicsStreamIndex(Gsi->getPublicsStreamIndex());
- Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex());
- Dbi->setSymbolRecordStreamIndex(Gsi->getRecordStreamIndex());
- }
- }
- if (Tpi) {
- if (auto EC = Tpi->finalizeMsfLayout())
- return EC;
- }
- if (Dbi) {
- if (auto EC = Dbi->finalizeMsfLayout())
- return EC;
- }
- SN = allocateNamedStream("/names", StringsLen);
- if (!SN)
- return SN.takeError();
-
- if (Ipi) {
- if (auto EC = Ipi->finalizeMsfLayout())
- return EC;
- }
-
- // Do this last, since it relies on the named stream map being complete, and
- // that can be updated by previous steps in the finalization.
- if (Info) {
- if (auto EC = Info->finalizeMsfLayout())
- return EC;
- }
-
- if (!InjectedSources.empty()) {
- for (const auto &IS : InjectedSources) {
- JamCRC CRC(0);
- CRC.update(arrayRefFromStringRef(IS.Content->getBuffer()));
-
- SrcHeaderBlockEntry Entry;
- ::memset(&Entry, 0, sizeof(SrcHeaderBlockEntry));
- Entry.Size = sizeof(SrcHeaderBlockEntry);
- Entry.FileSize = IS.Content->getBufferSize();
- Entry.FileNI = IS.NameIndex;
- Entry.VFileNI = IS.VNameIndex;
- Entry.ObjNI = 1;
- Entry.IsVirtual = 0;
- Entry.Version =
- static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne);
- Entry.CRC = CRC.getCRC();
- StringRef VName = getStringTableBuilder().getStringForId(IS.VNameIndex);
- InjectedSourceTable.set_as(VName, std::move(Entry),
- InjectedSourceHashTraits);
- }
-
- uint32_t SrcHeaderBlockSize =
- sizeof(SrcHeaderBlockHeader) +
- InjectedSourceTable.calculateSerializedLength();
- SN = allocateNamedStream("/src/headerblock", SrcHeaderBlockSize);
- if (!SN)
- return SN.takeError();
- for (const auto &IS : InjectedSources) {
- SN = allocateNamedStream(IS.StreamName, IS.Content->getBufferSize());
- if (!SN)
- return SN.takeError();
- }
- }
-
- // Do this last, since it relies on the named stream map being complete, and
- // that can be updated by previous steps in the finalization.
- if (Info) {
- if (auto EC = Info->finalizeMsfLayout())
- return EC;
- }
-
- return Error::success();
-}
-
-Expected<uint32_t> PDBFileBuilder::getNamedStreamIndex(StringRef Name) const {
- uint32_t SN = 0;
- if (!NamedStreams.get(Name, SN))
- return llvm::make_error<pdb::RawError>(raw_error_code::no_stream);
- return SN;
-}
-
-void PDBFileBuilder::commitSrcHeaderBlock(WritableBinaryStream &MsfBuffer,
- const msf::MSFLayout &Layout) {
- assert(!InjectedSourceTable.empty());
-
- uint32_t SN = cantFail(getNamedStreamIndex("/src/headerblock"));
- auto Stream = WritableMappedBlockStream::createIndexedStream(
- Layout, MsfBuffer, SN, Allocator);
- BinaryStreamWriter Writer(*Stream);
-
- SrcHeaderBlockHeader Header;
- ::memset(&Header, 0, sizeof(Header));
- Header.Version = static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne);
- Header.Size = Writer.bytesRemaining();
-
- cantFail(Writer.writeObject(Header));
- cantFail(InjectedSourceTable.commit(Writer));
-
- assert(Writer.bytesRemaining() == 0);
-}
-
-void PDBFileBuilder::commitInjectedSources(WritableBinaryStream &MsfBuffer,
- const msf::MSFLayout &Layout) {
- if (InjectedSourceTable.empty())
- return;
-
- commitSrcHeaderBlock(MsfBuffer, Layout);
-
- for (const auto &IS : InjectedSources) {
- uint32_t SN = cantFail(getNamedStreamIndex(IS.StreamName));
-
- auto SourceStream = WritableMappedBlockStream::createIndexedStream(
- Layout, MsfBuffer, SN, Allocator);
- BinaryStreamWriter SourceWriter(*SourceStream);
- assert(SourceWriter.bytesRemaining() == IS.Content->getBufferSize());
- cantFail(SourceWriter.writeBytes(
- arrayRefFromStringRef(IS.Content->getBuffer())));
- }
-}
-
-Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
- assert(!Filename.empty());
- if (auto EC = finalizeMsfLayout())
- return EC;
-
- MSFLayout Layout;
- Expected<FileBufferByteStream> ExpectedMsfBuffer =
- Msf->commit(Filename, Layout);
- if (!ExpectedMsfBuffer)
- return ExpectedMsfBuffer.takeError();
- FileBufferByteStream Buffer = std::move(*ExpectedMsfBuffer);
-
- auto ExpectedSN = getNamedStreamIndex("/names");
- if (!ExpectedSN)
- return ExpectedSN.takeError();
-
- auto NS = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, *ExpectedSN, Allocator);
- BinaryStreamWriter NSWriter(*NS);
- if (auto EC = Strings.commit(NSWriter))
- return EC;
-
- for (const auto &NSE : NamedStreamData) {
- if (NSE.second.empty())
- continue;
-
- auto NS = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, NSE.first, Allocator);
- BinaryStreamWriter NSW(*NS);
- if (auto EC = NSW.writeBytes(arrayRefFromStringRef(NSE.second)))
- return EC;
- }
-
- if (Info) {
- if (auto EC = Info->commit(Layout, Buffer))
- return EC;
- }
-
- if (Dbi) {
- if (auto EC = Dbi->commit(Layout, Buffer))
- return EC;
- }
-
- if (Tpi) {
- if (auto EC = Tpi->commit(Layout, Buffer))
- return EC;
- }
-
- if (Ipi) {
- if (auto EC = Ipi->commit(Layout, Buffer))
- return EC;
- }
-
- if (Gsi) {
- if (auto EC = Gsi->commit(Layout, Buffer))
- return EC;
- }
-
- auto InfoStreamBlocks = Layout.StreamMap[StreamPDB];
- assert(!InfoStreamBlocks.empty());
- uint64_t InfoStreamFileOffset =
- blockToOffset(InfoStreamBlocks.front(), Layout.SB->BlockSize);
- InfoStreamHeader *H = reinterpret_cast<InfoStreamHeader *>(
- Buffer.getBufferStart() + InfoStreamFileOffset);
-
- commitInjectedSources(Buffer, Layout);
-
- // Set the build id at the very end, after every other byte of the PDB
- // has been written.
- if (Info->hashPDBContentsToGUID()) {
- // Compute a hash of all sections of the output file.
- uint64_t Digest =
- xxHash64({Buffer.getBufferStart(), Buffer.getBufferEnd()});
-
- H->Age = 1;
-
- memcpy(H->Guid.Guid, &Digest, 8);
- // xxhash only gives us 8 bytes, so put some fixed data in the other half.
- memcpy(H->Guid.Guid + 8, "LLD PDB.", 8);
-
- // Put the hash in the Signature field too.
- H->Signature = static_cast<uint32_t>(Digest);
-
- // Return GUID to caller.
- memcpy(Guid, H->Guid.Guid, 16);
- } else {
- H->Age = Info->getAge();
- H->Guid = Info->getGuid();
- Optional<uint32_t> Sig = Info->getSignature();
- H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
- }
-
- return Buffer.commit();
-}
+//===- PDBFileBuilder.cpp - PDB File Creation -------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/GSIStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
+#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
+#include "llvm/Support/BinaryStream.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/CRC.h"
+#include "llvm/Support/Chrono.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/xxhash.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
+ : Allocator(Allocator), InjectedSourceHashTraits(Strings),
+ InjectedSourceTable(2) {}
+
+PDBFileBuilder::~PDBFileBuilder() {}
+
+Error PDBFileBuilder::initialize(uint32_t BlockSize) {
+ auto ExpectedMsf = MSFBuilder::create(Allocator, BlockSize);
+ if (!ExpectedMsf)
+ return ExpectedMsf.takeError();
+ Msf = std::make_unique<MSFBuilder>(std::move(*ExpectedMsf));
+ return Error::success();
+}
+
+MSFBuilder &PDBFileBuilder::getMsfBuilder() { return *Msf; }
+
+InfoStreamBuilder &PDBFileBuilder::getInfoBuilder() {
+ if (!Info)
+ Info = std::make_unique<InfoStreamBuilder>(*Msf, NamedStreams);
+ return *Info;
+}
+
+DbiStreamBuilder &PDBFileBuilder::getDbiBuilder() {
+ if (!Dbi)
+ Dbi = std::make_unique<DbiStreamBuilder>(*Msf);
+ return *Dbi;
+}
+
+TpiStreamBuilder &PDBFileBuilder::getTpiBuilder() {
+ if (!Tpi)
+ Tpi = std::make_unique<TpiStreamBuilder>(*Msf, StreamTPI);
+ return *Tpi;
+}
+
+TpiStreamBuilder &PDBFileBuilder::getIpiBuilder() {
+ if (!Ipi)
+ Ipi = std::make_unique<TpiStreamBuilder>(*Msf, StreamIPI);
+ return *Ipi;
+}
+
+PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
+ return Strings;
+}
+
+GSIStreamBuilder &PDBFileBuilder::getGsiBuilder() {
+ if (!Gsi)
+ Gsi = std::make_unique<GSIStreamBuilder>(*Msf);
+ return *Gsi;
+}
+
+Expected<uint32_t> PDBFileBuilder::allocateNamedStream(StringRef Name,
+ uint32_t Size) {
+ auto ExpectedStream = Msf->addStream(Size);
+ if (ExpectedStream)
+ NamedStreams.set(Name, *ExpectedStream);
+ return ExpectedStream;
+}
+
+Error PDBFileBuilder::addNamedStream(StringRef Name, StringRef Data) {
+ Expected<uint32_t> ExpectedIndex = allocateNamedStream(Name, Data.size());
+ if (!ExpectedIndex)
+ return ExpectedIndex.takeError();
+ assert(NamedStreamData.count(*ExpectedIndex) == 0);
+ NamedStreamData[*ExpectedIndex] = std::string(Data);
+ return Error::success();
+}
+
+void PDBFileBuilder::addInjectedSource(StringRef Name,
+ std::unique_ptr<MemoryBuffer> Buffer) {
+ // Stream names must be exact matches, since they get looked up in a hash
+ // table and the hash value is dependent on the exact contents of the string.
+ // link.exe lowercases a path and converts / to \, so we must do the same.
+ SmallString<64> VName;
+ sys::path::native(Name.lower(), VName);
+
+ uint32_t NI = getStringTableBuilder().insert(Name);
+ uint32_t VNI = getStringTableBuilder().insert(VName);
+
+ InjectedSourceDescriptor Desc;
+ Desc.Content = std::move(Buffer);
+ Desc.NameIndex = NI;
+ Desc.VNameIndex = VNI;
+ Desc.StreamName = "/src/files/";
+
+ Desc.StreamName += VName;
+
+ InjectedSources.push_back(std::move(Desc));
+}
+
+Error PDBFileBuilder::finalizeMsfLayout() {
+
+ if (Ipi && Ipi->getRecordCount() > 0) {
+ // In theory newer PDBs always have an ID stream, but by saying that we're
+ // only going to *really* have an ID stream if there is at least one ID
+ // record, we leave open the opportunity to test older PDBs such as those
+ // that don't have an ID stream.
+ auto &Info = getInfoBuilder();
+ Info.addFeature(PdbRaw_FeatureSig::VC140);
+ }
+
+ uint32_t StringsLen = Strings.calculateSerializedSize();
+
+ Expected<uint32_t> SN = allocateNamedStream("/LinkInfo", 0);
+ if (!SN)
+ return SN.takeError();
+
+ if (Gsi) {
+ if (auto EC = Gsi->finalizeMsfLayout())
+ return EC;
+ if (Dbi) {
+ Dbi->setPublicsStreamIndex(Gsi->getPublicsStreamIndex());
+ Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex());
+ Dbi->setSymbolRecordStreamIndex(Gsi->getRecordStreamIndex());
+ }
+ }
+ if (Tpi) {
+ if (auto EC = Tpi->finalizeMsfLayout())
+ return EC;
+ }
+ if (Dbi) {
+ if (auto EC = Dbi->finalizeMsfLayout())
+ return EC;
+ }
+ SN = allocateNamedStream("/names", StringsLen);
+ if (!SN)
+ return SN.takeError();
+
+ if (Ipi) {
+ if (auto EC = Ipi->finalizeMsfLayout())
+ return EC;
+ }
+
+ // Do this last, since it relies on the named stream map being complete, and
+ // that can be updated by previous steps in the finalization.
+ if (Info) {
+ if (auto EC = Info->finalizeMsfLayout())
+ return EC;
+ }
+
+ if (!InjectedSources.empty()) {
+ for (const auto &IS : InjectedSources) {
+ JamCRC CRC(0);
+ CRC.update(arrayRefFromStringRef(IS.Content->getBuffer()));
+
+ SrcHeaderBlockEntry Entry;
+ ::memset(&Entry, 0, sizeof(SrcHeaderBlockEntry));
+ Entry.Size = sizeof(SrcHeaderBlockEntry);
+ Entry.FileSize = IS.Content->getBufferSize();
+ Entry.FileNI = IS.NameIndex;
+ Entry.VFileNI = IS.VNameIndex;
+ Entry.ObjNI = 1;
+ Entry.IsVirtual = 0;
+ Entry.Version =
+ static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne);
+ Entry.CRC = CRC.getCRC();
+ StringRef VName = getStringTableBuilder().getStringForId(IS.VNameIndex);
+ InjectedSourceTable.set_as(VName, std::move(Entry),
+ InjectedSourceHashTraits);
+ }
+
+ uint32_t SrcHeaderBlockSize =
+ sizeof(SrcHeaderBlockHeader) +
+ InjectedSourceTable.calculateSerializedLength();
+ SN = allocateNamedStream("/src/headerblock", SrcHeaderBlockSize);
+ if (!SN)
+ return SN.takeError();
+ for (const auto &IS : InjectedSources) {
+ SN = allocateNamedStream(IS.StreamName, IS.Content->getBufferSize());
+ if (!SN)
+ return SN.takeError();
+ }
+ }
+
+ // Do this last, since it relies on the named stream map being complete, and
+ // that can be updated by previous steps in the finalization.
+ if (Info) {
+ if (auto EC = Info->finalizeMsfLayout())
+ return EC;
+ }
+
+ return Error::success();
+}
+
+Expected<uint32_t> PDBFileBuilder::getNamedStreamIndex(StringRef Name) const {
+ uint32_t SN = 0;
+ if (!NamedStreams.get(Name, SN))
+ return llvm::make_error<pdb::RawError>(raw_error_code::no_stream);
+ return SN;
+}
+
+void PDBFileBuilder::commitSrcHeaderBlock(WritableBinaryStream &MsfBuffer,
+ const msf::MSFLayout &Layout) {
+ assert(!InjectedSourceTable.empty());
+
+ uint32_t SN = cantFail(getNamedStreamIndex("/src/headerblock"));
+ auto Stream = WritableMappedBlockStream::createIndexedStream(
+ Layout, MsfBuffer, SN, Allocator);
+ BinaryStreamWriter Writer(*Stream);
+
+ SrcHeaderBlockHeader Header;
+ ::memset(&Header, 0, sizeof(Header));
+ Header.Version = static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne);
+ Header.Size = Writer.bytesRemaining();
+
+ cantFail(Writer.writeObject(Header));
+ cantFail(InjectedSourceTable.commit(Writer));
+
+ assert(Writer.bytesRemaining() == 0);
+}
+
+void PDBFileBuilder::commitInjectedSources(WritableBinaryStream &MsfBuffer,
+ const msf::MSFLayout &Layout) {
+ if (InjectedSourceTable.empty())
+ return;
+
+ commitSrcHeaderBlock(MsfBuffer, Layout);
+
+ for (const auto &IS : InjectedSources) {
+ uint32_t SN = cantFail(getNamedStreamIndex(IS.StreamName));
+
+ auto SourceStream = WritableMappedBlockStream::createIndexedStream(
+ Layout, MsfBuffer, SN, Allocator);
+ BinaryStreamWriter SourceWriter(*SourceStream);
+ assert(SourceWriter.bytesRemaining() == IS.Content->getBufferSize());
+ cantFail(SourceWriter.writeBytes(
+ arrayRefFromStringRef(IS.Content->getBuffer())));
+ }
+}
+
+Error PDBFileBuilder::commit(StringRef Filename, codeview::GUID *Guid) {
+ assert(!Filename.empty());
+ if (auto EC = finalizeMsfLayout())
+ return EC;
+
+ MSFLayout Layout;
+ Expected<FileBufferByteStream> ExpectedMsfBuffer =
+ Msf->commit(Filename, Layout);
+ if (!ExpectedMsfBuffer)
+ return ExpectedMsfBuffer.takeError();
+ FileBufferByteStream Buffer = std::move(*ExpectedMsfBuffer);
+
+ auto ExpectedSN = getNamedStreamIndex("/names");
+ if (!ExpectedSN)
+ return ExpectedSN.takeError();
+
+ auto NS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, *ExpectedSN, Allocator);
+ BinaryStreamWriter NSWriter(*NS);
+ if (auto EC = Strings.commit(NSWriter))
+ return EC;
+
+ for (const auto &NSE : NamedStreamData) {
+ if (NSE.second.empty())
+ continue;
+
+ auto NS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, NSE.first, Allocator);
+ BinaryStreamWriter NSW(*NS);
+ if (auto EC = NSW.writeBytes(arrayRefFromStringRef(NSE.second)))
+ return EC;
+ }
+
+ if (Info) {
+ if (auto EC = Info->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Dbi) {
+ if (auto EC = Dbi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Tpi) {
+ if (auto EC = Tpi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Ipi) {
+ if (auto EC = Ipi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ if (Gsi) {
+ if (auto EC = Gsi->commit(Layout, Buffer))
+ return EC;
+ }
+
+ auto InfoStreamBlocks = Layout.StreamMap[StreamPDB];
+ assert(!InfoStreamBlocks.empty());
+ uint64_t InfoStreamFileOffset =
+ blockToOffset(InfoStreamBlocks.front(), Layout.SB->BlockSize);
+ InfoStreamHeader *H = reinterpret_cast<InfoStreamHeader *>(
+ Buffer.getBufferStart() + InfoStreamFileOffset);
+
+ commitInjectedSources(Buffer, Layout);
+
+ // Set the build id at the very end, after every other byte of the PDB
+ // has been written.
+ if (Info->hashPDBContentsToGUID()) {
+ // Compute a hash of all sections of the output file.
+ uint64_t Digest =
+ xxHash64({Buffer.getBufferStart(), Buffer.getBufferEnd()});
+
+ H->Age = 1;
+
+ memcpy(H->Guid.Guid, &Digest, 8);
+ // xxhash only gives us 8 bytes, so put some fixed data in the other half.
+ memcpy(H->Guid.Guid + 8, "LLD PDB.", 8);
+
+ // Put the hash in the Signature field too.
+ H->Signature = static_cast<uint32_t>(Digest);
+
+ // Return GUID to caller.
+ memcpy(Guid, H->Guid.Guid, 16);
+ } else {
+ H->Age = Info->getAge();
+ H->Guid = Info->getGuid();
+ Optional<uint32_t> Sig = Info->getSignature();
+ H->Signature = Sig.hasValue() ? *Sig : time(nullptr);
+ }
+
+ return Buffer.commit();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTable.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
index 2be1656e06..7c2f507229 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTable.cpp
@@ -1,140 +1,140 @@
-//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Endian.h"
-
-using namespace llvm;
-using namespace llvm::support;
-using namespace llvm::pdb;
-
-uint32_t PDBStringTable::getByteSize() const { return Header->ByteSize; }
-uint32_t PDBStringTable::getNameCount() const { return NameCount; }
-uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
-uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
-
-Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
- if (auto EC = Reader.readObject(Header))
- return EC;
-
- if (Header->Signature != PDBStringTableSignature)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid hash table signature");
- if (Header->HashVersion != 1 && Header->HashVersion != 2)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Unsupported hash version");
-
- assert(Reader.bytesRemaining() == 0);
- return Error::success();
-}
-
-Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
- BinaryStreamRef Stream;
- if (auto EC = Reader.readStreamRef(Stream))
- return EC;
-
- if (auto EC = Strings.initialize(Stream)) {
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Invalid hash table byte length"));
- }
-
- assert(Reader.bytesRemaining() == 0);
- return Error::success();
-}
-
-const codeview::DebugStringTableSubsectionRef &
-PDBStringTable::getStringTable() const {
- return Strings;
-}
-
-Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
- const support::ulittle32_t *HashCount;
- if (auto EC = Reader.readObject(HashCount))
- return EC;
-
- if (auto EC = Reader.readArray(IDs, *HashCount)) {
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read bucket array"));
- }
-
- return Error::success();
-}
-
-Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
- if (auto EC = Reader.readInteger(NameCount))
- return EC;
-
- assert(Reader.bytesRemaining() == 0);
- return Error::success();
-}
-
-Error PDBStringTable::reload(BinaryStreamReader &Reader) {
-
- BinaryStreamReader SectionReader;
-
- std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
- if (auto EC = readHeader(SectionReader))
- return EC;
-
- std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
- if (auto EC = readStrings(SectionReader))
- return EC;
-
- // We don't know how long the hash table is until we parse it, so let the
- // function responsible for doing that figure it out.
- if (auto EC = readHashTable(Reader))
- return EC;
-
- std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
- if (auto EC = readEpilogue(SectionReader))
- return EC;
-
- assert(Reader.bytesRemaining() == 0);
- return Error::success();
-}
-
-Expected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const {
- return Strings.getString(ID);
-}
-
-Expected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const {
- uint32_t Hash =
- (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
- size_t Count = IDs.size();
- uint32_t Start = Hash % Count;
- for (size_t I = 0; I < Count; ++I) {
- // The hash is just a starting point for the search, but if it
- // doesn't work we should find the string no matter what, because
- // we iterate the entire array.
- uint32_t Index = (Start + I) % Count;
-
- // If we find 0, it means the item isn't in the hash table.
- uint32_t ID = IDs[Index];
- if (ID == 0)
- return make_error<RawError>(raw_error_code::no_entry);
- auto ExpectedStr = getStringForID(ID);
- if (!ExpectedStr)
- return ExpectedStr.takeError();
-
- if (*ExpectedStr == Str)
- return ID;
- }
- return make_error<RawError>(raw_error_code::no_entry);
-}
-
-FixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {
- return IDs;
-}
+//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+
+using namespace llvm;
+using namespace llvm::support;
+using namespace llvm::pdb;
+
+uint32_t PDBStringTable::getByteSize() const { return Header->ByteSize; }
+uint32_t PDBStringTable::getNameCount() const { return NameCount; }
+uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
+uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
+
+Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
+ if (auto EC = Reader.readObject(Header))
+ return EC;
+
+ if (Header->Signature != PDBStringTableSignature)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid hash table signature");
+ if (Header->HashVersion != 1 && Header->HashVersion != 2)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Unsupported hash version");
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
+ BinaryStreamRef Stream;
+ if (auto EC = Reader.readStreamRef(Stream))
+ return EC;
+
+ if (auto EC = Strings.initialize(Stream)) {
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Invalid hash table byte length"));
+ }
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+const codeview::DebugStringTableSubsectionRef &
+PDBStringTable::getStringTable() const {
+ return Strings;
+}
+
+Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
+ const support::ulittle32_t *HashCount;
+ if (auto EC = Reader.readObject(HashCount))
+ return EC;
+
+ if (auto EC = Reader.readArray(IDs, *HashCount)) {
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read bucket array"));
+ }
+
+ return Error::success();
+}
+
+Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
+ if (auto EC = Reader.readInteger(NameCount))
+ return EC;
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTable::reload(BinaryStreamReader &Reader) {
+
+ BinaryStreamReader SectionReader;
+
+ std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
+ if (auto EC = readHeader(SectionReader))
+ return EC;
+
+ std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
+ if (auto EC = readStrings(SectionReader))
+ return EC;
+
+ // We don't know how long the hash table is until we parse it, so let the
+ // function responsible for doing that figure it out.
+ if (auto EC = readHashTable(Reader))
+ return EC;
+
+ std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
+ if (auto EC = readEpilogue(SectionReader))
+ return EC;
+
+ assert(Reader.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Expected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const {
+ return Strings.getString(ID);
+}
+
+Expected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const {
+ uint32_t Hash =
+ (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
+ size_t Count = IDs.size();
+ uint32_t Start = Hash % Count;
+ for (size_t I = 0; I < Count; ++I) {
+ // The hash is just a starting point for the search, but if it
+ // doesn't work we should find the string no matter what, because
+ // we iterate the entire array.
+ uint32_t Index = (Start + I) % Count;
+
+ // If we find 0, it means the item isn't in the hash table.
+ uint32_t ID = IDs[Index];
+ if (ID == 0)
+ return make_error<RawError>(raw_error_code::no_entry);
+ auto ExpectedStr = getStringForID(ID);
+ if (!ExpectedStr)
+ return ExpectedStr.takeError();
+
+ if (*ExpectedStr == Str)
+ return ID;
+ }
+ return make_error<RawError>(raw_error_code::no_entry);
+}
+
+FixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {
+ return IDs;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
index f7f36901e4..a31025757d 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp
@@ -1,229 +1,229 @@
-//===- PDBStringTableBuilder.cpp - PDB String Table -------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-
-#include <map>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::support;
-using namespace llvm::support::endian;
-using namespace llvm::pdb;
-
-StringTableHashTraits::StringTableHashTraits(PDBStringTableBuilder &Table)
- : Table(&Table) {}
-
-uint32_t StringTableHashTraits::hashLookupKey(StringRef S) const {
- // 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 {
- return Table->getStringForId(Offset);
-}
-
-uint32_t StringTableHashTraits::lookupKeyToStorageKey(StringRef S) {
- return Table->insert(S);
-}
-
-uint32_t PDBStringTableBuilder::insert(StringRef S) {
- return Strings.insert(S);
-}
-
-uint32_t PDBStringTableBuilder::getIdForString(StringRef S) const {
- return Strings.getIdForString(S);
-}
-
-StringRef PDBStringTableBuilder::getStringForId(uint32_t Id) const {
- return Strings.getStringForId(Id);
-}
-
-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;
-}
-
-uint32_t PDBStringTableBuilder::calculateHashTableSize() const {
- uint32_t Size = sizeof(uint32_t); // Hash table begins with 4-byte size field.
- Size += sizeof(uint32_t) * computeBucketCount(Strings.size());
-
- return Size;
-}
-
-uint32_t PDBStringTableBuilder::calculateSerializedSize() const {
- uint32_t Size = 0;
- Size += sizeof(PDBStringTableHeader);
- Size += Strings.calculateSerializedSize();
- Size += calculateHashTableSize();
- Size += sizeof(uint32_t); // The /names stream ends with the string count.
- return Size;
-}
-
-void PDBStringTableBuilder::setStrings(
- const codeview::DebugStringTableSubsection &Strings) {
- this->Strings = Strings;
-}
-
-Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const {
- // Write a header
- PDBStringTableHeader H;
- H.Signature = PDBStringTableSignature;
- H.HashVersion = 1;
- H.ByteSize = Strings.calculateSerializedSize();
- if (auto EC = Writer.writeObject(H))
- return EC;
- assert(Writer.bytesRemaining() == 0);
- return Error::success();
-}
-
-Error PDBStringTableBuilder::writeStrings(BinaryStreamWriter &Writer) const {
- if (auto EC = Strings.commit(Writer))
- return EC;
-
- assert(Writer.bytesRemaining() == 0);
- return Error::success();
-}
-
-Error PDBStringTableBuilder::writeHashTable(BinaryStreamWriter &Writer) const {
- // Write a hash table.
- uint32_t BucketCount = computeBucketCount(Strings.size());
- if (auto EC = Writer.writeInteger(BucketCount))
- return EC;
- std::vector<ulittle32_t> Buckets(BucketCount);
-
- for (auto &Pair : Strings) {
- StringRef S = Pair.getKey();
- uint32_t Offset = Pair.getValue();
- uint32_t Hash = hashStringV1(S);
-
- for (uint32_t I = 0; I != BucketCount; ++I) {
- uint32_t Slot = (Hash + I) % BucketCount;
- if (Buckets[Slot] != 0)
- continue;
- Buckets[Slot] = Offset;
- break;
- }
- }
-
- if (auto EC = Writer.writeArray(ArrayRef<ulittle32_t>(Buckets)))
- return EC;
-
- assert(Writer.bytesRemaining() == 0);
- return Error::success();
-}
-
-Error PDBStringTableBuilder::writeEpilogue(BinaryStreamWriter &Writer) const {
- if (auto EC = Writer.writeInteger<uint32_t>(Strings.size()))
- return EC;
- assert(Writer.bytesRemaining() == 0);
- return Error::success();
-}
-
-Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const {
- BinaryStreamWriter SectionWriter;
-
- std::tie(SectionWriter, Writer) = Writer.split(sizeof(PDBStringTableHeader));
- if (auto EC = writeHeader(SectionWriter))
- return EC;
-
- std::tie(SectionWriter, Writer) =
- Writer.split(Strings.calculateSerializedSize());
- if (auto EC = writeStrings(SectionWriter))
- return EC;
-
- std::tie(SectionWriter, Writer) = Writer.split(calculateHashTableSize());
- if (auto EC = writeHashTable(SectionWriter))
- return EC;
-
- std::tie(SectionWriter, Writer) = Writer.split(sizeof(uint32_t));
- if (auto EC = writeEpilogue(SectionWriter))
- return EC;
-
- return Error::success();
-}
+//===- PDBStringTableBuilder.cpp - PDB String Table -------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+
+#include <map>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::support;
+using namespace llvm::support::endian;
+using namespace llvm::pdb;
+
+StringTableHashTraits::StringTableHashTraits(PDBStringTableBuilder &Table)
+ : Table(&Table) {}
+
+uint32_t StringTableHashTraits::hashLookupKey(StringRef S) const {
+ // 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 {
+ return Table->getStringForId(Offset);
+}
+
+uint32_t StringTableHashTraits::lookupKeyToStorageKey(StringRef S) {
+ return Table->insert(S);
+}
+
+uint32_t PDBStringTableBuilder::insert(StringRef S) {
+ return Strings.insert(S);
+}
+
+uint32_t PDBStringTableBuilder::getIdForString(StringRef S) const {
+ return Strings.getIdForString(S);
+}
+
+StringRef PDBStringTableBuilder::getStringForId(uint32_t Id) const {
+ return Strings.getStringForId(Id);
+}
+
+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;
+}
+
+uint32_t PDBStringTableBuilder::calculateHashTableSize() const {
+ uint32_t Size = sizeof(uint32_t); // Hash table begins with 4-byte size field.
+ Size += sizeof(uint32_t) * computeBucketCount(Strings.size());
+
+ return Size;
+}
+
+uint32_t PDBStringTableBuilder::calculateSerializedSize() const {
+ uint32_t Size = 0;
+ Size += sizeof(PDBStringTableHeader);
+ Size += Strings.calculateSerializedSize();
+ Size += calculateHashTableSize();
+ Size += sizeof(uint32_t); // The /names stream ends with the string count.
+ return Size;
+}
+
+void PDBStringTableBuilder::setStrings(
+ const codeview::DebugStringTableSubsection &Strings) {
+ this->Strings = Strings;
+}
+
+Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const {
+ // Write a header
+ PDBStringTableHeader H;
+ H.Signature = PDBStringTableSignature;
+ H.HashVersion = 1;
+ H.ByteSize = Strings.calculateSerializedSize();
+ if (auto EC = Writer.writeObject(H))
+ return EC;
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::writeStrings(BinaryStreamWriter &Writer) const {
+ if (auto EC = Strings.commit(Writer))
+ return EC;
+
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::writeHashTable(BinaryStreamWriter &Writer) const {
+ // Write a hash table.
+ uint32_t BucketCount = computeBucketCount(Strings.size());
+ if (auto EC = Writer.writeInteger(BucketCount))
+ return EC;
+ std::vector<ulittle32_t> Buckets(BucketCount);
+
+ for (auto &Pair : Strings) {
+ StringRef S = Pair.getKey();
+ uint32_t Offset = Pair.getValue();
+ uint32_t Hash = hashStringV1(S);
+
+ for (uint32_t I = 0; I != BucketCount; ++I) {
+ uint32_t Slot = (Hash + I) % BucketCount;
+ if (Buckets[Slot] != 0)
+ continue;
+ Buckets[Slot] = Offset;
+ break;
+ }
+ }
+
+ if (auto EC = Writer.writeArray(ArrayRef<ulittle32_t>(Buckets)))
+ return EC;
+
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::writeEpilogue(BinaryStreamWriter &Writer) const {
+ if (auto EC = Writer.writeInteger<uint32_t>(Strings.size()))
+ return EC;
+ assert(Writer.bytesRemaining() == 0);
+ return Error::success();
+}
+
+Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const {
+ BinaryStreamWriter SectionWriter;
+
+ std::tie(SectionWriter, Writer) = Writer.split(sizeof(PDBStringTableHeader));
+ if (auto EC = writeHeader(SectionWriter))
+ return EC;
+
+ std::tie(SectionWriter, Writer) =
+ Writer.split(Strings.calculateSerializedSize());
+ if (auto EC = writeStrings(SectionWriter))
+ return EC;
+
+ std::tie(SectionWriter, Writer) = Writer.split(calculateHashTableSize());
+ if (auto EC = writeHashTable(SectionWriter))
+ return EC;
+
+ std::tie(SectionWriter, Writer) = Writer.split(sizeof(uint32_t));
+ if (auto EC = writeEpilogue(SectionWriter))
+ return EC;
+
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PublicsStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PublicsStream.cpp
index a33bf03bf8..2b40a335ac 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PublicsStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/PublicsStream.cpp
@@ -1,101 +1,101 @@
-//===- PublicsStream.cpp - PDB Public Symbol Stream -----------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-//
-// The data structures defined in this file are based on the reference
-// implementation which is available at
-// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
-//
-// When you are reading the reference source code, you'd find the
-// information below useful.
-//
-// - ppdb1->m_fMinimalDbgInfo seems to be always true.
-// - SMALLBUCKETS macro is defined.
-//
-// The reference doesn't compile, so I learned just by reading code.
-// It's not guaranteed to be correct.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::support;
-using namespace llvm::pdb;
-
-PublicsStream::PublicsStream(std::unique_ptr<MappedBlockStream> Stream)
- : Stream(std::move(Stream)) {}
-
-PublicsStream::~PublicsStream() = default;
-
-uint32_t PublicsStream::getSymHash() const { return Header->SymHash; }
-uint16_t PublicsStream::getThunkTableSection() const {
- return Header->ISectThunkTable;
-}
-uint32_t PublicsStream::getThunkTableOffset() const {
- return Header->OffThunkTable;
-}
-
-// Publics stream contains fixed-size headers and a serialized hash table.
-// This implementation is not complete yet. It reads till the end of the
-// stream so that we verify the stream is at least not corrupted. However,
-// we skip over the hash table which we believe contains information about
-// public symbols.
-Error PublicsStream::reload() {
- BinaryStreamReader Reader(*Stream);
-
- // Check stream size.
- if (Reader.bytesRemaining() <
- sizeof(PublicsStreamHeader) + sizeof(GSIHashHeader))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Publics Stream does not contain a header.");
-
- // Read PSGSIHDR struct.
- if (Reader.readObject(Header))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Publics Stream does not contain a header.");
-
- // Read the hash table.
- if (auto E = PublicsTable.read(Reader))
- return E;
-
- // Something called "address map" follows.
- uint32_t NumAddressMapEntries = Header->AddrMap / sizeof(uint32_t);
- if (auto EC = Reader.readArray(AddressMap, NumAddressMapEntries))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read an address map."));
-
- // Something called "thunk map" follows.
- if (auto EC = Reader.readArray(ThunkMap, Header->NumThunks))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read a thunk map."));
-
- // Something called "section map" follows.
- if (Reader.bytesRemaining() > 0) {
- if (auto EC = Reader.readArray(SectionOffsets, Header->NumSections))
- return joinErrors(std::move(EC),
- make_error<RawError>(raw_error_code::corrupt_file,
- "Could not read a section map."));
- }
-
- if (Reader.bytesRemaining() > 0)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Corrupted publics stream.");
- return Error::success();
-}
+//===- PublicsStream.cpp - PDB Public Symbol Stream -----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// The data structures defined in this file are based on the reference
+// implementation which is available at
+// https://github.com/Microsoft/microsoft-pdb/blob/master/PDB/dbi/gsi.h
+//
+// When you are reading the reference source code, you'd find the
+// information below useful.
+//
+// - ppdb1->m_fMinimalDbgInfo seems to be always true.
+// - SMALLBUCKETS macro is defined.
+//
+// The reference doesn't compile, so I learned just by reading code.
+// It's not guaranteed to be correct.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::support;
+using namespace llvm::pdb;
+
+PublicsStream::PublicsStream(std::unique_ptr<MappedBlockStream> Stream)
+ : Stream(std::move(Stream)) {}
+
+PublicsStream::~PublicsStream() = default;
+
+uint32_t PublicsStream::getSymHash() const { return Header->SymHash; }
+uint16_t PublicsStream::getThunkTableSection() const {
+ return Header->ISectThunkTable;
+}
+uint32_t PublicsStream::getThunkTableOffset() const {
+ return Header->OffThunkTable;
+}
+
+// Publics stream contains fixed-size headers and a serialized hash table.
+// This implementation is not complete yet. It reads till the end of the
+// stream so that we verify the stream is at least not corrupted. However,
+// we skip over the hash table which we believe contains information about
+// public symbols.
+Error PublicsStream::reload() {
+ BinaryStreamReader Reader(*Stream);
+
+ // Check stream size.
+ if (Reader.bytesRemaining() <
+ sizeof(PublicsStreamHeader) + sizeof(GSIHashHeader))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Publics Stream does not contain a header.");
+
+ // Read PSGSIHDR struct.
+ if (Reader.readObject(Header))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Publics Stream does not contain a header.");
+
+ // Read the hash table.
+ if (auto E = PublicsTable.read(Reader))
+ return E;
+
+ // Something called "address map" follows.
+ uint32_t NumAddressMapEntries = Header->AddrMap / sizeof(uint32_t);
+ if (auto EC = Reader.readArray(AddressMap, NumAddressMapEntries))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read an address map."));
+
+ // Something called "thunk map" follows.
+ if (auto EC = Reader.readArray(ThunkMap, Header->NumThunks))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read a thunk map."));
+
+ // Something called "section map" follows.
+ if (Reader.bytesRemaining() > 0) {
+ if (auto EC = Reader.readArray(SectionOffsets, Header->NumSections))
+ return joinErrors(std::move(EC),
+ make_error<RawError>(raw_error_code::corrupt_file,
+ "Could not read a section map."));
+ }
+
+ if (Reader.bytesRemaining() > 0)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Corrupted publics stream.");
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/RawError.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/RawError.cpp
index ed6cf08396..dd6913cbbe 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/RawError.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/RawError.cpp
@@ -1,53 +1,53 @@
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ManagedStatic.h"
-
-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.
-class RawErrorCategory : public std::error_category {
-public:
- const char *name() const noexcept override { return "llvm.pdb.raw"; }
- std::string message(int Condition) const override {
- switch (static_cast<raw_error_code>(Condition)) {
- case raw_error_code::unspecified:
- return "An unknown error has occurred.";
- case raw_error_code::feature_unsupported:
- return "The feature is unsupported by the implementation.";
- case raw_error_code::invalid_format:
- return "The record is in an unexpected format.";
- case raw_error_code::corrupt_file:
- return "The PDB file is corrupt.";
- case raw_error_code::insufficient_buffer:
- return "The buffer is not large enough to read the requested number of "
- "bytes.";
- case raw_error_code::no_stream:
- return "The specified stream could not be loaded.";
- case raw_error_code::index_out_of_bounds:
- return "The specified item does not exist in the array.";
- case raw_error_code::invalid_block_address:
- return "The specified block address is not valid.";
- case raw_error_code::duplicate_entry:
- return "The entry already exists.";
- case raw_error_code::no_entry:
- return "The entry does not exist.";
- case raw_error_code::not_writable:
- return "The PDB does not support writing.";
- case raw_error_code::stream_too_long:
- return "The stream was longer than expected.";
- case raw_error_code::invalid_tpi_hash:
- return "The Type record has an invalid hash value.";
- }
- llvm_unreachable("Unrecognized raw_error_code");
- }
-};
-} // namespace
-
-static llvm::ManagedStatic<RawErrorCategory> RawCategory;
-const std::error_category &llvm::pdb::RawErrCategory() { return *RawCategory; }
-
-char RawError::ID;
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ManagedStatic.h"
+
+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.
+class RawErrorCategory : public std::error_category {
+public:
+ const char *name() const noexcept override { return "llvm.pdb.raw"; }
+ std::string message(int Condition) const override {
+ switch (static_cast<raw_error_code>(Condition)) {
+ case raw_error_code::unspecified:
+ return "An unknown error has occurred.";
+ case raw_error_code::feature_unsupported:
+ return "The feature is unsupported by the implementation.";
+ case raw_error_code::invalid_format:
+ return "The record is in an unexpected format.";
+ case raw_error_code::corrupt_file:
+ return "The PDB file is corrupt.";
+ case raw_error_code::insufficient_buffer:
+ return "The buffer is not large enough to read the requested number of "
+ "bytes.";
+ case raw_error_code::no_stream:
+ return "The specified stream could not be loaded.";
+ case raw_error_code::index_out_of_bounds:
+ return "The specified item does not exist in the array.";
+ case raw_error_code::invalid_block_address:
+ return "The specified block address is not valid.";
+ case raw_error_code::duplicate_entry:
+ return "The entry already exists.";
+ case raw_error_code::no_entry:
+ return "The entry does not exist.";
+ case raw_error_code::not_writable:
+ return "The PDB does not support writing.";
+ case raw_error_code::stream_too_long:
+ return "The stream was longer than expected.";
+ case raw_error_code::invalid_tpi_hash:
+ return "The Type record has an invalid hash value.";
+ }
+ llvm_unreachable("Unrecognized raw_error_code");
+ }
+};
+} // namespace
+
+static llvm::ManagedStatic<RawErrorCategory> RawCategory;
+const std::error_category &llvm::pdb::RawErrCategory() { return *RawCategory; }
+
+char RawError::ID;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp
index fd9a0deb54..eca69a4a83 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolCache.cpp
@@ -1,297 +1,297 @@
-#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
-
+#include "llvm/DebugInfo/PDB/Native/SymbolCache.h"
+
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
-#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
-#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
-#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
-#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
-#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
-#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
+#include "llvm/DebugInfo/CodeView/DebugLinesSubsection.h"
+#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
+#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
+#include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
+#include "llvm/DebugInfo/PDB/Native/ISectionContribVisitor.h"
+#include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumGlobals.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumLineNumbers.h"
#include "llvm/DebugInfo/PDB/Native/NativeEnumSymbols.h"
-#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
-#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
+#include "llvm/DebugInfo/PDB/Native/NativeFunctionSymbol.h"
#include "llvm/DebugInfo/PDB/Native/NativeInlineSiteSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
-#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
-#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
-#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-// Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
-// to instantiate a NativeBuiltinSymbol for that type.
-static const struct BuiltinTypeEntry {
- codeview::SimpleTypeKind Kind;
- PDB_BuiltinType Type;
- uint32_t Size;
-} BuiltinTypes[] = {
- {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0},
- {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0},
- {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4},
- {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
- {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
- {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
- {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
- {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4},
- {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
- {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8},
- {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
- {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
- {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2},
- {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2},
- {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4},
- {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
- {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
- {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4},
- {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8},
- {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10},
- {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1},
- // This table can be grown as necessary, but these are the only types we've
- // needed so far.
-};
-
-SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
+#include "llvm/DebugInfo/PDB/Native/NativePublicSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeRawSymbol.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeArray.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypePointer.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeUDT.h"
+#include "llvm/DebugInfo/PDB/Native/NativeTypeVTShape.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
+#include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
+#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+// Maps codeview::SimpleTypeKind of a built-in type to the parameters necessary
+// to instantiate a NativeBuiltinSymbol for that type.
+static const struct BuiltinTypeEntry {
+ codeview::SimpleTypeKind Kind;
+ PDB_BuiltinType Type;
+ uint32_t Size;
+} BuiltinTypes[] = {
+ {codeview::SimpleTypeKind::None, PDB_BuiltinType::None, 0},
+ {codeview::SimpleTypeKind::Void, PDB_BuiltinType::Void, 0},
+ {codeview::SimpleTypeKind::HResult, PDB_BuiltinType::HResult, 4},
+ {codeview::SimpleTypeKind::Int16Short, PDB_BuiltinType::Int, 2},
+ {codeview::SimpleTypeKind::UInt16Short, PDB_BuiltinType::UInt, 2},
+ {codeview::SimpleTypeKind::Int32, PDB_BuiltinType::Int, 4},
+ {codeview::SimpleTypeKind::UInt32, PDB_BuiltinType::UInt, 4},
+ {codeview::SimpleTypeKind::Int32Long, PDB_BuiltinType::Int, 4},
+ {codeview::SimpleTypeKind::UInt32Long, PDB_BuiltinType::UInt, 4},
+ {codeview::SimpleTypeKind::Int64Quad, PDB_BuiltinType::Int, 8},
+ {codeview::SimpleTypeKind::UInt64Quad, PDB_BuiltinType::UInt, 8},
+ {codeview::SimpleTypeKind::NarrowCharacter, PDB_BuiltinType::Char, 1},
+ {codeview::SimpleTypeKind::WideCharacter, PDB_BuiltinType::WCharT, 2},
+ {codeview::SimpleTypeKind::Character16, PDB_BuiltinType::Char16, 2},
+ {codeview::SimpleTypeKind::Character32, PDB_BuiltinType::Char32, 4},
+ {codeview::SimpleTypeKind::SignedCharacter, PDB_BuiltinType::Char, 1},
+ {codeview::SimpleTypeKind::UnsignedCharacter, PDB_BuiltinType::UInt, 1},
+ {codeview::SimpleTypeKind::Float32, PDB_BuiltinType::Float, 4},
+ {codeview::SimpleTypeKind::Float64, PDB_BuiltinType::Float, 8},
+ {codeview::SimpleTypeKind::Float80, PDB_BuiltinType::Float, 10},
+ {codeview::SimpleTypeKind::Boolean8, PDB_BuiltinType::Bool, 1},
+ // This table can be grown as necessary, but these are the only types we've
+ // needed so far.
+};
+
+SymbolCache::SymbolCache(NativeSession &Session, DbiStream *Dbi)
: Session(Session), Dbi(Dbi) {
- // Id 0 is reserved for the invalid symbol.
- Cache.push_back(nullptr);
- SourceFiles.push_back(nullptr);
-
- if (Dbi)
- Compilands.resize(Dbi->modules().getModuleCount());
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-SymbolCache::createTypeEnumerator(TypeLeafKind Kind) {
- return createTypeEnumerator(std::vector<TypeLeafKind>{Kind});
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) {
- auto Tpi = Session.getPDBFile().getPDBTpiStream();
- if (!Tpi) {
- consumeError(Tpi.takeError());
- return nullptr;
- }
- auto &Types = Tpi->typeCollection();
- return std::unique_ptr<IPDBEnumSymbols>(
- new NativeEnumTypes(Session, Types, std::move(Kinds)));
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
- return std::unique_ptr<IPDBEnumSymbols>(
- new NativeEnumGlobals(Session, {Kind}));
-}
-
-SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
+ // Id 0 is reserved for the invalid symbol.
+ Cache.push_back(nullptr);
+ SourceFiles.push_back(nullptr);
+
+ if (Dbi)
+ Compilands.resize(Dbi->modules().getModuleCount());
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+SymbolCache::createTypeEnumerator(TypeLeafKind Kind) {
+ return createTypeEnumerator(std::vector<TypeLeafKind>{Kind});
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+SymbolCache::createTypeEnumerator(std::vector<TypeLeafKind> Kinds) {
+ auto Tpi = Session.getPDBFile().getPDBTpiStream();
+ if (!Tpi) {
+ consumeError(Tpi.takeError());
+ return nullptr;
+ }
+ auto &Types = Tpi->typeCollection();
+ return std::unique_ptr<IPDBEnumSymbols>(
+ new NativeEnumTypes(Session, Types, std::move(Kinds)));
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+SymbolCache::createGlobalsEnumerator(codeview::SymbolKind Kind) {
+ return std::unique_ptr<IPDBEnumSymbols>(
+ new NativeEnumGlobals(Session, {Kind}));
+}
+
+SymIndexId SymbolCache::createSimpleType(TypeIndex Index,
ModifierOptions Mods) const {
- if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
- return createSymbol<NativeTypePointer>(Index);
-
- const auto Kind = Index.getSimpleKind();
+ if (Index.getSimpleMode() != codeview::SimpleTypeMode::Direct)
+ return createSymbol<NativeTypePointer>(Index);
+
+ const auto Kind = Index.getSimpleKind();
const auto It =
llvm::find_if(BuiltinTypes, [Kind](const BuiltinTypeEntry &Builtin) {
return Builtin.Kind == Kind;
});
- if (It == std::end(BuiltinTypes))
- return 0;
- return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
-}
-
-SymIndexId
-SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
+ if (It == std::end(BuiltinTypes))
+ return 0;
+ return createSymbol<NativeTypeBuiltin>(Mods, It->Type, It->Size);
+}
+
+SymIndexId
+SymbolCache::createSymbolForModifiedType(codeview::TypeIndex ModifierTI,
codeview::CVType CVT) const {
- ModifierRecord Record;
- if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) {
- consumeError(std::move(EC));
- return 0;
- }
-
- if (Record.ModifiedType.isSimple())
- return createSimpleType(Record.ModifiedType, Record.Modifiers);
-
- // Make sure we create and cache a record for the unmodified type.
- SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType);
- NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId];
-
- switch (UnmodifiedNRS.getSymTag()) {
- case PDB_SymType::Enum:
- return createSymbol<NativeTypeEnum>(
- static_cast<NativeTypeEnum &>(UnmodifiedNRS), std::move(Record));
- case PDB_SymType::UDT:
- return createSymbol<NativeTypeUDT>(
- static_cast<NativeTypeUDT &>(UnmodifiedNRS), std::move(Record));
- default:
- // No other types can be modified. (LF_POINTER, for example, records
- // its modifiers a different way.
- assert(false && "Invalid LF_MODIFIER record");
- break;
- }
- return 0;
-}
-
+ ModifierRecord Record;
+ if (auto EC = TypeDeserializer::deserializeAs<ModifierRecord>(CVT, Record)) {
+ consumeError(std::move(EC));
+ return 0;
+ }
+
+ if (Record.ModifiedType.isSimple())
+ return createSimpleType(Record.ModifiedType, Record.Modifiers);
+
+ // Make sure we create and cache a record for the unmodified type.
+ SymIndexId UnmodifiedId = findSymbolByTypeIndex(Record.ModifiedType);
+ NativeRawSymbol &UnmodifiedNRS = *Cache[UnmodifiedId];
+
+ switch (UnmodifiedNRS.getSymTag()) {
+ case PDB_SymType::Enum:
+ return createSymbol<NativeTypeEnum>(
+ static_cast<NativeTypeEnum &>(UnmodifiedNRS), std::move(Record));
+ case PDB_SymType::UDT:
+ return createSymbol<NativeTypeUDT>(
+ static_cast<NativeTypeUDT &>(UnmodifiedNRS), std::move(Record));
+ default:
+ // No other types can be modified. (LF_POINTER, for example, records
+ // its modifiers a different way.
+ assert(false && "Invalid LF_MODIFIER record");
+ break;
+ }
+ return 0;
+}
+
SymIndexId SymbolCache::findSymbolByTypeIndex(codeview::TypeIndex Index) const {
- // First see if it's already in our cache.
- const auto Entry = TypeIndexToSymbolId.find(Index);
- if (Entry != TypeIndexToSymbolId.end())
- return Entry->second;
-
- // Symbols for built-in types are created on the fly.
- if (Index.isSimple()) {
- SymIndexId Result = createSimpleType(Index, ModifierOptions::None);
- assert(TypeIndexToSymbolId.count(Index) == 0);
- TypeIndexToSymbolId[Index] = Result;
- return Result;
- }
-
- // We need to instantiate and cache the desired type symbol.
- auto Tpi = Session.getPDBFile().getPDBTpiStream();
- if (!Tpi) {
- consumeError(Tpi.takeError());
- return 0;
- }
- codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
- codeview::CVType CVT = Types.getType(Index);
-
- if (isUdtForwardRef(CVT)) {
- Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index);
-
- if (!EFD)
- consumeError(EFD.takeError());
- else if (*EFD != Index) {
- assert(!isUdtForwardRef(Types.getType(*EFD)));
- SymIndexId Result = findSymbolByTypeIndex(*EFD);
- // Record a mapping from ForwardRef -> SymIndex of complete type so that
- // we'll take the fast path next time.
- assert(TypeIndexToSymbolId.count(Index) == 0);
- TypeIndexToSymbolId[Index] = Result;
- return Result;
- }
- }
-
- // At this point if we still have a forward ref udt it means the full decl was
- // not in the PDB. We just have to deal with it and use the forward ref.
- SymIndexId Id = 0;
- switch (CVT.kind()) {
- case codeview::LF_ENUM:
- Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT));
- break;
- case codeview::LF_ARRAY:
- Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index,
- std::move(CVT));
- break;
- case codeview::LF_CLASS:
- case codeview::LF_STRUCTURE:
- case codeview::LF_INTERFACE:
- Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT));
- break;
- case codeview::LF_UNION:
- Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT));
- break;
- case codeview::LF_POINTER:
- Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index,
- std::move(CVT));
- break;
- case codeview::LF_MODIFIER:
- Id = createSymbolForModifiedType(Index, std::move(CVT));
- break;
- case codeview::LF_PROCEDURE:
- Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
- Index, std::move(CVT));
- break;
- case codeview::LF_MFUNCTION:
- Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
- Index, std::move(CVT));
- break;
- case codeview::LF_VTSHAPE:
- Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
- Index, std::move(CVT));
- break;
- default:
- Id = createSymbolPlaceholder();
- break;
- }
- if (Id != 0) {
- assert(TypeIndexToSymbolId.count(Index) == 0);
- TypeIndexToSymbolId[Index] = Id;
- }
- return Id;
-}
-
-std::unique_ptr<PDBSymbol>
-SymbolCache::getSymbolById(SymIndexId SymbolId) const {
- assert(SymbolId < Cache.size());
-
- // Id 0 is reserved.
- if (SymbolId == 0 || SymbolId >= Cache.size())
- return nullptr;
-
- // Make sure to handle the case where we've inserted a placeholder symbol
+ // First see if it's already in our cache.
+ const auto Entry = TypeIndexToSymbolId.find(Index);
+ if (Entry != TypeIndexToSymbolId.end())
+ return Entry->second;
+
+ // Symbols for built-in types are created on the fly.
+ if (Index.isSimple()) {
+ SymIndexId Result = createSimpleType(Index, ModifierOptions::None);
+ assert(TypeIndexToSymbolId.count(Index) == 0);
+ TypeIndexToSymbolId[Index] = Result;
+ return Result;
+ }
+
+ // We need to instantiate and cache the desired type symbol.
+ auto Tpi = Session.getPDBFile().getPDBTpiStream();
+ if (!Tpi) {
+ consumeError(Tpi.takeError());
+ return 0;
+ }
+ codeview::LazyRandomTypeCollection &Types = Tpi->typeCollection();
+ codeview::CVType CVT = Types.getType(Index);
+
+ if (isUdtForwardRef(CVT)) {
+ Expected<TypeIndex> EFD = Tpi->findFullDeclForForwardRef(Index);
+
+ if (!EFD)
+ consumeError(EFD.takeError());
+ else if (*EFD != Index) {
+ assert(!isUdtForwardRef(Types.getType(*EFD)));
+ SymIndexId Result = findSymbolByTypeIndex(*EFD);
+ // Record a mapping from ForwardRef -> SymIndex of complete type so that
+ // we'll take the fast path next time.
+ assert(TypeIndexToSymbolId.count(Index) == 0);
+ TypeIndexToSymbolId[Index] = Result;
+ return Result;
+ }
+ }
+
+ // At this point if we still have a forward ref udt it means the full decl was
+ // not in the PDB. We just have to deal with it and use the forward ref.
+ SymIndexId Id = 0;
+ switch (CVT.kind()) {
+ case codeview::LF_ENUM:
+ Id = createSymbolForType<NativeTypeEnum, EnumRecord>(Index, std::move(CVT));
+ break;
+ case codeview::LF_ARRAY:
+ Id = createSymbolForType<NativeTypeArray, ArrayRecord>(Index,
+ std::move(CVT));
+ break;
+ case codeview::LF_CLASS:
+ case codeview::LF_STRUCTURE:
+ case codeview::LF_INTERFACE:
+ Id = createSymbolForType<NativeTypeUDT, ClassRecord>(Index, std::move(CVT));
+ break;
+ case codeview::LF_UNION:
+ Id = createSymbolForType<NativeTypeUDT, UnionRecord>(Index, std::move(CVT));
+ break;
+ case codeview::LF_POINTER:
+ Id = createSymbolForType<NativeTypePointer, PointerRecord>(Index,
+ std::move(CVT));
+ break;
+ case codeview::LF_MODIFIER:
+ Id = createSymbolForModifiedType(Index, std::move(CVT));
+ break;
+ case codeview::LF_PROCEDURE:
+ Id = createSymbolForType<NativeTypeFunctionSig, ProcedureRecord>(
+ Index, std::move(CVT));
+ break;
+ case codeview::LF_MFUNCTION:
+ Id = createSymbolForType<NativeTypeFunctionSig, MemberFunctionRecord>(
+ Index, std::move(CVT));
+ break;
+ case codeview::LF_VTSHAPE:
+ Id = createSymbolForType<NativeTypeVTShape, VFTableShapeRecord>(
+ Index, std::move(CVT));
+ break;
+ default:
+ Id = createSymbolPlaceholder();
+ break;
+ }
+ if (Id != 0) {
+ assert(TypeIndexToSymbolId.count(Index) == 0);
+ TypeIndexToSymbolId[Index] = Id;
+ }
+ return Id;
+}
+
+std::unique_ptr<PDBSymbol>
+SymbolCache::getSymbolById(SymIndexId SymbolId) const {
+ assert(SymbolId < Cache.size());
+
+ // Id 0 is reserved.
+ if (SymbolId == 0 || SymbolId >= Cache.size())
+ return nullptr;
+
+ // Make sure to handle the case where we've inserted a placeholder symbol
// for types we don't yet support.
- NativeRawSymbol *NRS = Cache[SymbolId].get();
- if (!NRS)
- return nullptr;
-
- return PDBSymbol::create(Session, *NRS);
-}
-
-NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const {
- return *Cache[SymbolId];
-}
-
-uint32_t SymbolCache::getNumCompilands() const {
- if (!Dbi)
- return 0;
-
- return Dbi->modules().getModuleCount();
-}
-
-SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
- auto Iter = GlobalOffsetToSymbolId.find(Offset);
- if (Iter != GlobalOffsetToSymbolId.end())
- return Iter->second;
-
- SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
- CVSymbol CVS = SS.readRecord(Offset);
- SymIndexId Id = 0;
- switch (CVS.kind()) {
- case SymbolKind::S_UDT: {
- UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS));
- Id = createSymbol<NativeTypeTypedef>(std::move(US));
- break;
- }
- default:
- Id = createSymbolPlaceholder();
- break;
- }
- if (Id != 0) {
- assert(GlobalOffsetToSymbolId.count(Offset) == 0);
- GlobalOffsetToSymbolId[Offset] = Id;
- }
-
- return Id;
-}
-
+ NativeRawSymbol *NRS = Cache[SymbolId].get();
+ if (!NRS)
+ return nullptr;
+
+ return PDBSymbol::create(Session, *NRS);
+}
+
+NativeRawSymbol &SymbolCache::getNativeSymbolById(SymIndexId SymbolId) const {
+ return *Cache[SymbolId];
+}
+
+uint32_t SymbolCache::getNumCompilands() const {
+ if (!Dbi)
+ return 0;
+
+ return Dbi->modules().getModuleCount();
+}
+
+SymIndexId SymbolCache::getOrCreateGlobalSymbolByOffset(uint32_t Offset) {
+ auto Iter = GlobalOffsetToSymbolId.find(Offset);
+ if (Iter != GlobalOffsetToSymbolId.end())
+ return Iter->second;
+
+ SymbolStream &SS = cantFail(Session.getPDBFile().getPDBSymbolStream());
+ CVSymbol CVS = SS.readRecord(Offset);
+ SymIndexId Id = 0;
+ switch (CVS.kind()) {
+ case SymbolKind::S_UDT: {
+ UDTSym US = cantFail(SymbolDeserializer::deserializeAs<UDTSym>(CVS));
+ Id = createSymbol<NativeTypeTypedef>(std::move(US));
+ break;
+ }
+ default:
+ Id = createSymbolPlaceholder();
+ break;
+ }
+ if (Id != 0) {
+ assert(GlobalOffsetToSymbolId.count(Offset) == 0);
+ GlobalOffsetToSymbolId[Offset] = Id;
+ }
+
+ return Id;
+}
+
SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym,
uint64_t ParentAddr,
uint16_t Modi,
@@ -299,66 +299,66 @@ SymIndexId SymbolCache::getOrCreateInlineSymbol(InlineSiteSym Sym,
auto Iter = SymTabOffsetToSymbolId.find({Modi, RecordOffset});
if (Iter != SymTabOffsetToSymbolId.end())
return Iter->second;
-
+
SymIndexId Id = createSymbol<NativeInlineSiteSymbol>(Sym, ParentAddr);
SymTabOffsetToSymbolId.insert({{Modi, RecordOffset}, Id});
return Id;
-}
-
-std::unique_ptr<PDBSymbol>
-SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
- PDB_SymType Type) {
- switch (Type) {
- case PDB_SymType::Function:
- return findFunctionSymbolBySectOffset(Sect, Offset);
- case PDB_SymType::PublicSymbol:
- return findPublicSymbolBySectOffset(Sect, Offset);
+}
+
+std::unique_ptr<PDBSymbol>
+SymbolCache::findSymbolBySectOffset(uint32_t Sect, uint32_t Offset,
+ PDB_SymType Type) {
+ switch (Type) {
+ case PDB_SymType::Function:
+ return findFunctionSymbolBySectOffset(Sect, Offset);
+ case PDB_SymType::PublicSymbol:
+ return findPublicSymbolBySectOffset(Sect, Offset);
case PDB_SymType::Compiland: {
uint16_t Modi;
if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
return nullptr;
return getOrCreateCompiland(Modi);
}
- case PDB_SymType::None: {
+ case PDB_SymType::None: {
// FIXME: Implement for PDB_SymType::Data. The symbolizer calls this but
// only uses it to find the symbol length.
- if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset))
- return Sym;
- return nullptr;
- }
- default:
- return nullptr;
- }
-}
-
-std::unique_ptr<PDBSymbol>
-SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
+ if (auto Sym = findFunctionSymbolBySectOffset(Sect, Offset))
+ return Sym;
+ return nullptr;
+ }
+ default:
+ return nullptr;
+ }
+}
+
+std::unique_ptr<PDBSymbol>
+SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
auto Iter = AddressToSymbolId.find({Sect, Offset});
if (Iter != AddressToSymbolId.end())
- return getSymbolById(Iter->second);
-
- if (!Dbi)
- return nullptr;
-
+ return getSymbolById(Iter->second);
+
+ if (!Dbi)
+ return nullptr;
+
uint16_t Modi;
if (!Session.moduleIndexForSectOffset(Sect, Offset, Modi))
- return nullptr;
-
+ return nullptr;
+
Expected<ModuleDebugStreamRef> ExpectedModS =
Session.getModuleDebugStream(Modi);
- if (!ExpectedModS) {
- consumeError(ExpectedModS.takeError());
- return nullptr;
- }
- CVSymbolArray Syms = ExpectedModS->getSymbolArray();
-
- // Search for the symbol in this module.
- for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
- if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32)
- continue;
- auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
- if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
- Offset < PS.CodeOffset + PS.CodeSize) {
+ if (!ExpectedModS) {
+ consumeError(ExpectedModS.takeError());
+ return nullptr;
+ }
+ CVSymbolArray Syms = ExpectedModS->getSymbolArray();
+
+ // Search for the symbol in this module.
+ for (auto I = Syms.begin(), E = Syms.end(); I != E; ++I) {
+ if (I->kind() != S_LPROC32 && I->kind() != S_GPROC32)
+ continue;
+ auto PS = cantFail(SymbolDeserializer::deserializeAs<ProcSym>(*I));
+ if (Sect == PS.Segment && Offset >= PS.CodeOffset &&
+ Offset < PS.CodeOffset + PS.CodeSize) {
// Check if the symbol is already cached.
auto Found = AddressToSymbolId.find({PS.Segment, PS.CodeOffset});
if (Found != AddressToSymbolId.end())
@@ -367,121 +367,121 @@ SymbolCache::findFunctionSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
// Otherwise, create a new symbol.
SymIndexId Id = createSymbol<NativeFunctionSymbol>(PS, I.offset());
AddressToSymbolId.insert({{PS.Segment, PS.CodeOffset}, Id});
- return getSymbolById(Id);
- }
-
- // Jump to the end of this ProcSym.
- I = Syms.at(PS.End);
- }
- return nullptr;
-}
-
-std::unique_ptr<PDBSymbol>
-SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
- auto Iter = AddressToPublicSymId.find({Sect, Offset});
- if (Iter != AddressToPublicSymId.end())
- return getSymbolById(Iter->second);
-
- auto Publics = Session.getPDBFile().getPDBPublicsStream();
- if (!Publics)
- return nullptr;
-
- auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream();
- if (!ExpectedSyms)
- return nullptr;
- BinaryStreamRef SymStream =
- ExpectedSyms->getSymbolArray().getUnderlyingStream();
-
- // Use binary search to find the first public symbol with an address greater
- // than or equal to Sect, Offset.
- auto AddrMap = Publics->getAddressMap();
- auto First = AddrMap.begin();
- auto It = AddrMap.begin();
- size_t Count = AddrMap.size();
- size_t Half;
- while (Count > 0) {
- It = First;
- Half = Count / 2;
- It += Half;
- Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
- if (!Sym) {
- consumeError(Sym.takeError());
- return nullptr;
- }
-
- auto PS =
- cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
- if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) {
- First = ++It;
- Count -= Half + 1;
- } else
- Count = Half;
- }
- if (It == AddrMap.begin())
- return nullptr;
- --It;
-
- Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
- if (!Sym) {
- consumeError(Sym.takeError());
- return nullptr;
- }
+ return getSymbolById(Id);
+ }
+
+ // Jump to the end of this ProcSym.
+ I = Syms.at(PS.End);
+ }
+ return nullptr;
+}
+
+std::unique_ptr<PDBSymbol>
+SymbolCache::findPublicSymbolBySectOffset(uint32_t Sect, uint32_t Offset) {
+ auto Iter = AddressToPublicSymId.find({Sect, Offset});
+ if (Iter != AddressToPublicSymId.end())
+ return getSymbolById(Iter->second);
+
+ auto Publics = Session.getPDBFile().getPDBPublicsStream();
+ if (!Publics)
+ return nullptr;
+
+ auto ExpectedSyms = Session.getPDBFile().getPDBSymbolStream();
+ if (!ExpectedSyms)
+ return nullptr;
+ BinaryStreamRef SymStream =
+ ExpectedSyms->getSymbolArray().getUnderlyingStream();
+
+ // Use binary search to find the first public symbol with an address greater
+ // than or equal to Sect, Offset.
+ auto AddrMap = Publics->getAddressMap();
+ auto First = AddrMap.begin();
+ auto It = AddrMap.begin();
+ size_t Count = AddrMap.size();
+ size_t Half;
+ while (Count > 0) {
+ It = First;
+ Half = Count / 2;
+ It += Half;
+ Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
+ if (!Sym) {
+ consumeError(Sym.takeError());
+ return nullptr;
+ }
+
+ auto PS =
+ cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
+ if (PS.Segment < Sect || (PS.Segment == Sect && PS.Offset <= Offset)) {
+ First = ++It;
+ Count -= Half + 1;
+ } else
+ Count = Half;
+ }
+ if (It == AddrMap.begin())
+ return nullptr;
+ --It;
+
+ Expected<CVSymbol> Sym = readSymbolFromStream(SymStream, *It);
+ if (!Sym) {
+ consumeError(Sym.takeError());
+ return nullptr;
+ }
// Check if the symbol is already cached.
- auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
+ auto PS = cantFail(SymbolDeserializer::deserializeAs<PublicSym32>(Sym.get()));
auto Found = AddressToPublicSymId.find({PS.Segment, PS.Offset});
if (Found != AddressToPublicSymId.end())
return getSymbolById(Found->second);
// Otherwise, create a new symbol.
- SymIndexId Id = createSymbol<NativePublicSymbol>(PS);
+ SymIndexId Id = createSymbol<NativePublicSymbol>(PS);
AddressToPublicSymId.insert({{PS.Segment, PS.Offset}, Id});
- return getSymbolById(Id);
-}
-
-std::vector<SymbolCache::LineTableEntry>
-SymbolCache::findLineTable(uint16_t Modi) const {
- // Check if this module has already been added.
- auto LineTableIter = LineTable.find(Modi);
- if (LineTableIter != LineTable.end())
- return LineTableIter->second;
-
- std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi];
-
- // If there is an error or there are no lines, just return the
- // empty vector.
+ return getSymbolById(Id);
+}
+
+std::vector<SymbolCache::LineTableEntry>
+SymbolCache::findLineTable(uint16_t Modi) const {
+ // Check if this module has already been added.
+ auto LineTableIter = LineTable.find(Modi);
+ if (LineTableIter != LineTable.end())
+ return LineTableIter->second;
+
+ std::vector<LineTableEntry> &ModuleLineTable = LineTable[Modi];
+
+ // If there is an error or there are no lines, just return the
+ // empty vector.
Expected<ModuleDebugStreamRef> ExpectedModS =
Session.getModuleDebugStream(Modi);
- if (!ExpectedModS) {
- consumeError(ExpectedModS.takeError());
- return ModuleLineTable;
- }
-
- std::vector<std::vector<LineTableEntry>> EntryList;
- for (const auto &SS : ExpectedModS->getSubsectionsArray()) {
- if (SS.kind() != DebugSubsectionKind::Lines)
- continue;
-
- DebugLinesSubsectionRef Lines;
- BinaryStreamReader Reader(SS.getRecordData());
- if (auto EC = Lines.initialize(Reader)) {
- consumeError(std::move(EC));
- continue;
- }
-
- uint32_t RelocSegment = Lines.header()->RelocSegment;
- uint32_t RelocOffset = Lines.header()->RelocOffset;
- for (const LineColumnEntry &Group : Lines) {
- if (Group.LineNumbers.empty())
- continue;
-
- std::vector<LineTableEntry> Entries;
-
- // If there are column numbers, then they should be in a parallel stream
- // to the line numbers.
- auto ColIt = Group.Columns.begin();
- auto ColsEnd = Group.Columns.end();
-
+ if (!ExpectedModS) {
+ consumeError(ExpectedModS.takeError());
+ return ModuleLineTable;
+ }
+
+ std::vector<std::vector<LineTableEntry>> EntryList;
+ for (const auto &SS : ExpectedModS->getSubsectionsArray()) {
+ if (SS.kind() != DebugSubsectionKind::Lines)
+ continue;
+
+ DebugLinesSubsectionRef Lines;
+ BinaryStreamReader Reader(SS.getRecordData());
+ if (auto EC = Lines.initialize(Reader)) {
+ consumeError(std::move(EC));
+ continue;
+ }
+
+ uint32_t RelocSegment = Lines.header()->RelocSegment;
+ uint32_t RelocOffset = Lines.header()->RelocOffset;
+ for (const LineColumnEntry &Group : Lines) {
+ if (Group.LineNumbers.empty())
+ continue;
+
+ std::vector<LineTableEntry> Entries;
+
+ // If there are column numbers, then they should be in a parallel stream
+ // to the line numbers.
+ auto ColIt = Group.Columns.begin();
+ auto ColsEnd = Group.Columns.end();
+
// Add a line to mark the beginning of this section.
uint64_t StartAddr =
Session.getVAFromSectOffset(RelocSegment, RelocOffset);
@@ -490,144 +490,144 @@ SymbolCache::findLineTable(uint16_t Modi) const {
(Lines.hasColumnInfo()) ? Group.Columns.front().StartColumn : 0;
Entries.push_back({StartAddr, FirstLine, ColNum, Group.NameIndex, false});
- for (const LineNumberEntry &LN : Group.LineNumbers) {
- uint64_t VA =
- Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
- LineInfo Line(LN.Flags);
+ for (const LineNumberEntry &LN : Group.LineNumbers) {
+ uint64_t VA =
+ Session.getVAFromSectOffset(RelocSegment, RelocOffset + LN.Offset);
+ LineInfo Line(LN.Flags);
ColNum = 0;
-
- if (Lines.hasColumnInfo() && ColIt != ColsEnd) {
- ColNum = ColIt->StartColumn;
- ++ColIt;
- }
- Entries.push_back({VA, Line, ColNum, Group.NameIndex, false});
- }
-
- // Add a terminal entry line to mark the end of this subsection.
+
+ if (Lines.hasColumnInfo() && ColIt != ColsEnd) {
+ ColNum = ColIt->StartColumn;
+ ++ColIt;
+ }
+ Entries.push_back({VA, Line, ColNum, Group.NameIndex, false});
+ }
+
+ // Add a terminal entry line to mark the end of this subsection.
uint64_t EndAddr = StartAddr + Lines.header()->CodeSize;
- LineInfo LastLine(Group.LineNumbers.back().Flags);
+ LineInfo LastLine(Group.LineNumbers.back().Flags);
ColNum = (Lines.hasColumnInfo()) ? Group.Columns.back().StartColumn : 0;
Entries.push_back({EndAddr, LastLine, ColNum, Group.NameIndex, true});
-
- EntryList.push_back(Entries);
- }
- }
-
- // Sort EntryList, and add flattened contents to the line table.
+
+ EntryList.push_back(Entries);
+ }
+ }
+
+ // Sort EntryList, and add flattened contents to the line table.
llvm::sort(EntryList, [](const std::vector<LineTableEntry> &LHS,
const std::vector<LineTableEntry> &RHS) {
return LHS[0].Addr < RHS[0].Addr;
});
- for (size_t I = 0; I < EntryList.size(); ++I)
+ for (size_t I = 0; I < EntryList.size(); ++I)
llvm::append_range(ModuleLineTable, EntryList[I]);
-
- return ModuleLineTable;
-}
-
-std::unique_ptr<IPDBEnumLineNumbers>
-SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
+
+ return ModuleLineTable;
+}
+
+std::unique_ptr<IPDBEnumLineNumbers>
+SymbolCache::findLineNumbersByVA(uint64_t VA, uint32_t Length) const {
uint16_t Modi;
if (!Session.moduleIndexForVA(VA, Modi))
- return nullptr;
-
- std::vector<LineTableEntry> Lines = findLineTable(Modi);
- if (Lines.empty())
- return nullptr;
-
- // Find the first line in the line table whose address is not greater than
- // the one we are searching for.
- auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) {
- return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry));
- });
-
- // Try to back up if we've gone too far.
- if (LineIter == Lines.end() || LineIter->Addr > VA) {
- if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry)
- return nullptr;
- --LineIter;
- }
-
+ return nullptr;
+
+ std::vector<LineTableEntry> Lines = findLineTable(Modi);
+ if (Lines.empty())
+ return nullptr;
+
+ // Find the first line in the line table whose address is not greater than
+ // the one we are searching for.
+ auto LineIter = llvm::partition_point(Lines, [&](const LineTableEntry &E) {
+ return (E.Addr < VA || (E.Addr == VA && E.IsTerminalEntry));
+ });
+
+ // Try to back up if we've gone too far.
+ if (LineIter == Lines.end() || LineIter->Addr > VA) {
+ if (LineIter == Lines.begin() || std::prev(LineIter)->IsTerminalEntry)
+ return nullptr;
+ --LineIter;
+ }
+
Expected<ModuleDebugStreamRef> ExpectedModS =
Session.getModuleDebugStream(Modi);
- if (!ExpectedModS) {
- consumeError(ExpectedModS.takeError());
- return nullptr;
- }
- Expected<DebugChecksumsSubsectionRef> ExpectedChecksums =
- ExpectedModS->findChecksumsSubsection();
- if (!ExpectedChecksums) {
- consumeError(ExpectedChecksums.takeError());
- return nullptr;
- }
-
- // Populate a vector of NativeLineNumbers that have addresses in the given
- // address range.
- std::vector<NativeLineNumber> LineNumbers;
+ if (!ExpectedModS) {
+ consumeError(ExpectedModS.takeError());
+ return nullptr;
+ }
+ Expected<DebugChecksumsSubsectionRef> ExpectedChecksums =
+ ExpectedModS->findChecksumsSubsection();
+ if (!ExpectedChecksums) {
+ consumeError(ExpectedChecksums.takeError());
+ return nullptr;
+ }
+
+ // Populate a vector of NativeLineNumbers that have addresses in the given
+ // address range.
+ std::vector<NativeLineNumber> LineNumbers;
while (LineIter != Lines.end()) {
- if (LineIter->IsTerminalEntry) {
- ++LineIter;
- continue;
- }
-
- // If the line is still within the address range, create a NativeLineNumber
- // and add to the list.
- if (LineIter->Addr > VA + Length)
- break;
-
- uint32_t LineSect, LineOff;
- Session.addressForVA(LineIter->Addr, LineSect, LineOff);
- uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr;
- auto ChecksumIter =
- ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
- uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter);
- NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber,
+ if (LineIter->IsTerminalEntry) {
+ ++LineIter;
+ continue;
+ }
+
+ // If the line is still within the address range, create a NativeLineNumber
+ // and add to the list.
+ if (LineIter->Addr > VA + Length)
+ break;
+
+ uint32_t LineSect, LineOff;
+ Session.addressForVA(LineIter->Addr, LineSect, LineOff);
+ uint32_t LineLength = std::next(LineIter)->Addr - LineIter->Addr;
+ auto ChecksumIter =
+ ExpectedChecksums->getArray().at(LineIter->FileNameIndex);
+ uint32_t SrcFileId = getOrCreateSourceFile(*ChecksumIter);
+ NativeLineNumber LineNum(Session, LineIter->Line, LineIter->ColumnNumber,
LineSect, LineOff, LineLength, SrcFileId, Modi);
- LineNumbers.push_back(LineNum);
- ++LineIter;
- }
- return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers));
-}
-
-std::unique_ptr<PDBSymbolCompiland>
-SymbolCache::getOrCreateCompiland(uint32_t Index) {
- if (!Dbi)
- return nullptr;
-
- if (Index >= Compilands.size())
- return nullptr;
-
- if (Compilands[Index] == 0) {
- const DbiModuleList &Modules = Dbi->modules();
- Compilands[Index] =
- createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index));
- }
-
- return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]);
-}
-
-std::unique_ptr<IPDBSourceFile>
-SymbolCache::getSourceFileById(SymIndexId FileId) const {
- assert(FileId < SourceFiles.size());
-
- // Id 0 is reserved.
- if (FileId == 0)
- return nullptr;
-
- return std::unique_ptr<NativeSourceFile>(
- new NativeSourceFile(*SourceFiles[FileId].get()));
-}
-
-SymIndexId
-SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const {
- auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset);
- if (Iter != FileNameOffsetToId.end())
- return Iter->second;
-
- SymIndexId Id = SourceFiles.size();
- auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums);
- SourceFiles.push_back(std::move(SrcFile));
- FileNameOffsetToId[Checksums.FileNameOffset] = Id;
- return Id;
-}
-
-
+ LineNumbers.push_back(LineNum);
+ ++LineIter;
+ }
+ return std::make_unique<NativeEnumLineNumbers>(std::move(LineNumbers));
+}
+
+std::unique_ptr<PDBSymbolCompiland>
+SymbolCache::getOrCreateCompiland(uint32_t Index) {
+ if (!Dbi)
+ return nullptr;
+
+ if (Index >= Compilands.size())
+ return nullptr;
+
+ if (Compilands[Index] == 0) {
+ const DbiModuleList &Modules = Dbi->modules();
+ Compilands[Index] =
+ createSymbol<NativeCompilandSymbol>(Modules.getModuleDescriptor(Index));
+ }
+
+ return Session.getConcreteSymbolById<PDBSymbolCompiland>(Compilands[Index]);
+}
+
+std::unique_ptr<IPDBSourceFile>
+SymbolCache::getSourceFileById(SymIndexId FileId) const {
+ assert(FileId < SourceFiles.size());
+
+ // Id 0 is reserved.
+ if (FileId == 0)
+ return nullptr;
+
+ return std::unique_ptr<NativeSourceFile>(
+ new NativeSourceFile(*SourceFiles[FileId].get()));
+}
+
+SymIndexId
+SymbolCache::getOrCreateSourceFile(const FileChecksumEntry &Checksums) const {
+ auto Iter = FileNameOffsetToId.find(Checksums.FileNameOffset);
+ if (Iter != FileNameOffsetToId.end())
+ return Iter->second;
+
+ SymIndexId Id = SourceFiles.size();
+ auto SrcFile = std::make_unique<NativeSourceFile>(Session, Id, Checksums);
+ SourceFiles.push_back(std::move(SrcFile));
+ FileNameOffsetToId[Checksums.FileNameOffset] = Id;
+ return Id;
+}
+
+
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolStream.cpp
index 003840b6e6..f07fcecbe2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/SymbolStream.cpp
@@ -1,45 +1,45 @@
-//===- SymbolStream.cpp - PDB Symbol 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/SymbolStream.h"
-
-#include "llvm/DebugInfo/CodeView/CodeView.h"
-#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.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;
-
-SymbolStream::SymbolStream(std::unique_ptr<MappedBlockStream> Stream)
- : Stream(std::move(Stream)) {}
-
-SymbolStream::~SymbolStream() {}
-
-Error SymbolStream::reload() {
- BinaryStreamReader Reader(*Stream);
-
- if (auto EC = Reader.readArray(SymbolRecords, Stream->getLength()))
- return EC;
-
- return Error::success();
-}
-
-iterator_range<codeview::CVSymbolArray::Iterator>
-SymbolStream::getSymbols(bool *HadError) const {
- return llvm::make_range(SymbolRecords.begin(HadError), SymbolRecords.end());
-}
-
-Error SymbolStream::commit() { return Error::success(); }
-
-codeview::CVSymbol SymbolStream::readRecord(uint32_t Offset) const {
- return *SymbolRecords.at(Offset);
-}
+//===- SymbolStream.cpp - PDB Symbol 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/SymbolStream.h"
+
+#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.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;
+
+SymbolStream::SymbolStream(std::unique_ptr<MappedBlockStream> Stream)
+ : Stream(std::move(Stream)) {}
+
+SymbolStream::~SymbolStream() {}
+
+Error SymbolStream::reload() {
+ BinaryStreamReader Reader(*Stream);
+
+ if (auto EC = Reader.readArray(SymbolRecords, Stream->getLength()))
+ return EC;
+
+ return Error::success();
+}
+
+iterator_range<codeview::CVSymbolArray::Iterator>
+SymbolStream::getSymbols(bool *HadError) const {
+ return llvm::make_range(SymbolRecords.begin(HadError), SymbolRecords.end());
+}
+
+Error SymbolStream::commit() { return Error::success(); }
+
+codeview::CVSymbol SymbolStream::readRecord(uint32_t Offset) const {
+ return *SymbolRecords.at(Offset);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiHashing.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiHashing.cpp
index b71b2b1581..5695e974fa 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiHashing.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiHashing.cpp
@@ -1,129 +1,129 @@
-//===- TpiHashing.cpp -----------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
-
-#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/Support/CRC.h"
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::pdb;
-
-// Corresponds to `fUDTAnon`.
-static bool isAnonymous(StringRef Name) {
- return Name == "<unnamed-tag>" || Name == "__unnamed" ||
- Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed");
-}
-
-// Computes the hash for a user-defined type record. This could be a struct,
-// class, union, or enum.
-static uint32_t getHashForUdt(const TagRecord &Rec,
- ArrayRef<uint8_t> FullRecord) {
- ClassOptions Opts = Rec.getOptions();
- bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
- bool Scoped = bool(Opts & ClassOptions::Scoped);
- bool HasUniqueName = bool(Opts & ClassOptions::HasUniqueName);
- bool IsAnon = HasUniqueName && isAnonymous(Rec.getName());
-
- if (!ForwardRef && !Scoped && !IsAnon)
- return hashStringV1(Rec.getName());
- if (!ForwardRef && HasUniqueName && !IsAnon)
- return hashStringV1(Rec.getUniqueName());
- return hashBufferV8(FullRecord);
-}
-
-template <typename T>
-static Expected<uint32_t> getHashForUdt(const CVType &Rec) {
- T Deserialized;
- if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
- Deserialized))
- return std::move(E);
- return getHashForUdt(Deserialized, Rec.data());
-}
-
-template <typename T>
-static Expected<TagRecordHash> getTagRecordHashForUdt(const CVType &Rec) {
- T Deserialized;
- if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
- Deserialized))
- return std::move(E);
-
- ClassOptions Opts = Deserialized.getOptions();
-
- bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
-
- uint32_t ThisRecordHash = getHashForUdt(Deserialized, Rec.data());
-
- // If we don't have a forward ref we can't compute the hash of it from the
- // full record because it requires hashing the entire buffer.
- if (!ForwardRef)
- return TagRecordHash{std::move(Deserialized), ThisRecordHash, 0};
-
- bool Scoped = bool(Opts & ClassOptions::Scoped);
-
- StringRef NameToHash =
- Scoped ? Deserialized.getUniqueName() : Deserialized.getName();
- uint32_t FullHash = hashStringV1(NameToHash);
- return TagRecordHash{std::move(Deserialized), FullHash, ThisRecordHash};
-}
-
-template <typename T>
-static Expected<uint32_t> getSourceLineHash(const CVType &Rec) {
- T Deserialized;
- if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
- Deserialized))
- return std::move(E);
- char Buf[4];
- support::endian::write32le(Buf, Deserialized.getUDT().getIndex());
- return hashStringV1(StringRef(Buf, 4));
-}
-
-Expected<TagRecordHash> llvm::pdb::hashTagRecord(const codeview::CVType &Type) {
- switch (Type.kind()) {
- case LF_CLASS:
- case LF_STRUCTURE:
- case LF_INTERFACE:
- return getTagRecordHashForUdt<ClassRecord>(Type);
- case LF_UNION:
- return getTagRecordHashForUdt<UnionRecord>(Type);
- case LF_ENUM:
- return getTagRecordHashForUdt<EnumRecord>(Type);
- default:
- assert(false && "Type is not a tag record!");
- }
- return make_error<StringError>("Invalid record type",
- inconvertibleErrorCode());
-}
-
-Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) {
- switch (Rec.kind()) {
- case LF_CLASS:
- case LF_STRUCTURE:
- case LF_INTERFACE:
- return getHashForUdt<ClassRecord>(Rec);
- case LF_UNION:
- return getHashForUdt<UnionRecord>(Rec);
- case LF_ENUM:
- return getHashForUdt<EnumRecord>(Rec);
-
- case LF_UDT_SRC_LINE:
- return getSourceLineHash<UdtSourceLineRecord>(Rec);
- case LF_UDT_MOD_SRC_LINE:
- return getSourceLineHash<UdtModSourceLineRecord>(Rec);
-
- default:
- break;
- }
-
- // Run CRC32 over the bytes. This corresponds to `hashBufv8`.
- JamCRC JC(/*Init=*/0U);
- JC.update(Rec.data());
- return JC.getCRC();
-}
+//===- TpiHashing.cpp -----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
+
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/Support/CRC.h"
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::pdb;
+
+// Corresponds to `fUDTAnon`.
+static bool isAnonymous(StringRef Name) {
+ return Name == "<unnamed-tag>" || Name == "__unnamed" ||
+ Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed");
+}
+
+// Computes the hash for a user-defined type record. This could be a struct,
+// class, union, or enum.
+static uint32_t getHashForUdt(const TagRecord &Rec,
+ ArrayRef<uint8_t> FullRecord) {
+ ClassOptions Opts = Rec.getOptions();
+ bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
+ bool Scoped = bool(Opts & ClassOptions::Scoped);
+ bool HasUniqueName = bool(Opts & ClassOptions::HasUniqueName);
+ bool IsAnon = HasUniqueName && isAnonymous(Rec.getName());
+
+ if (!ForwardRef && !Scoped && !IsAnon)
+ return hashStringV1(Rec.getName());
+ if (!ForwardRef && HasUniqueName && !IsAnon)
+ return hashStringV1(Rec.getUniqueName());
+ return hashBufferV8(FullRecord);
+}
+
+template <typename T>
+static Expected<uint32_t> getHashForUdt(const CVType &Rec) {
+ T Deserialized;
+ if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
+ Deserialized))
+ return std::move(E);
+ return getHashForUdt(Deserialized, Rec.data());
+}
+
+template <typename T>
+static Expected<TagRecordHash> getTagRecordHashForUdt(const CVType &Rec) {
+ T Deserialized;
+ if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
+ Deserialized))
+ return std::move(E);
+
+ ClassOptions Opts = Deserialized.getOptions();
+
+ bool ForwardRef = bool(Opts & ClassOptions::ForwardReference);
+
+ uint32_t ThisRecordHash = getHashForUdt(Deserialized, Rec.data());
+
+ // If we don't have a forward ref we can't compute the hash of it from the
+ // full record because it requires hashing the entire buffer.
+ if (!ForwardRef)
+ return TagRecordHash{std::move(Deserialized), ThisRecordHash, 0};
+
+ bool Scoped = bool(Opts & ClassOptions::Scoped);
+
+ StringRef NameToHash =
+ Scoped ? Deserialized.getUniqueName() : Deserialized.getName();
+ uint32_t FullHash = hashStringV1(NameToHash);
+ return TagRecordHash{std::move(Deserialized), FullHash, ThisRecordHash};
+}
+
+template <typename T>
+static Expected<uint32_t> getSourceLineHash(const CVType &Rec) {
+ T Deserialized;
+ if (auto E = TypeDeserializer::deserializeAs(const_cast<CVType &>(Rec),
+ Deserialized))
+ return std::move(E);
+ char Buf[4];
+ support::endian::write32le(Buf, Deserialized.getUDT().getIndex());
+ return hashStringV1(StringRef(Buf, 4));
+}
+
+Expected<TagRecordHash> llvm::pdb::hashTagRecord(const codeview::CVType &Type) {
+ switch (Type.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE:
+ return getTagRecordHashForUdt<ClassRecord>(Type);
+ case LF_UNION:
+ return getTagRecordHashForUdt<UnionRecord>(Type);
+ case LF_ENUM:
+ return getTagRecordHashForUdt<EnumRecord>(Type);
+ default:
+ assert(false && "Type is not a tag record!");
+ }
+ return make_error<StringError>("Invalid record type",
+ inconvertibleErrorCode());
+}
+
+Expected<uint32_t> llvm::pdb::hashTypeRecord(const CVType &Rec) {
+ switch (Rec.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE:
+ return getHashForUdt<ClassRecord>(Rec);
+ case LF_UNION:
+ return getHashForUdt<UnionRecord>(Rec);
+ case LF_ENUM:
+ return getHashForUdt<EnumRecord>(Rec);
+
+ case LF_UDT_SRC_LINE:
+ return getSourceLineHash<UdtSourceLineRecord>(Rec);
+ case LF_UDT_MOD_SRC_LINE:
+ return getSourceLineHash<UdtModSourceLineRecord>(Rec);
+
+ default:
+ break;
+ }
+
+ // Run CRC32 over the bytes. This corresponds to `hashBufv8`.
+ JamCRC JC(/*Init=*/0U);
+ JC.update(Rec.data());
+ return JC.getCRC();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStream.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStream.cpp
index ac19db03fa..e82fc1b4c2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStream.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStream.cpp
@@ -1,246 +1,246 @@
-//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 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/TpiStream.h"
-
-#include "llvm/ADT/iterator_range.h"
-#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
-#include "llvm/DebugInfo/CodeView/RecordName.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/Hash.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::codeview;
-using namespace llvm::support;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-
-TpiStream::TpiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream)
- : Pdb(File), Stream(std::move(Stream)) {}
-
-TpiStream::~TpiStream() = default;
-
-Error TpiStream::reload() {
- BinaryStreamReader Reader(*Stream);
-
- if (Reader.bytesRemaining() < sizeof(TpiStreamHeader))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "TPI Stream does not contain a header.");
-
- if (Reader.readObject(Header))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "TPI Stream does not contain a header.");
-
- if (Header->Version != PdbTpiV80)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Unsupported TPI Version.");
-
- if (Header->HeaderSize != sizeof(TpiStreamHeader))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "Corrupt TPI Header size.");
-
- if (Header->HashKeySize != sizeof(ulittle32_t))
- return make_error<RawError>(raw_error_code::corrupt_file,
- "TPI Stream expected 4 byte hash key size.");
-
- if (Header->NumHashBuckets < MinTpiHashBuckets ||
- Header->NumHashBuckets > MaxTpiHashBuckets)
- return make_error<RawError>(raw_error_code::corrupt_file,
- "TPI Stream Invalid number of hash buckets.");
-
- // The actual type records themselves come from this stream
- if (auto EC =
- Reader.readSubstream(TypeRecordsSubstream, Header->TypeRecordBytes))
- return EC;
-
- BinaryStreamReader RecordReader(TypeRecordsSubstream.StreamData);
- if (auto EC =
- RecordReader.readArray(TypeRecords, TypeRecordsSubstream.size()))
- return EC;
-
- // Hash indices, hash values, etc come from the hash stream.
- if (Header->HashStreamIndex != kInvalidStreamIndex) {
- 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.");
- }
- BinaryStreamReader HSR(**HS);
-
- // There should be a hash value for every type record, or no hashes at all.
- uint32_t NumHashValues =
- Header->HashValueBuffer.Length / sizeof(ulittle32_t);
- if (NumHashValues != getNumTypeRecords() && NumHashValues != 0)
- return make_error<RawError>(
- raw_error_code::corrupt_file,
- "TPI hash count does not match with the number of type records.");
- HSR.setOffset(Header->HashValueBuffer.Off);
- if (auto EC = HSR.readArray(HashValues, NumHashValues))
- return EC;
-
- HSR.setOffset(Header->IndexOffsetBuffer.Off);
- uint32_t NumTypeIndexOffsets =
- Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
- if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
- return EC;
-
- if (Header->HashAdjBuffer.Length > 0) {
- HSR.setOffset(Header->HashAdjBuffer.Off);
- if (auto EC = HashAdjusters.load(HSR))
- return EC;
- }
-
- HashStream = std::move(*HS);
- }
-
- Types = std::make_unique<LazyRandomTypeCollection>(
- TypeRecords, getNumTypeRecords(), getTypeIndexOffsets());
- return Error::success();
-}
-
-PdbRaw_TpiVer TpiStream::getTpiVersion() const {
- uint32_t Value = Header->Version;
- return static_cast<PdbRaw_TpiVer>(Value);
-}
-
-uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }
-
-uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }
-
-uint32_t TpiStream::getNumTypeRecords() const {
- return TypeIndexEnd() - TypeIndexBegin();
-}
-
-uint16_t TpiStream::getTypeHashStreamIndex() const {
- return Header->HashStreamIndex;
-}
-
-uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
- return Header->HashAuxStreamIndex;
-}
-
-uint32_t TpiStream::getNumHashBuckets() const { return Header->NumHashBuckets; }
-uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }
-
-void TpiStream::buildHashMap() {
- if (!HashMap.empty())
- return;
- if (HashValues.empty())
- return;
-
- HashMap.resize(Header->NumHashBuckets);
-
- TypeIndex TIB{Header->TypeIndexBegin};
- TypeIndex TIE{Header->TypeIndexEnd};
- while (TIB < TIE) {
- uint32_t HV = HashValues[TIB.toArrayIndex()];
- HashMap[HV].push_back(TIB++);
- }
-}
-
-std::vector<TypeIndex> TpiStream::findRecordsByName(StringRef Name) const {
- if (!supportsTypeLookup())
- const_cast<TpiStream*>(this)->buildHashMap();
-
- uint32_t Bucket = hashStringV1(Name) % Header->NumHashBuckets;
- if (Bucket > HashMap.size())
- return {};
-
- std::vector<TypeIndex> Result;
- for (TypeIndex TI : HashMap[Bucket]) {
- std::string ThisName = computeTypeName(*Types, TI);
- if (ThisName == Name)
- Result.push_back(TI);
- }
- return Result;
-}
-
-bool TpiStream::supportsTypeLookup() const { return !HashMap.empty(); }
-
-Expected<TypeIndex>
-TpiStream::findFullDeclForForwardRef(TypeIndex ForwardRefTI) const {
- if (!supportsTypeLookup())
- const_cast<TpiStream*>(this)->buildHashMap();
-
- CVType F = Types->getType(ForwardRefTI);
- if (!isUdtForwardRef(F))
- return ForwardRefTI;
-
- Expected<TagRecordHash> ForwardTRH = hashTagRecord(F);
- if (!ForwardTRH)
- return ForwardTRH.takeError();
-
- uint32_t BucketIdx = ForwardTRH->FullRecordHash % Header->NumHashBuckets;
-
- for (TypeIndex TI : HashMap[BucketIdx]) {
- CVType CVT = Types->getType(TI);
- if (CVT.kind() != F.kind())
- continue;
-
- Expected<TagRecordHash> FullTRH = hashTagRecord(CVT);
- if (!FullTRH)
- return FullTRH.takeError();
- if (ForwardTRH->FullRecordHash != FullTRH->FullRecordHash)
- continue;
- TagRecord &ForwardTR = ForwardTRH->getRecord();
- TagRecord &FullTR = FullTRH->getRecord();
-
- if (!ForwardTR.hasUniqueName()) {
- if (ForwardTR.getName() == FullTR.getName())
- return TI;
- continue;
- }
-
- if (!FullTR.hasUniqueName())
- continue;
- if (ForwardTR.getUniqueName() == FullTR.getUniqueName())
- return TI;
- }
- return ForwardRefTI;
-}
-
-codeview::CVType TpiStream::getType(codeview::TypeIndex Index) {
- assert(!Index.isSimple());
- return Types->getType(Index);
-}
-
-BinarySubstreamRef TpiStream::getTypeRecordsSubstream() const {
- return TypeRecordsSubstream;
-}
-
-FixedStreamArray<support::ulittle32_t> TpiStream::getHashValues() const {
- return HashValues;
-}
-
-FixedStreamArray<TypeIndexOffset> TpiStream::getTypeIndexOffsets() const {
- return TypeIndexOffsets;
-}
-
-HashTable<support::ulittle32_t> &TpiStream::getHashAdjusters() {
- return HashAdjusters;
-}
-
-CVTypeRange TpiStream::types(bool *HadError) const {
- return make_range(TypeRecords.begin(HadError), TypeRecords.end());
-}
-
-Error TpiStream::commit() { return Error::success(); }
+//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 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/TpiStream.h"
+
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
+#include "llvm/DebugInfo/CodeView/RecordName.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/CodeView/TypeRecordHelpers.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/Hash.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawConstants.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/DebugInfo/PDB/Native/TpiHashing.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::codeview;
+using namespace llvm::support;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+
+TpiStream::TpiStream(PDBFile &File, std::unique_ptr<MappedBlockStream> Stream)
+ : Pdb(File), Stream(std::move(Stream)) {}
+
+TpiStream::~TpiStream() = default;
+
+Error TpiStream::reload() {
+ BinaryStreamReader Reader(*Stream);
+
+ if (Reader.bytesRemaining() < sizeof(TpiStreamHeader))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "TPI Stream does not contain a header.");
+
+ if (Reader.readObject(Header))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "TPI Stream does not contain a header.");
+
+ if (Header->Version != PdbTpiV80)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Unsupported TPI Version.");
+
+ if (Header->HeaderSize != sizeof(TpiStreamHeader))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "Corrupt TPI Header size.");
+
+ if (Header->HashKeySize != sizeof(ulittle32_t))
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "TPI Stream expected 4 byte hash key size.");
+
+ if (Header->NumHashBuckets < MinTpiHashBuckets ||
+ Header->NumHashBuckets > MaxTpiHashBuckets)
+ return make_error<RawError>(raw_error_code::corrupt_file,
+ "TPI Stream Invalid number of hash buckets.");
+
+ // The actual type records themselves come from this stream
+ if (auto EC =
+ Reader.readSubstream(TypeRecordsSubstream, Header->TypeRecordBytes))
+ return EC;
+
+ BinaryStreamReader RecordReader(TypeRecordsSubstream.StreamData);
+ if (auto EC =
+ RecordReader.readArray(TypeRecords, TypeRecordsSubstream.size()))
+ return EC;
+
+ // Hash indices, hash values, etc come from the hash stream.
+ if (Header->HashStreamIndex != kInvalidStreamIndex) {
+ 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.");
+ }
+ BinaryStreamReader HSR(**HS);
+
+ // There should be a hash value for every type record, or no hashes at all.
+ uint32_t NumHashValues =
+ Header->HashValueBuffer.Length / sizeof(ulittle32_t);
+ if (NumHashValues != getNumTypeRecords() && NumHashValues != 0)
+ return make_error<RawError>(
+ raw_error_code::corrupt_file,
+ "TPI hash count does not match with the number of type records.");
+ HSR.setOffset(Header->HashValueBuffer.Off);
+ if (auto EC = HSR.readArray(HashValues, NumHashValues))
+ return EC;
+
+ HSR.setOffset(Header->IndexOffsetBuffer.Off);
+ uint32_t NumTypeIndexOffsets =
+ Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
+ if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
+ return EC;
+
+ if (Header->HashAdjBuffer.Length > 0) {
+ HSR.setOffset(Header->HashAdjBuffer.Off);
+ if (auto EC = HashAdjusters.load(HSR))
+ return EC;
+ }
+
+ HashStream = std::move(*HS);
+ }
+
+ Types = std::make_unique<LazyRandomTypeCollection>(
+ TypeRecords, getNumTypeRecords(), getTypeIndexOffsets());
+ return Error::success();
+}
+
+PdbRaw_TpiVer TpiStream::getTpiVersion() const {
+ uint32_t Value = Header->Version;
+ return static_cast<PdbRaw_TpiVer>(Value);
+}
+
+uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }
+
+uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }
+
+uint32_t TpiStream::getNumTypeRecords() const {
+ return TypeIndexEnd() - TypeIndexBegin();
+}
+
+uint16_t TpiStream::getTypeHashStreamIndex() const {
+ return Header->HashStreamIndex;
+}
+
+uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
+ return Header->HashAuxStreamIndex;
+}
+
+uint32_t TpiStream::getNumHashBuckets() const { return Header->NumHashBuckets; }
+uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }
+
+void TpiStream::buildHashMap() {
+ if (!HashMap.empty())
+ return;
+ if (HashValues.empty())
+ return;
+
+ HashMap.resize(Header->NumHashBuckets);
+
+ TypeIndex TIB{Header->TypeIndexBegin};
+ TypeIndex TIE{Header->TypeIndexEnd};
+ while (TIB < TIE) {
+ uint32_t HV = HashValues[TIB.toArrayIndex()];
+ HashMap[HV].push_back(TIB++);
+ }
+}
+
+std::vector<TypeIndex> TpiStream::findRecordsByName(StringRef Name) const {
+ if (!supportsTypeLookup())
+ const_cast<TpiStream*>(this)->buildHashMap();
+
+ uint32_t Bucket = hashStringV1(Name) % Header->NumHashBuckets;
+ if (Bucket > HashMap.size())
+ return {};
+
+ std::vector<TypeIndex> Result;
+ for (TypeIndex TI : HashMap[Bucket]) {
+ std::string ThisName = computeTypeName(*Types, TI);
+ if (ThisName == Name)
+ Result.push_back(TI);
+ }
+ return Result;
+}
+
+bool TpiStream::supportsTypeLookup() const { return !HashMap.empty(); }
+
+Expected<TypeIndex>
+TpiStream::findFullDeclForForwardRef(TypeIndex ForwardRefTI) const {
+ if (!supportsTypeLookup())
+ const_cast<TpiStream*>(this)->buildHashMap();
+
+ CVType F = Types->getType(ForwardRefTI);
+ if (!isUdtForwardRef(F))
+ return ForwardRefTI;
+
+ Expected<TagRecordHash> ForwardTRH = hashTagRecord(F);
+ if (!ForwardTRH)
+ return ForwardTRH.takeError();
+
+ uint32_t BucketIdx = ForwardTRH->FullRecordHash % Header->NumHashBuckets;
+
+ for (TypeIndex TI : HashMap[BucketIdx]) {
+ CVType CVT = Types->getType(TI);
+ if (CVT.kind() != F.kind())
+ continue;
+
+ Expected<TagRecordHash> FullTRH = hashTagRecord(CVT);
+ if (!FullTRH)
+ return FullTRH.takeError();
+ if (ForwardTRH->FullRecordHash != FullTRH->FullRecordHash)
+ continue;
+ TagRecord &ForwardTR = ForwardTRH->getRecord();
+ TagRecord &FullTR = FullTRH->getRecord();
+
+ if (!ForwardTR.hasUniqueName()) {
+ if (ForwardTR.getName() == FullTR.getName())
+ return TI;
+ continue;
+ }
+
+ if (!FullTR.hasUniqueName())
+ continue;
+ if (ForwardTR.getUniqueName() == FullTR.getUniqueName())
+ return TI;
+ }
+ return ForwardRefTI;
+}
+
+codeview::CVType TpiStream::getType(codeview::TypeIndex Index) {
+ assert(!Index.isSimple());
+ return Types->getType(Index);
+}
+
+BinarySubstreamRef TpiStream::getTypeRecordsSubstream() const {
+ return TypeRecordsSubstream;
+}
+
+FixedStreamArray<support::ulittle32_t> TpiStream::getHashValues() const {
+ return HashValues;
+}
+
+FixedStreamArray<TypeIndexOffset> TpiStream::getTypeIndexOffsets() const {
+ return TypeIndexOffsets;
+}
+
+HashTable<support::ulittle32_t> &TpiStream::getHashAdjusters() {
+ return HashAdjusters;
+}
+
+CVTypeRange TpiStream::types(bool *HadError) const {
+ return make_range(TypeRecords.begin(HadError), TypeRecords.end());
+}
+
+Error TpiStream::commit() { return Error::success(); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
index 5f4f497690..204ca508d4 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/Native/TpiStreamBuilder.cpp
@@ -1,47 +1,47 @@
-//===- TpiStreamBuilder.cpp - -------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeRecord.h"
-#include "llvm/DebugInfo/MSF/MSFBuilder.h"
-#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
-#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
-#include "llvm/DebugInfo/PDB/Native/RawError.h"
-#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/BinaryByteStream.h"
-#include "llvm/Support/BinaryStreamArray.h"
-#include "llvm/Support/BinaryStreamReader.h"
-#include "llvm/Support/BinaryStreamWriter.h"
-#include "llvm/Support/Endian.h"
-#include "llvm/Support/Error.h"
-#include <algorithm>
-#include <cstdint>
+//===- TpiStreamBuilder.cpp - -------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/CodeView/TypeIndex.h"
+#include "llvm/DebugInfo/CodeView/TypeRecord.h"
+#include "llvm/DebugInfo/MSF/MSFBuilder.h"
+#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
+#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
+#include "llvm/DebugInfo/PDB/Native/RawError.h"
+#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/BinaryByteStream.h"
+#include "llvm/Support/BinaryStreamArray.h"
+#include "llvm/Support/BinaryStreamReader.h"
+#include "llvm/Support/BinaryStreamWriter.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include <algorithm>
+#include <cstdint>
#include <numeric>
-
-using namespace llvm;
-using namespace llvm::msf;
-using namespace llvm::pdb;
-using namespace llvm::support;
-
-TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx)
- : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) {
-}
-
-TpiStreamBuilder::~TpiStreamBuilder() = default;
-
-void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
- VerHeader = Version;
-}
-
+
+using namespace llvm;
+using namespace llvm::msf;
+using namespace llvm::pdb;
+using namespace llvm::support;
+
+TpiStreamBuilder::TpiStreamBuilder(MSFBuilder &Msf, uint32_t StreamIdx)
+ : Msf(Msf), Allocator(Msf.getAllocator()), Header(nullptr), Idx(StreamIdx) {
+}
+
+TpiStreamBuilder::~TpiStreamBuilder() = default;
+
+void TpiStreamBuilder::setVersionHeader(PdbRaw_TpiVer Version) {
+ VerHeader = Version;
+}
+
void TpiStreamBuilder::updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes) {
// If we just crossed an 8KB threshold, add a type index offset.
for (uint16_t Size : Sizes) {
@@ -58,21 +58,21 @@ void TpiStreamBuilder::updateTypeIndexOffsets(ArrayRef<uint16_t> Sizes) {
}
}
-void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
- Optional<uint32_t> Hash) {
- assert(((Record.size() & 3) == 0) &&
- "The type record's size is not a multiple of 4 bytes which will "
- "cause misalignment in the output TPI stream!");
+void TpiStreamBuilder::addTypeRecord(ArrayRef<uint8_t> Record,
+ Optional<uint32_t> Hash) {
+ assert(((Record.size() & 3) == 0) &&
+ "The type record's size is not a multiple of 4 bytes which will "
+ "cause misalignment in the output TPI stream!");
assert(Record.size() <= codeview::MaxRecordLength);
uint16_t OneSize = (uint16_t)Record.size();
updateTypeIndexOffsets(makeArrayRef(&OneSize, 1));
-
+
TypeRecBuffers.push_back(Record);
// FIXME: Require it.
- if (Hash)
- TypeHashes.push_back(*Hash);
-}
-
+ if (Hash)
+ TypeHashes.push_back(*Hash);
+}
+
void TpiStreamBuilder::addTypeRecords(ArrayRef<uint8_t> Types,
ArrayRef<uint16_t> Sizes,
ArrayRef<uint32_t> Hashes) {
@@ -94,121 +94,121 @@ void TpiStreamBuilder::addTypeRecords(ArrayRef<uint8_t> Types,
llvm::append_range(TypeHashes, Hashes);
}
-Error TpiStreamBuilder::finalize() {
- if (Header)
- return Error::success();
-
- TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
-
- H->Version = VerHeader;
- H->HeaderSize = sizeof(TpiStreamHeader);
- H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
+Error TpiStreamBuilder::finalize() {
+ if (Header)
+ return Error::success();
+
+ TpiStreamHeader *H = Allocator.Allocate<TpiStreamHeader>();
+
+ H->Version = VerHeader;
+ H->HeaderSize = sizeof(TpiStreamHeader);
+ H->TypeIndexBegin = codeview::TypeIndex::FirstNonSimpleIndex;
H->TypeIndexEnd = H->TypeIndexBegin + TypeRecordCount;
- H->TypeRecordBytes = TypeRecordBytes;
-
- H->HashStreamIndex = HashStreamIndex;
- H->HashAuxStreamIndex = kInvalidStreamIndex;
- H->HashKeySize = sizeof(ulittle32_t);
- 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
- // begins at offset 0 of this independent stream.
- H->HashValueBuffer.Off = 0;
- H->HashValueBuffer.Length = calculateHashBufferSize();
-
- // We never write any adjustments into our PDBs, so this is usually some
- // offset with zero length.
- H->HashAdjBuffer.Off = H->HashValueBuffer.Off + H->HashValueBuffer.Length;
- H->HashAdjBuffer.Length = 0;
-
- H->IndexOffsetBuffer.Off = H->HashAdjBuffer.Off + H->HashAdjBuffer.Length;
- H->IndexOffsetBuffer.Length = calculateIndexOffsetSize();
-
- Header = H;
- return Error::success();
-}
-
-uint32_t TpiStreamBuilder::calculateSerializedLength() {
- return sizeof(TpiStreamHeader) + TypeRecordBytes;
-}
-
-uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
+ H->TypeRecordBytes = TypeRecordBytes;
+
+ H->HashStreamIndex = HashStreamIndex;
+ H->HashAuxStreamIndex = kInvalidStreamIndex;
+ H->HashKeySize = sizeof(ulittle32_t);
+ 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
+ // begins at offset 0 of this independent stream.
+ H->HashValueBuffer.Off = 0;
+ H->HashValueBuffer.Length = calculateHashBufferSize();
+
+ // We never write any adjustments into our PDBs, so this is usually some
+ // offset with zero length.
+ H->HashAdjBuffer.Off = H->HashValueBuffer.Off + H->HashValueBuffer.Length;
+ H->HashAdjBuffer.Length = 0;
+
+ H->IndexOffsetBuffer.Off = H->HashAdjBuffer.Off + H->HashAdjBuffer.Length;
+ H->IndexOffsetBuffer.Length = calculateIndexOffsetSize();
+
+ Header = H;
+ return Error::success();
+}
+
+uint32_t TpiStreamBuilder::calculateSerializedLength() {
+ return sizeof(TpiStreamHeader) + TypeRecordBytes;
+}
+
+uint32_t TpiStreamBuilder::calculateHashBufferSize() const {
assert((TypeRecordCount == TypeHashes.size() || TypeHashes.empty()) &&
- "either all or no type records should have hashes");
- return TypeHashes.size() * sizeof(ulittle32_t);
-}
-
-uint32_t TpiStreamBuilder::calculateIndexOffsetSize() const {
- return TypeIndexOffsets.size() * sizeof(codeview::TypeIndexOffset);
-}
-
-Error TpiStreamBuilder::finalizeMsfLayout() {
- uint32_t Length = calculateSerializedLength();
- if (auto EC = Msf.setStreamSize(Idx, Length))
- return EC;
-
- uint32_t HashStreamSize =
- calculateHashBufferSize() + calculateIndexOffsetSize();
-
- if (HashStreamSize == 0)
- return Error::success();
-
- auto ExpectedIndex = Msf.addStream(HashStreamSize);
- if (!ExpectedIndex)
- return ExpectedIndex.takeError();
- HashStreamIndex = *ExpectedIndex;
- if (!TypeHashes.empty()) {
- 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] % (MaxTpiHashBuckets - 1);
- }
- ArrayRef<uint8_t> Bytes(
- reinterpret_cast<const uint8_t *>(HashBuffer.data()),
- calculateHashBufferSize());
- HashValueStream =
- std::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
- }
- return Error::success();
-}
-
-Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
- WritableBinaryStreamRef Buffer) {
- if (auto EC = finalize())
- return EC;
-
- auto InfoS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
- Idx, Allocator);
-
- BinaryStreamWriter Writer(*InfoS);
- if (auto EC = Writer.writeObject(*Header))
- return EC;
-
+ "either all or no type records should have hashes");
+ return TypeHashes.size() * sizeof(ulittle32_t);
+}
+
+uint32_t TpiStreamBuilder::calculateIndexOffsetSize() const {
+ return TypeIndexOffsets.size() * sizeof(codeview::TypeIndexOffset);
+}
+
+Error TpiStreamBuilder::finalizeMsfLayout() {
+ uint32_t Length = calculateSerializedLength();
+ if (auto EC = Msf.setStreamSize(Idx, Length))
+ return EC;
+
+ uint32_t HashStreamSize =
+ calculateHashBufferSize() + calculateIndexOffsetSize();
+
+ if (HashStreamSize == 0)
+ return Error::success();
+
+ auto ExpectedIndex = Msf.addStream(HashStreamSize);
+ if (!ExpectedIndex)
+ return ExpectedIndex.takeError();
+ HashStreamIndex = *ExpectedIndex;
+ if (!TypeHashes.empty()) {
+ 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] % (MaxTpiHashBuckets - 1);
+ }
+ ArrayRef<uint8_t> Bytes(
+ reinterpret_cast<const uint8_t *>(HashBuffer.data()),
+ calculateHashBufferSize());
+ HashValueStream =
+ std::make_unique<BinaryByteStream>(Bytes, llvm::support::little);
+ }
+ return Error::success();
+}
+
+Error TpiStreamBuilder::commit(const msf::MSFLayout &Layout,
+ WritableBinaryStreamRef Buffer) {
+ if (auto EC = finalize())
+ return EC;
+
+ auto InfoS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
+ Idx, Allocator);
+
+ BinaryStreamWriter Writer(*InfoS);
+ if (auto EC = Writer.writeObject(*Header))
+ return EC;
+
for (auto Rec : TypeRecBuffers) {
- assert(!Rec.empty() && "Attempting to write an empty type record shifts "
- "all offsets in the TPI stream!");
- assert(((Rec.size() & 3) == 0) &&
- "The type record's size is not a multiple of 4 bytes which will "
- "cause misalignment in the output TPI stream!");
- if (auto EC = Writer.writeBytes(Rec))
- return EC;
- }
-
- if (HashStreamIndex != kInvalidStreamIndex) {
- auto HVS = WritableMappedBlockStream::createIndexedStream(
- Layout, Buffer, HashStreamIndex, Allocator);
- BinaryStreamWriter HW(*HVS);
- if (HashValueStream) {
- if (auto EC = HW.writeStreamRef(*HashValueStream))
- return EC;
- }
-
- for (auto &IndexOffset : TypeIndexOffsets) {
- if (auto EC = HW.writeObject(IndexOffset))
- return EC;
- }
- }
-
- return Error::success();
-}
+ assert(!Rec.empty() && "Attempting to write an empty type record shifts "
+ "all offsets in the TPI stream!");
+ assert(((Rec.size() & 3) == 0) &&
+ "The type record's size is not a multiple of 4 bytes which will "
+ "cause misalignment in the output TPI stream!");
+ if (auto EC = Writer.writeBytes(Rec))
+ return EC;
+ }
+
+ if (HashStreamIndex != kInvalidStreamIndex) {
+ auto HVS = WritableMappedBlockStream::createIndexedStream(
+ Layout, Buffer, HashStreamIndex, Allocator);
+ BinaryStreamWriter HW(*HVS);
+ if (HashValueStream) {
+ if (auto EC = HW.writeStreamRef(*HashValueStream))
+ return EC;
+ }
+
+ for (auto &IndexOffset : TypeIndexOffsets) {
+ if (auto EC = HW.writeObject(IndexOffset))
+ return EC;
+ }
+ }
+
+ return Error::success();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp
index 6dc42715fb..9c1737663a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDB.cpp
@@ -1,51 +1,51 @@
-//===- PDB.cpp - base header file for creating a PDB reader ---------------===//
-//
-// 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/PDB.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Config/config.h"
-#include "llvm/DebugInfo/PDB/GenericError.h"
-#if LLVM_ENABLE_DIA_SDK
+//===- PDB.cpp - base header file for creating a PDB reader ---------------===//
+//
+// 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/PDB.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
+#include "llvm/DebugInfo/PDB/GenericError.h"
+#if LLVM_ENABLE_DIA_SDK
#error #include "llvm/DebugInfo/PDB/DIA/DIASession.h"
-#endif
-#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
-#include "llvm/Support/Error.h"
-#include "llvm/Support/MemoryBuffer.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-Error llvm::pdb::loadDataForPDB(PDB_ReaderType Type, StringRef Path,
- std::unique_ptr<IPDBSession> &Session) {
- // Create the correct concrete instance type based on the value of Type.
- if (Type == PDB_ReaderType::Native)
- return NativeSession::createFromPdbPath(Path, Session);
-
-#if LLVM_ENABLE_DIA_SDK
- return DIASession::createFromPdb(Path, Session);
-#else
- return make_error<PDBError>(pdb_error_code::dia_sdk_not_present);
-#endif
-}
-
-Error llvm::pdb::loadDataForEXE(PDB_ReaderType Type, StringRef Path,
- std::unique_ptr<IPDBSession> &Session) {
- // Create the correct concrete instance type based on the value of Type.
- if (Type == PDB_ReaderType::Native) {
- Expected<std::string> PdbPath = NativeSession::searchForPdb({Path});
- if (!PdbPath)
- return PdbPath.takeError();
- return NativeSession::createFromPdbPath(PdbPath.get(), Session);
- }
-
-#if LLVM_ENABLE_DIA_SDK
- return DIASession::createFromExe(Path, Session);
-#else
- return make_error<PDBError>(pdb_error_code::dia_sdk_not_present);
-#endif
-}
+#endif
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+Error llvm::pdb::loadDataForPDB(PDB_ReaderType Type, StringRef Path,
+ std::unique_ptr<IPDBSession> &Session) {
+ // Create the correct concrete instance type based on the value of Type.
+ if (Type == PDB_ReaderType::Native)
+ return NativeSession::createFromPdbPath(Path, Session);
+
+#if LLVM_ENABLE_DIA_SDK
+ return DIASession::createFromPdb(Path, Session);
+#else
+ return make_error<PDBError>(pdb_error_code::dia_sdk_not_present);
+#endif
+}
+
+Error llvm::pdb::loadDataForEXE(PDB_ReaderType Type, StringRef Path,
+ std::unique_ptr<IPDBSession> &Session) {
+ // Create the correct concrete instance type based on the value of Type.
+ if (Type == PDB_ReaderType::Native) {
+ Expected<std::string> PdbPath = NativeSession::searchForPdb({Path});
+ if (!PdbPath)
+ return PdbPath.takeError();
+ return NativeSession::createFromPdbPath(PdbPath.get(), Session);
+ }
+
+#if LLVM_ENABLE_DIA_SDK
+ return DIASession::createFromExe(Path, Session);
+#else
+ return make_error<PDBError>(pdb_error_code::dia_sdk_not_present);
+#endif
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp
index 0ebb70e010..886eac8eaf 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBContext.cpp
@@ -1,91 +1,91 @@
-//===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===/
-
-#include "llvm/DebugInfo/PDB/PDBContext.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
-#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
-#include "llvm/Object/COFF.h"
-
-using namespace llvm;
-using namespace llvm::object;
-using namespace llvm::pdb;
-
-PDBContext::PDBContext(const COFFObjectFile &Object,
- std::unique_ptr<IPDBSession> PDBSession)
- : DIContext(CK_PDB), Session(std::move(PDBSession)) {
- ErrorOr<uint64_t> ImageBase = Object.getImageBase();
- if (ImageBase)
- Session->setLoadAddress(ImageBase.get());
-}
-
-void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
-
-DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
- DILineInfoSpecifier Specifier) {
- DILineInfo Result;
- Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind);
-
- uint32_t Length = 1;
- std::unique_ptr<PDBSymbol> Symbol =
- 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())) {
- Length = Data->getLength();
- }
-
- // 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.Address, Length);
- if (!LineNumbers || LineNumbers->getChildCount() == 0)
- return Result;
-
- auto LineInfo = LineNumbers->getNext();
- assert(LineInfo);
- auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
-
- if (SourceFile &&
- Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
- Result.FileName = SourceFile->getFileName();
- Result.Column = LineInfo->getColumnNumber();
- Result.Line = LineInfo->getLineNumber();
- return Result;
-}
-
-DILineInfoTable
-PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
- uint64_t Size,
- DILineInfoSpecifier Specifier) {
- if (Size == 0)
- return DILineInfoTable();
-
- DILineInfoTable Table;
- auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size);
- if (!LineNumbers || LineNumbers->getChildCount() == 0)
- return Table;
-
- while (auto LineInfo = LineNumbers->getNext()) {
- DILineInfo LineEntry = getLineInfoForAddress(
- {LineInfo->getVirtualAddress(), Address.SectionIndex}, Specifier);
- Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
- }
- return Table;
-}
-
-DIInliningInfo
-PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
- DILineInfoSpecifier Specifier) {
- DIInliningInfo InlineInfo;
+//===-- PDBContext.cpp ------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===/
+
+#include "llvm/DebugInfo/PDB/PDBContext.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+#include "llvm/Object/COFF.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace llvm::pdb;
+
+PDBContext::PDBContext(const COFFObjectFile &Object,
+ std::unique_ptr<IPDBSession> PDBSession)
+ : DIContext(CK_PDB), Session(std::move(PDBSession)) {
+ ErrorOr<uint64_t> ImageBase = Object.getImageBase();
+ if (ImageBase)
+ Session->setLoadAddress(ImageBase.get());
+}
+
+void PDBContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){}
+
+DILineInfo PDBContext::getLineInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier) {
+ DILineInfo Result;
+ Result.FunctionName = getFunctionName(Address.Address, Specifier.FNKind);
+
+ uint32_t Length = 1;
+ std::unique_ptr<PDBSymbol> Symbol =
+ 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())) {
+ Length = Data->getLength();
+ }
+
+ // 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.Address, Length);
+ if (!LineNumbers || LineNumbers->getChildCount() == 0)
+ return Result;
+
+ auto LineInfo = LineNumbers->getNext();
+ assert(LineInfo);
+ auto SourceFile = Session->getSourceFileById(LineInfo->getSourceFileId());
+
+ if (SourceFile &&
+ Specifier.FLIKind != DILineInfoSpecifier::FileLineInfoKind::None)
+ Result.FileName = SourceFile->getFileName();
+ Result.Column = LineInfo->getColumnNumber();
+ Result.Line = LineInfo->getLineNumber();
+ return Result;
+}
+
+DILineInfoTable
+PDBContext::getLineInfoForAddressRange(object::SectionedAddress Address,
+ uint64_t Size,
+ DILineInfoSpecifier Specifier) {
+ if (Size == 0)
+ return DILineInfoTable();
+
+ DILineInfoTable Table;
+ auto LineNumbers = Session->findLineNumbersByAddress(Address.Address, Size);
+ if (!LineNumbers || LineNumbers->getChildCount() == 0)
+ return Table;
+
+ while (auto LineInfo = LineNumbers->getNext()) {
+ DILineInfo LineEntry = getLineInfoForAddress(
+ {LineInfo->getVirtualAddress(), Address.SectionIndex}, Specifier);
+ Table.push_back(std::make_pair(LineInfo->getVirtualAddress(), LineEntry));
+ }
+ return Table;
+}
+
+DIInliningInfo
+PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
+ DILineInfoSpecifier Specifier) {
+ DIInliningInfo InlineInfo;
DILineInfo CurrentLine = getLineInfoForAddress(Address, Specifier);
// Find the function at this address.
@@ -123,37 +123,37 @@ PDBContext::getInliningInfoForAddress(object::SectionedAddress Address,
}
InlineInfo.addFrame(CurrentLine);
- 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)
- return std::string();
-
- std::unique_ptr<PDBSymbol> FuncSymbol =
- Session->findSymbolByAddress(Address, PDB_SymType::Function);
- auto *Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get());
-
- if (NameKind == DINameKind::LinkageName) {
- // It is not possible to get the mangled linkage name through a
- // PDBSymbolFunc. For that we have to specifically request a
- // PDBSymbolPublicSymbol.
- auto PublicSym =
- Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
- if (auto *PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) {
- // If we also have a function symbol, prefer the use of public symbol name
- // only if it refers to the same address. The public symbol uses the
- // linkage name while the function does not.
- if (!Func || Func->getVirtualAddress() == PS->getVirtualAddress())
- return PS->getName();
- }
- }
-
- return Func ? Func->getName() : std::string();
-}
+ 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)
+ return std::string();
+
+ std::unique_ptr<PDBSymbol> FuncSymbol =
+ Session->findSymbolByAddress(Address, PDB_SymType::Function);
+ auto *Func = dyn_cast_or_null<PDBSymbolFunc>(FuncSymbol.get());
+
+ if (NameKind == DINameKind::LinkageName) {
+ // It is not possible to get the mangled linkage name through a
+ // PDBSymbolFunc. For that we have to specifically request a
+ // PDBSymbolPublicSymbol.
+ auto PublicSym =
+ Session->findSymbolByAddress(Address, PDB_SymType::PublicSymbol);
+ if (auto *PS = dyn_cast_or_null<PDBSymbolPublicSymbol>(PublicSym.get())) {
+ // If we also have a function symbol, prefer the use of public symbol name
+ // only if it refers to the same address. The public symbol uses the
+ // linkage name while the function does not.
+ if (!Func || Func->getVirtualAddress() == PS->getVirtualAddress())
+ return PS->getName();
+ }
+ }
+
+ return Func ? Func->getName() : std::string();
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp
index 25962e5152..a1bd7f6a29 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBExtras.cpp
@@ -1,125 +1,125 @@
-//===- PDBExtras.cpp - helper functions and classes for PDBs --------------===//
-//
-// 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/PDBExtras.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-#define CASE_OUTPUT_ENUM_CLASS_STR(Class, Value, Str, Stream) \
- case Class::Value: \
- Stream << Str; \
- break;
-
-#define CASE_OUTPUT_ENUM_CLASS_NAME(Class, Value, Stream) \
- CASE_OUTPUT_ENUM_CLASS_STR(Class, Value, #Value, Stream)
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const PDB_VariantType &Type) {
- switch (Type) {
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Bool, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Single, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Double, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int8, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int16, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int32, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int64, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt8, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt16, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt32, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt64, OS)
- default:
- OS << "Unknown";
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const PDB_BuiltinType &Type) {
- switch (Type) {
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, None, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Void, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, WCharT, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Int, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, UInt, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Float, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, BCD, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Bool, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Long, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, ULong, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Currency, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Date, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Variant, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Complex, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Bitfield, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, BSTR, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, HResult, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char16, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char32, OS)
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const PDB_CallingConv &Conv) {
- OS << "__";
- switch (Conv) {
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearC , "cdecl", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarC , "cdecl", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearPascal , "pascal", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarPascal , "pascal", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearFast , "fastcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarFast , "fastcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearStdCall, "stdcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarStdCall , "stdcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearSysCall, "syscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarSysCall , "syscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ThisCall , "thiscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, MipsCall , "mipscall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Generic , "genericcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, AlphaCall , "alphacall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, PpcCall , "ppccall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, SHCall , "superhcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ArmCall , "armcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, AM33Call , "am33call", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, TriCall , "tricall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, SH5Call , "sh5call", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, M32RCall , "m32rcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ClrCall , "clrcall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Inline , "inlinecall", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearVector , "vectorcall", OS)
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_DataKind &Data) {
- switch (Data) {
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Unknown, "unknown", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Local, "local", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, StaticLocal, "static local", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Param, "param", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, ObjectPtr, "this ptr", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, FileStatic, "static global", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Global, "global", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Member, "member", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, StaticMember, "static member", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Constant, "const", OS)
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const llvm::codeview::CPURegister &CpuReg) {
+//===- PDBExtras.cpp - helper functions and classes for PDBs --------------===//
+//
+// 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/PDBExtras.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+#define CASE_OUTPUT_ENUM_CLASS_STR(Class, Value, Str, Stream) \
+ case Class::Value: \
+ Stream << Str; \
+ break;
+
+#define CASE_OUTPUT_ENUM_CLASS_NAME(Class, Value, Stream) \
+ CASE_OUTPUT_ENUM_CLASS_STR(Class, Value, #Value, Stream)
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const PDB_VariantType &Type) {
+ switch (Type) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Bool, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Single, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Double, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int8, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int32, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, Int64, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt8, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt32, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_VariantType, UInt64, OS)
+ default:
+ OS << "Unknown";
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const PDB_BuiltinType &Type) {
+ switch (Type) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, None, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Void, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, WCharT, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Int, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, UInt, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Float, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, BCD, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Bool, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Long, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, ULong, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Currency, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Date, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Variant, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Complex, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Bitfield, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, BSTR, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, HResult, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_BuiltinType, Char32, OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const PDB_CallingConv &Conv) {
+ OS << "__";
+ switch (Conv) {
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearC , "cdecl", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarC , "cdecl", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearPascal , "pascal", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarPascal , "pascal", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearFast , "fastcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarFast , "fastcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearStdCall, "stdcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarStdCall , "stdcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearSysCall, "syscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, FarSysCall , "syscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ThisCall , "thiscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, MipsCall , "mipscall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Generic , "genericcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, AlphaCall , "alphacall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, PpcCall , "ppccall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, SHCall , "superhcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ArmCall , "armcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, AM33Call , "am33call", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, TriCall , "tricall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, SH5Call , "sh5call", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, M32RCall , "m32rcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, ClrCall , "clrcall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, Inline , "inlinecall", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_CallingConv, NearVector , "vectorcall", OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_DataKind &Data) {
+ switch (Data) {
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Unknown, "unknown", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Local, "local", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, StaticLocal, "static local", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Param, "param", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, ObjectPtr, "this ptr", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, FileStatic, "static global", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Global, "global", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Member, "member", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, StaticMember, "static member", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_DataKind, Constant, "const", OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const llvm::codeview::CPURegister &CpuReg) {
if (CpuReg.Cpu == llvm::codeview::CPUType::ARMNT) {
- switch (CpuReg.Reg) {
+ switch (CpuReg.Reg) {
#define CV_REGISTERS_ARM
#define CV_REGISTER(name, val) \
case codeview::RegisterId::name: \
@@ -134,274 +134,274 @@ raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
}
} else 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>(CpuReg.Reg);
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_LocType &Loc) {
- switch (Loc) {
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Static, "static", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, TLS, "tls", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, RegRel, "regrel", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, ThisRel, "thisrel", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Enregistered, "register", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, BitField, "bitfield", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Slot, "slot", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, IlRel, "IL rel", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, MetaData, "metadata", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Constant, "constant", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, RegRelAliasIndir,
- "regrelaliasindir", OS)
- default:
- OS << "Unknown";
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const codeview::ThunkOrdinal &Thunk) {
- switch (Thunk) {
- CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, BranchIsland, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, Pcode, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, Standard, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, ThisAdjustor, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, TrampIncremental, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, UnknownLoad, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, Vcall, OS)
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const PDB_Checksum &Checksum) {
- switch (Checksum) {
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, None, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, MD5, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, SHA1, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, SHA256, OS)
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_Lang &Lang) {
- switch (Lang) {
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, C, OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_Lang, Cpp, "C++", OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Fortran, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Masm, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Pascal, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Basic, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Cobol, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Link, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Cvtres, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Cvtpgd, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, CSharp, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, VB, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, ILAsm, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Java, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, JScript, OS)
- 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;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_SymType &Tag) {
- switch (Tag) {
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Exe, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Compiland, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CompilandDetails, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CompilandEnv, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Function, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Block, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Data, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Annotation, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Label, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, PublicSymbol, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, UDT, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Enum, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FunctionSig, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, PointerType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, ArrayType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, BuiltinType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Typedef, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, BaseClass, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Friend, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FunctionArg, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FuncDebugStart, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FuncDebugEnd, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, UsingNamespace, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, VTableShape, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, VTable, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Custom, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Thunk, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CustomType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, ManagedType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Dimension, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CallSite, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, InlineSite, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, BaseInterface, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, VectorType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, MatrixType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, HLSLType, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Caller, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Callee, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Export, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, HeapAllocationSite, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CoffGroup, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Inlinee, OS)
- default:
- OS << "Unknown SymTag " << uint32_t(Tag);
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const PDB_MemberAccess &Access) {
- switch (Access) {
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Public, "public", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Protected, "protected", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Private, "private", OS)
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UdtType &Type) {
- switch (Type) {
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Class, "class", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Struct, "struct", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Interface, "interface", OS)
- CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Union, "union", OS)
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const PDB_Machine &Machine) {
- switch (Machine) {
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Am33, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Amd64, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Arm, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, ArmNT, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Ebc, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, x86, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Ia64, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, M32R, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Mips16, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, MipsFpu, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, MipsFpu16, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, PowerPC, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, PowerPCFP, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, R4000, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH3, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH3DSP, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH4, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH5, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Thumb, OS)
- CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, WceMipsV2, OS)
- default:
- OS << "Unknown";
- }
- return OS;
-}
-
-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;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const Variant &Value) {
- switch (Value.Type) {
- case PDB_VariantType::Bool:
- OS << (Value.Value.Bool ? "true" : "false");
- break;
- case PDB_VariantType::Double:
- OS << Value.Value.Double;
- break;
- case PDB_VariantType::Int16:
- OS << Value.Value.Int16;
- break;
- case PDB_VariantType::Int32:
- OS << Value.Value.Int32;
- break;
- case PDB_VariantType::Int64:
- OS << Value.Value.Int64;
- break;
- case PDB_VariantType::Int8:
- OS << static_cast<int>(Value.Value.Int8);
- break;
- case PDB_VariantType::Single:
- OS << Value.Value.Single;
- break;
- case PDB_VariantType::UInt16:
- OS << Value.Value.UInt16;
- break;
- case PDB_VariantType::UInt32:
- OS << Value.Value.UInt32;
- break;
- case PDB_VariantType::UInt64:
- OS << Value.Value.UInt64;
- break;
- case PDB_VariantType::UInt8:
- OS << static_cast<unsigned>(Value.Value.UInt8);
- break;
- case PDB_VariantType::String:
- OS << Value.Value.String;
- break;
- default:
- OS << Value.Type;
- }
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
- const VersionInfo &Version) {
- OS << Version.Major << "." << Version.Minor << "." << Version.Build;
- return OS;
-}
-
-raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const TagStats &Stats) {
- for (auto Tag : Stats) {
- OS << Tag.first << ":" << Tag.second << " ";
- }
- return OS;
-}
+#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>(CpuReg.Reg);
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_LocType &Loc) {
+ switch (Loc) {
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Static, "static", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, TLS, "tls", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, RegRel, "regrel", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, ThisRel, "thisrel", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Enregistered, "register", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, BitField, "bitfield", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Slot, "slot", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, IlRel, "IL rel", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, MetaData, "metadata", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, Constant, "constant", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_LocType, RegRelAliasIndir,
+ "regrelaliasindir", OS)
+ default:
+ OS << "Unknown";
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const codeview::ThunkOrdinal &Thunk) {
+ switch (Thunk) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, BranchIsland, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, Pcode, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, Standard, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, ThisAdjustor, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, TrampIncremental, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, UnknownLoad, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(codeview::ThunkOrdinal, Vcall, OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const PDB_Checksum &Checksum) {
+ switch (Checksum) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, None, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, MD5, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, SHA1, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Checksum, SHA256, OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_Lang &Lang) {
+ switch (Lang) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, C, OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_Lang, Cpp, "C++", OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Fortran, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Masm, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Pascal, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Basic, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Cobol, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Link, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Cvtres, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Cvtpgd, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, CSharp, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, VB, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, ILAsm, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, Java, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Lang, JScript, OS)
+ 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;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_SymType &Tag) {
+ switch (Tag) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Exe, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Compiland, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CompilandDetails, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CompilandEnv, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Function, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Block, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Data, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Annotation, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Label, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, PublicSymbol, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, UDT, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Enum, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FunctionSig, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, PointerType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, ArrayType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, BuiltinType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Typedef, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, BaseClass, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Friend, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FunctionArg, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FuncDebugStart, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, FuncDebugEnd, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, UsingNamespace, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, VTableShape, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, VTable, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Custom, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Thunk, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CustomType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, ManagedType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Dimension, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CallSite, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, InlineSite, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, BaseInterface, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, VectorType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, MatrixType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, HLSLType, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Caller, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Callee, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Export, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, HeapAllocationSite, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, CoffGroup, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SymType, Inlinee, OS)
+ default:
+ OS << "Unknown SymTag " << uint32_t(Tag);
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const PDB_MemberAccess &Access) {
+ switch (Access) {
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Public, "public", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Protected, "protected", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_MemberAccess, Private, "private", OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const PDB_UdtType &Type) {
+ switch (Type) {
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Class, "class", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Struct, "struct", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Interface, "interface", OS)
+ CASE_OUTPUT_ENUM_CLASS_STR(PDB_UdtType, Union, "union", OS)
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const PDB_Machine &Machine) {
+ switch (Machine) {
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Am33, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Amd64, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Arm, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, ArmNT, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Ebc, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, x86, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Ia64, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, M32R, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Mips16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, MipsFpu, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, MipsFpu16, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, PowerPC, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, PowerPCFP, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, R4000, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH3, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH3DSP, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH4, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, SH5, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, Thumb, OS)
+ CASE_OUTPUT_ENUM_CLASS_NAME(PDB_Machine, WceMipsV2, OS)
+ default:
+ OS << "Unknown";
+ }
+ return OS;
+}
+
+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;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const Variant &Value) {
+ switch (Value.Type) {
+ case PDB_VariantType::Bool:
+ OS << (Value.Value.Bool ? "true" : "false");
+ break;
+ case PDB_VariantType::Double:
+ OS << Value.Value.Double;
+ break;
+ case PDB_VariantType::Int16:
+ OS << Value.Value.Int16;
+ break;
+ case PDB_VariantType::Int32:
+ OS << Value.Value.Int32;
+ break;
+ case PDB_VariantType::Int64:
+ OS << Value.Value.Int64;
+ break;
+ case PDB_VariantType::Int8:
+ OS << static_cast<int>(Value.Value.Int8);
+ break;
+ case PDB_VariantType::Single:
+ OS << Value.Value.Single;
+ break;
+ case PDB_VariantType::UInt16:
+ OS << Value.Value.UInt16;
+ break;
+ case PDB_VariantType::UInt32:
+ OS << Value.Value.UInt32;
+ break;
+ case PDB_VariantType::UInt64:
+ OS << Value.Value.UInt64;
+ break;
+ case PDB_VariantType::UInt8:
+ OS << static_cast<unsigned>(Value.Value.UInt8);
+ break;
+ case PDB_VariantType::String:
+ OS << Value.Value.String;
+ break;
+ default:
+ OS << Value.Type;
+ }
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
+ const VersionInfo &Version) {
+ OS << Version.Major << "." << Version.Minor << "." << Version.Build;
+ return OS;
+}
+
+raw_ostream &llvm::pdb::operator<<(raw_ostream &OS, const TagStats &Stats) {
+ for (auto Tag : Stats) {
+ OS << Tag.first << ":" << Tag.second << " ";
+ }
+ return OS;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
index d51091d809..76324b3577 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBInterfaceAnchors.cpp
@@ -1,39 +1,39 @@
//===- PDBInterfaceAnchors.h - defines class anchor functions ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-// Class anchors are necessary per the LLVM Coding style guide, to ensure that
-// the vtable is only generated in this object file, and not in every object
+//
+// 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
+// the vtable is only generated in this object file, and not in every object
// file that includes the corresponding header.
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
-#include "llvm/DebugInfo/PDB/IPDBFrameData.h"
-#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
-#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
-#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
-#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/IPDBTable.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-IPDBSession::~IPDBSession() = default;
-
-IPDBDataStream::~IPDBDataStream() = default;
-
-IPDBRawSymbol::~IPDBRawSymbol() = default;
-
-IPDBLineNumber::~IPDBLineNumber() = default;
-
-IPDBTable::~IPDBTable() = default;
-
-IPDBInjectedSource::~IPDBInjectedSource() = default;
-
-IPDBSectionContrib::~IPDBSectionContrib() = default;
-
-IPDBFrameData::~IPDBFrameData() = default;
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/IPDBDataStream.h"
+#include "llvm/DebugInfo/PDB/IPDBFrameData.h"
+#include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
+#include "llvm/DebugInfo/PDB/IPDBLineNumber.h"
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/IPDBTable.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+IPDBSession::~IPDBSession() = default;
+
+IPDBDataStream::~IPDBDataStream() = default;
+
+IPDBRawSymbol::~IPDBRawSymbol() = default;
+
+IPDBLineNumber::~IPDBLineNumber() = default;
+
+IPDBTable::~IPDBTable() = default;
+
+IPDBInjectedSource::~IPDBInjectedSource() = default;
+
+IPDBSectionContrib::~IPDBSectionContrib() = default;
+
+IPDBFrameData::~IPDBFrameData() = default;
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymDumper.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymDumper.cpp
index 0956a32f4a..df87f64134 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymDumper.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymDumper.cpp
@@ -1,146 +1,146 @@
-//===- PDBSymDumper.cpp - ---------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/Support/ErrorHandling.h"
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-#define PDB_SYMDUMP_UNREACHABLE(Type) \
- if (RequireImpl) \
- llvm_unreachable("Attempt to dump " #Type " with no dump implementation");
-
-PDBSymDumper::PDBSymDumper(bool ShouldRequireImpl)
- : RequireImpl(ShouldRequireImpl) {}
-
-PDBSymDumper::~PDBSymDumper() = default;
-
-void PDBSymDumper::dump(const PDBSymbolAnnotation &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolAnnotation)
-}
-
-void PDBSymDumper::dump(const PDBSymbolBlock &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolBlock)
-}
-
-void PDBSymDumper::dump(const PDBSymbolCompiland &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolCompiland)
-}
-
-void PDBSymDumper::dump(const PDBSymbolCompilandDetails &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolCompilandDetails)
-}
-
-void PDBSymDumper::dump(const PDBSymbolCompilandEnv &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolCompilandEnv)
-}
-
-void PDBSymDumper::dump(const PDBSymbolCustom &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolCustom)
-}
-
-void PDBSymDumper::dump(const PDBSymbolData &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolData)
-}
-
-void PDBSymDumper::dump(const PDBSymbolExe &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolExe)
-}
-
-void PDBSymDumper::dump(const PDBSymbolFunc &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolFunc)
-}
-
-void PDBSymDumper::dump(const PDBSymbolFuncDebugEnd &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolFuncDebugEnd)
-}
-
-void PDBSymDumper::dump(const PDBSymbolFuncDebugStart &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolFuncDebugStart)
-}
-
-void PDBSymDumper::dump(const PDBSymbolLabel &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolLabel)
-}
-
-void PDBSymDumper::dump(const PDBSymbolPublicSymbol &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolPublicSymbol)
-}
-
-void PDBSymDumper::dump(const PDBSymbolThunk &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolThunk)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeArray &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeArray)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeBaseClass)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeBuiltin)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeCustom &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeCustom)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeDimension &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeDimension)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeEnum &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeEnum)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeFriend &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeFriend)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeFunctionArg)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeFunctionSig)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeManaged &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeManaged)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypePointer &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypePointer)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeTypedef)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeUDT &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeUDT)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeVTable &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeVTable)
-}
-
-void PDBSymDumper::dump(const PDBSymbolTypeVTableShape &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeVTableShape)
-}
-
-void PDBSymDumper::dump(const PDBSymbolUnknown &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolUnknown)
-}
-
-void PDBSymDumper::dump(const PDBSymbolUsingNamespace &Symbol) {
- PDB_SYMDUMP_UNREACHABLE(PDBSymbolUsingNamespace)
-}
+//===- PDBSymDumper.cpp - ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+#define PDB_SYMDUMP_UNREACHABLE(Type) \
+ if (RequireImpl) \
+ llvm_unreachable("Attempt to dump " #Type " with no dump implementation");
+
+PDBSymDumper::PDBSymDumper(bool ShouldRequireImpl)
+ : RequireImpl(ShouldRequireImpl) {}
+
+PDBSymDumper::~PDBSymDumper() = default;
+
+void PDBSymDumper::dump(const PDBSymbolAnnotation &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolAnnotation)
+}
+
+void PDBSymDumper::dump(const PDBSymbolBlock &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolBlock)
+}
+
+void PDBSymDumper::dump(const PDBSymbolCompiland &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolCompiland)
+}
+
+void PDBSymDumper::dump(const PDBSymbolCompilandDetails &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolCompilandDetails)
+}
+
+void PDBSymDumper::dump(const PDBSymbolCompilandEnv &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolCompilandEnv)
+}
+
+void PDBSymDumper::dump(const PDBSymbolCustom &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolCustom)
+}
+
+void PDBSymDumper::dump(const PDBSymbolData &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolData)
+}
+
+void PDBSymDumper::dump(const PDBSymbolExe &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolExe)
+}
+
+void PDBSymDumper::dump(const PDBSymbolFunc &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolFunc)
+}
+
+void PDBSymDumper::dump(const PDBSymbolFuncDebugEnd &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolFuncDebugEnd)
+}
+
+void PDBSymDumper::dump(const PDBSymbolFuncDebugStart &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolFuncDebugStart)
+}
+
+void PDBSymDumper::dump(const PDBSymbolLabel &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolLabel)
+}
+
+void PDBSymDumper::dump(const PDBSymbolPublicSymbol &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolPublicSymbol)
+}
+
+void PDBSymDumper::dump(const PDBSymbolThunk &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolThunk)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeArray &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeArray)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeBaseClass &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeBaseClass)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeBuiltin &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeBuiltin)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeCustom &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeCustom)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeDimension &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeDimension)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeEnum &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeEnum)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeFriend &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeFriend)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeFunctionArg &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeFunctionArg)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeFunctionSig &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeFunctionSig)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeManaged &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeManaged)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypePointer &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypePointer)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeTypedef &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeTypedef)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeUDT &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeUDT)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeVTable &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeVTable)
+}
+
+void PDBSymDumper::dump(const PDBSymbolTypeVTableShape &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolTypeVTableShape)
+}
+
+void PDBSymDumper::dump(const PDBSymbolUnknown &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolUnknown)
+}
+
+void PDBSymDumper::dump(const PDBSymbolUsingNamespace &Symbol) {
+ PDB_SYMDUMP_UNREACHABLE(PDBSymbolUsingNamespace)
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp
index d6bc7ee9c9..77e3c284ef 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbol.cpp
@@ -1,175 +1,175 @@
-//===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDBExtras.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
-#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include <algorithm>
-#include <memory>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-PDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {}
-
-PDBSymbol::PDBSymbol(PDBSymbol &&Other)
- : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {}
-
-PDBSymbol::~PDBSymbol() = default;
-
-#define FACTORY_SYMTAG_CASE(Tag, Type) \
- case PDB_SymType::Tag: \
- return std::unique_ptr<PDBSymbol>(new Type(PDBSession));
-
-std::unique_ptr<PDBSymbol>
-PDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) {
- switch (Tag) {
- FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe)
- FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland)
- FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails)
- FACTORY_SYMTAG_CASE(CompilandEnv, PDBSymbolCompilandEnv)
- FACTORY_SYMTAG_CASE(Function, PDBSymbolFunc)
- FACTORY_SYMTAG_CASE(Block, PDBSymbolBlock)
- FACTORY_SYMTAG_CASE(Data, PDBSymbolData)
- FACTORY_SYMTAG_CASE(Annotation, PDBSymbolAnnotation)
- FACTORY_SYMTAG_CASE(Label, PDBSymbolLabel)
- FACTORY_SYMTAG_CASE(PublicSymbol, PDBSymbolPublicSymbol)
- FACTORY_SYMTAG_CASE(UDT, PDBSymbolTypeUDT)
- FACTORY_SYMTAG_CASE(Enum, PDBSymbolTypeEnum)
- FACTORY_SYMTAG_CASE(FunctionSig, PDBSymbolTypeFunctionSig)
- FACTORY_SYMTAG_CASE(PointerType, PDBSymbolTypePointer)
- FACTORY_SYMTAG_CASE(ArrayType, PDBSymbolTypeArray)
- FACTORY_SYMTAG_CASE(BuiltinType, PDBSymbolTypeBuiltin)
- FACTORY_SYMTAG_CASE(Typedef, PDBSymbolTypeTypedef)
- FACTORY_SYMTAG_CASE(BaseClass, PDBSymbolTypeBaseClass)
- FACTORY_SYMTAG_CASE(Friend, PDBSymbolTypeFriend)
- FACTORY_SYMTAG_CASE(FunctionArg, PDBSymbolTypeFunctionArg)
- FACTORY_SYMTAG_CASE(FuncDebugStart, PDBSymbolFuncDebugStart)
- FACTORY_SYMTAG_CASE(FuncDebugEnd, PDBSymbolFuncDebugEnd)
- FACTORY_SYMTAG_CASE(UsingNamespace, PDBSymbolUsingNamespace)
- FACTORY_SYMTAG_CASE(VTableShape, PDBSymbolTypeVTableShape)
- FACTORY_SYMTAG_CASE(VTable, PDBSymbolTypeVTable)
- FACTORY_SYMTAG_CASE(Custom, PDBSymbolCustom)
- FACTORY_SYMTAG_CASE(Thunk, PDBSymbolThunk)
- FACTORY_SYMTAG_CASE(CustomType, PDBSymbolTypeCustom)
- FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged)
- FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension)
- default:
- return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession));
- }
-}
-
-std::unique_ptr<PDBSymbol>
-PDBSymbol::create(const IPDBSession &PDBSession,
- std::unique_ptr<IPDBRawSymbol> RawSymbol) {
- auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag());
- SymbolPtr->RawSymbol = RawSymbol.get();
- SymbolPtr->OwnedRawSymbol = std::move(RawSymbol);
- return SymbolPtr;
-}
-
-std::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession,
- IPDBRawSymbol &RawSymbol) {
- auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag());
- SymbolPtr->RawSymbol = &RawSymbol;
- return SymbolPtr;
-}
-
-void PDBSymbol::defaultDump(raw_ostream &OS, int Indent,
- PdbSymbolIdField ShowFlags,
- PdbSymbolIdField RecurseFlags) const {
- RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags);
-}
-
-void PDBSymbol::dumpProperties() const {
- outs() << "\n";
- defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None);
- outs().flush();
-}
-
-void PDBSymbol::dumpChildStats() const {
- TagStats Stats;
- getChildStats(Stats);
- outs() << "\n";
- for (auto &Stat : Stats) {
- outs() << Stat.first << ": " << Stat.second << "\n";
- }
- outs().flush();
-}
-
-PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }
-uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }
-
-std::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const {
- return findAllChildren(PDB_SymType::None);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-PDBSymbol::findAllChildren(PDB_SymType Type) const {
- return RawSymbol->findChildren(Type);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-PDBSymbol::findChildren(PDB_SymType Type, StringRef Name,
- PDB_NameSearchFlags Flags) const {
- return RawSymbol->findChildren(Type, Name, Flags);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-PDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
- PDB_NameSearchFlags Flags, uint32_t RVA) const {
- return RawSymbol->findChildrenByRVA(Type, Name, Flags, RVA);
-}
-
-std::unique_ptr<IPDBEnumSymbols>
+//===- PDBSymbol.cpp - base class for user-facing symbol types --*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBExtras.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include <algorithm>
+#include <memory>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+PDBSymbol::PDBSymbol(const IPDBSession &PDBSession) : Session(PDBSession) {}
+
+PDBSymbol::PDBSymbol(PDBSymbol &&Other)
+ : Session(Other.Session), RawSymbol(std::move(Other.RawSymbol)) {}
+
+PDBSymbol::~PDBSymbol() = default;
+
+#define FACTORY_SYMTAG_CASE(Tag, Type) \
+ case PDB_SymType::Tag: \
+ return std::unique_ptr<PDBSymbol>(new Type(PDBSession));
+
+std::unique_ptr<PDBSymbol>
+PDBSymbol::createSymbol(const IPDBSession &PDBSession, PDB_SymType Tag) {
+ switch (Tag) {
+ FACTORY_SYMTAG_CASE(Exe, PDBSymbolExe)
+ FACTORY_SYMTAG_CASE(Compiland, PDBSymbolCompiland)
+ FACTORY_SYMTAG_CASE(CompilandDetails, PDBSymbolCompilandDetails)
+ FACTORY_SYMTAG_CASE(CompilandEnv, PDBSymbolCompilandEnv)
+ FACTORY_SYMTAG_CASE(Function, PDBSymbolFunc)
+ FACTORY_SYMTAG_CASE(Block, PDBSymbolBlock)
+ FACTORY_SYMTAG_CASE(Data, PDBSymbolData)
+ FACTORY_SYMTAG_CASE(Annotation, PDBSymbolAnnotation)
+ FACTORY_SYMTAG_CASE(Label, PDBSymbolLabel)
+ FACTORY_SYMTAG_CASE(PublicSymbol, PDBSymbolPublicSymbol)
+ FACTORY_SYMTAG_CASE(UDT, PDBSymbolTypeUDT)
+ FACTORY_SYMTAG_CASE(Enum, PDBSymbolTypeEnum)
+ FACTORY_SYMTAG_CASE(FunctionSig, PDBSymbolTypeFunctionSig)
+ FACTORY_SYMTAG_CASE(PointerType, PDBSymbolTypePointer)
+ FACTORY_SYMTAG_CASE(ArrayType, PDBSymbolTypeArray)
+ FACTORY_SYMTAG_CASE(BuiltinType, PDBSymbolTypeBuiltin)
+ FACTORY_SYMTAG_CASE(Typedef, PDBSymbolTypeTypedef)
+ FACTORY_SYMTAG_CASE(BaseClass, PDBSymbolTypeBaseClass)
+ FACTORY_SYMTAG_CASE(Friend, PDBSymbolTypeFriend)
+ FACTORY_SYMTAG_CASE(FunctionArg, PDBSymbolTypeFunctionArg)
+ FACTORY_SYMTAG_CASE(FuncDebugStart, PDBSymbolFuncDebugStart)
+ FACTORY_SYMTAG_CASE(FuncDebugEnd, PDBSymbolFuncDebugEnd)
+ FACTORY_SYMTAG_CASE(UsingNamespace, PDBSymbolUsingNamespace)
+ FACTORY_SYMTAG_CASE(VTableShape, PDBSymbolTypeVTableShape)
+ FACTORY_SYMTAG_CASE(VTable, PDBSymbolTypeVTable)
+ FACTORY_SYMTAG_CASE(Custom, PDBSymbolCustom)
+ FACTORY_SYMTAG_CASE(Thunk, PDBSymbolThunk)
+ FACTORY_SYMTAG_CASE(CustomType, PDBSymbolTypeCustom)
+ FACTORY_SYMTAG_CASE(ManagedType, PDBSymbolTypeManaged)
+ FACTORY_SYMTAG_CASE(Dimension, PDBSymbolTypeDimension)
+ default:
+ return std::unique_ptr<PDBSymbol>(new PDBSymbolUnknown(PDBSession));
+ }
+}
+
+std::unique_ptr<PDBSymbol>
+PDBSymbol::create(const IPDBSession &PDBSession,
+ std::unique_ptr<IPDBRawSymbol> RawSymbol) {
+ auto SymbolPtr = createSymbol(PDBSession, RawSymbol->getSymTag());
+ SymbolPtr->RawSymbol = RawSymbol.get();
+ SymbolPtr->OwnedRawSymbol = std::move(RawSymbol);
+ return SymbolPtr;
+}
+
+std::unique_ptr<PDBSymbol> PDBSymbol::create(const IPDBSession &PDBSession,
+ IPDBRawSymbol &RawSymbol) {
+ auto SymbolPtr = createSymbol(PDBSession, RawSymbol.getSymTag());
+ SymbolPtr->RawSymbol = &RawSymbol;
+ return SymbolPtr;
+}
+
+void PDBSymbol::defaultDump(raw_ostream &OS, int Indent,
+ PdbSymbolIdField ShowFlags,
+ PdbSymbolIdField RecurseFlags) const {
+ RawSymbol->dump(OS, Indent, ShowFlags, RecurseFlags);
+}
+
+void PDBSymbol::dumpProperties() const {
+ outs() << "\n";
+ defaultDump(outs(), 0, PdbSymbolIdField::All, PdbSymbolIdField::None);
+ outs().flush();
+}
+
+void PDBSymbol::dumpChildStats() const {
+ TagStats Stats;
+ getChildStats(Stats);
+ outs() << "\n";
+ for (auto &Stat : Stats) {
+ outs() << Stat.first << ": " << Stat.second << "\n";
+ }
+ outs().flush();
+}
+
+PDB_SymType PDBSymbol::getSymTag() const { return RawSymbol->getSymTag(); }
+uint32_t PDBSymbol::getSymIndexId() const { return RawSymbol->getSymIndexId(); }
+
+std::unique_ptr<IPDBEnumSymbols> PDBSymbol::findAllChildren() const {
+ return findAllChildren(PDB_SymType::None);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+PDBSymbol::findAllChildren(PDB_SymType Type) const {
+ return RawSymbol->findChildren(Type);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+PDBSymbol::findChildren(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags) const {
+ return RawSymbol->findChildren(Type, Name, Flags);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+PDBSymbol::findChildrenByRVA(PDB_SymType Type, StringRef Name,
+ PDB_NameSearchFlags Flags, uint32_t RVA) const {
+ return RawSymbol->findChildrenByRVA(Type, Name, Flags, RVA);
+}
+
+std::unique_ptr<IPDBEnumSymbols>
PDBSymbol::findInlineFramesByVA(uint64_t VA) const {
return RawSymbol->findInlineFramesByVA(VA);
}
std::unique_ptr<IPDBEnumSymbols>
-PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
- return RawSymbol->findInlineFramesByRVA(RVA);
-}
-
+PDBSymbol::findInlineFramesByRVA(uint32_t RVA) const {
+ return RawSymbol->findInlineFramesByRVA(RVA);
+}
+
std::unique_ptr<IPDBEnumLineNumbers>
PDBSymbol::findInlineeLinesByVA(uint64_t VA, uint32_t Length) const {
return RawSymbol->findInlineeLinesByVA(VA, Length);
@@ -182,50 +182,50 @@ PDBSymbol::findInlineeLinesByRVA(uint32_t RVA, uint32_t Length) const {
std::string PDBSymbol::getName() const { return RawSymbol->getName(); }
-std::unique_ptr<IPDBEnumSymbols>
-PDBSymbol::getChildStats(TagStats &Stats) const {
- std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
- if (!Result)
- return nullptr;
- Stats.clear();
- while (auto Child = Result->getNext()) {
- ++Stats[Child->getSymTag()];
- }
- Result->reset();
- return Result;
-}
-
-std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {
- return Session.getSymbolById(Id);
-}
-
-void llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name,
- SymIndexId Value, int Indent,
- const IPDBSession &Session,
- PdbSymbolIdField FieldId,
- PdbSymbolIdField ShowFlags,
- PdbSymbolIdField RecurseFlags) {
- if ((FieldId & ShowFlags) == PdbSymbolIdField::None)
- return;
-
- OS << "\n";
- OS.indent(Indent);
- OS << Name << ": " << Value;
- // Don't recurse unless the user requested it.
- if ((FieldId & RecurseFlags) == PdbSymbolIdField::None)
- return;
- // And obviously don't recurse on the symbol itself.
- if (FieldId == PdbSymbolIdField::SymIndexId)
- return;
-
- auto Child = Session.getSymbolById(Value);
-
- // It could have been a placeholder symbol for a type we don't yet support,
- // so just exit in that case.
- if (!Child)
- return;
-
- // Don't recurse more than once, so pass PdbSymbolIdField::None) for the
- // recurse flags.
- Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None);
-}
+std::unique_ptr<IPDBEnumSymbols>
+PDBSymbol::getChildStats(TagStats &Stats) const {
+ std::unique_ptr<IPDBEnumSymbols> Result(findAllChildren());
+ if (!Result)
+ return nullptr;
+ Stats.clear();
+ while (auto Child = Result->getNext()) {
+ ++Stats[Child->getSymTag()];
+ }
+ Result->reset();
+ return Result;
+}
+
+std::unique_ptr<PDBSymbol> PDBSymbol::getSymbolByIdHelper(uint32_t Id) const {
+ return Session.getSymbolById(Id);
+}
+
+void llvm::pdb::dumpSymbolIdField(raw_ostream &OS, StringRef Name,
+ SymIndexId Value, int Indent,
+ const IPDBSession &Session,
+ PdbSymbolIdField FieldId,
+ PdbSymbolIdField ShowFlags,
+ PdbSymbolIdField RecurseFlags) {
+ if ((FieldId & ShowFlags) == PdbSymbolIdField::None)
+ return;
+
+ OS << "\n";
+ OS.indent(Indent);
+ OS << Name << ": " << Value;
+ // Don't recurse unless the user requested it.
+ if ((FieldId & RecurseFlags) == PdbSymbolIdField::None)
+ return;
+ // And obviously don't recurse on the symbol itself.
+ if (FieldId == PdbSymbolIdField::SymIndexId)
+ return;
+
+ auto Child = Session.getSymbolById(Value);
+
+ // It could have been a placeholder symbol for a type we don't yet support,
+ // so just exit in that case.
+ if (!Child)
+ return;
+
+ // Don't recurse more than once, so pass PdbSymbolIdField::None) for the
+ // recurse flags.
+ Child->defaultDump(OS, Indent + 2, ShowFlags, PdbSymbolIdField::None);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
index 0fa83efb7a..a9df1b387e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolAnnotation.cpp
@@ -1,20 +1,20 @@
-//===- PDBSymbolAnnotation.cpp - --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolAnnotation::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolAnnotation.cpp - --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolAnnotation.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolAnnotation::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolBlock.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
index 9452282a88..97eb8970a2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolBlock.cpp
@@ -1,19 +1,19 @@
-//===- PDBSymbolBlock.cpp - -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolBlock::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+//===- PDBSymbolBlock.cpp - -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolBlock.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolBlock::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
index 9b28835463..db2fc404ac 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompiland.cpp
@@ -1,109 +1,109 @@
-//===- PDBSymbolCompiland.cpp - compiland details ---------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/Support/Path.h"
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
-
-std::string PDBSymbolCompiland::getSourceFileName() const {
- return sys::path::filename(getSourceFileFullPath()).str();
-}
-
-std::string PDBSymbolCompiland::getSourceFileFullPath() const {
- std::string SourceFileFullPath;
-
- // RecordedResult could be the basename, relative path or full path of the
- // source file. Usually it is retrieved and recorded from the command that
- // compiles this compiland.
- //
- // cmd FileName -> RecordedResult = .\\FileName
- // cmd (Path)\\FileName -> RecordedResult = (Path)\\FileName
- //
- std::string RecordedResult = RawSymbol->getSourceFileName();
-
- if (RecordedResult.empty()) {
- if (auto Envs = findAllChildren<PDBSymbolCompilandEnv>()) {
- std::string EnvWorkingDir, EnvSrc;
-
- while (auto Env = Envs->getNext()) {
- std::string Var = Env->getName();
- if (Var == "cwd") {
- EnvWorkingDir = Env->getValue();
- continue;
- }
- if (Var == "src") {
- EnvSrc = Env->getValue();
- if (sys::path::is_absolute(EnvSrc))
- return EnvSrc;
- RecordedResult = EnvSrc;
- continue;
- }
- }
- if (!EnvWorkingDir.empty() && !EnvSrc.empty()) {
- auto Len = EnvWorkingDir.length();
- if (EnvWorkingDir[Len - 1] != '/' && EnvWorkingDir[Len - 1] != '\\') {
- std::string Path = EnvWorkingDir + "\\" + EnvSrc;
- std::replace(Path.begin(), Path.end(), '/', '\\');
- // We will return it as full path if we can't find a better one.
- if (sys::path::is_absolute(Path))
- SourceFileFullPath = Path;
- }
- }
- }
- }
-
- if (!RecordedResult.empty()) {
- if (sys::path::is_absolute(RecordedResult))
- return RecordedResult;
-
- // This searches name that has same basename as the one in RecordedResult.
- auto OneSrcFile = Session.findOneSourceFile(
- this, RecordedResult, PDB_NameSearchFlags::NS_CaseInsensitive);
- if (OneSrcFile)
- return OneSrcFile->getFileName();
- }
-
- // At this point, we have to walk through all source files of this compiland,
- // and determine the right source file if any that is used to generate this
- // compiland based on language indicated in compilanddetails language field.
- auto Details = findOneChild<PDBSymbolCompilandDetails>();
- PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp;
- auto SrcFiles = Session.getSourceFilesForCompiland(*this);
- if (SrcFiles) {
- 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", 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();
- }
- }
-
- return SourceFileFullPath;
-}
+//===- PDBSymbolCompiland.cpp - compiland details ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymbolCompiland.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Path.h"
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolCompiland::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
+
+std::string PDBSymbolCompiland::getSourceFileName() const {
+ return sys::path::filename(getSourceFileFullPath()).str();
+}
+
+std::string PDBSymbolCompiland::getSourceFileFullPath() const {
+ std::string SourceFileFullPath;
+
+ // RecordedResult could be the basename, relative path or full path of the
+ // source file. Usually it is retrieved and recorded from the command that
+ // compiles this compiland.
+ //
+ // cmd FileName -> RecordedResult = .\\FileName
+ // cmd (Path)\\FileName -> RecordedResult = (Path)\\FileName
+ //
+ std::string RecordedResult = RawSymbol->getSourceFileName();
+
+ if (RecordedResult.empty()) {
+ if (auto Envs = findAllChildren<PDBSymbolCompilandEnv>()) {
+ std::string EnvWorkingDir, EnvSrc;
+
+ while (auto Env = Envs->getNext()) {
+ std::string Var = Env->getName();
+ if (Var == "cwd") {
+ EnvWorkingDir = Env->getValue();
+ continue;
+ }
+ if (Var == "src") {
+ EnvSrc = Env->getValue();
+ if (sys::path::is_absolute(EnvSrc))
+ return EnvSrc;
+ RecordedResult = EnvSrc;
+ continue;
+ }
+ }
+ if (!EnvWorkingDir.empty() && !EnvSrc.empty()) {
+ auto Len = EnvWorkingDir.length();
+ if (EnvWorkingDir[Len - 1] != '/' && EnvWorkingDir[Len - 1] != '\\') {
+ std::string Path = EnvWorkingDir + "\\" + EnvSrc;
+ std::replace(Path.begin(), Path.end(), '/', '\\');
+ // We will return it as full path if we can't find a better one.
+ if (sys::path::is_absolute(Path))
+ SourceFileFullPath = Path;
+ }
+ }
+ }
+ }
+
+ if (!RecordedResult.empty()) {
+ if (sys::path::is_absolute(RecordedResult))
+ return RecordedResult;
+
+ // This searches name that has same basename as the one in RecordedResult.
+ auto OneSrcFile = Session.findOneSourceFile(
+ this, RecordedResult, PDB_NameSearchFlags::NS_CaseInsensitive);
+ if (OneSrcFile)
+ return OneSrcFile->getFileName();
+ }
+
+ // At this point, we have to walk through all source files of this compiland,
+ // and determine the right source file if any that is used to generate this
+ // compiland based on language indicated in compilanddetails language field.
+ auto Details = findOneChild<PDBSymbolCompilandDetails>();
+ PDB_Lang Lang = Details ? Details->getLanguage() : PDB_Lang::Cpp;
+ auto SrcFiles = Session.getSourceFilesForCompiland(*this);
+ if (SrcFiles) {
+ 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", 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();
+ }
+ }
+
+ return SourceFileFullPath;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
index 0d86dfe1e6..6fc1dbaece 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandDetails.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolCompilandDetails.cpp - compiland details --------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolCompilandDetails::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolCompilandDetails.cpp - compiland details --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandDetails.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolCompilandDetails::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
index 61f119405f..bfb0df0cd9 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCompilandEnv.cpp
@@ -1,29 +1,29 @@
-//===- PDBSymbolCompilandEnv.cpp - compiland env variables ------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
-
-#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-std::string PDBSymbolCompilandEnv::getValue() const {
- Variant Value = RawSymbol->getValue();
- if (Value.Type != PDB_VariantType::String)
- return std::string();
- return std::string(Value.Value.String);
-}
-
-void PDBSymbolCompilandEnv::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolCompilandEnv.cpp - compiland env variables ------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolCompilandEnv.h"
+
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+std::string PDBSymbolCompilandEnv::getValue() const {
+ Variant Value = RawSymbol->getValue();
+ if (Value.Type != PDB_VariantType::String)
+ return std::string();
+ return std::string(Value.Value.String);
+}
+
+void PDBSymbolCompilandEnv::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCustom.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
index 6c9a4aa76c..ccedff48a4 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolCustom.cpp
@@ -1,24 +1,24 @@
-//===- PDBSymbolCustom.cpp - compiler-specific types ------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
-
-#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolCustom::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) {
- RawSymbol->getDataBytes(bytes);
-}
-
-void PDBSymbolCustom::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+//===- PDBSymbolCustom.cpp - compiler-specific types ------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolCustom.h"
+
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolCustom::getDataBytes(llvm::SmallVector<uint8_t, 32> &bytes) {
+ RawSymbol->getDataBytes(bytes);
+}
+
+void PDBSymbolCustom::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolData.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolData.cpp
index d2b82111cc..8036765f1a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolData.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolData.cpp
@@ -1,68 +1,68 @@
-//===- PDBSymbolData.cpp - PDB data (e.g. variable) accessors ---*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolData::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
-
-std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolData::getLineNumbers() const {
- auto Len = RawSymbol->getLength();
- Len = Len ? Len : 1;
- if (auto RVA = RawSymbol->getRelativeVirtualAddress())
- return Session.findLineNumbersByRVA(RVA, Len);
-
- if (auto Section = RawSymbol->getAddressSection())
- return Session.findLineNumbersBySectOffset(
- Section, RawSymbol->getAddressOffset(), Len);
-
- return nullptr;
-}
-
-uint32_t PDBSymbolData::getCompilandId() const {
- if (auto Lines = getLineNumbers()) {
- if (auto FirstLine = Lines->getNext())
- return FirstLine->getCompilandId();
- }
-
- uint32_t DataSection = RawSymbol->getAddressSection();
- uint32_t DataOffset = RawSymbol->getAddressOffset();
- if (DataSection == 0) {
- if (auto RVA = RawSymbol->getRelativeVirtualAddress())
- Session.addressForRVA(RVA, DataSection, DataOffset);
- }
-
- if (DataSection) {
- if (auto SecContribs = Session.getSectionContribs()) {
- while (auto Section = SecContribs->getNext()) {
- if (Section->getAddressSection() == DataSection &&
- Section->getAddressOffset() <= DataOffset &&
- (Section->getAddressOffset() + Section->getLength()) > DataOffset)
- return Section->getCompilandId();
- }
- }
- } else {
- auto LexParentId = RawSymbol->getLexicalParentId();
- while (auto LexParent = Session.getSymbolById(LexParentId)) {
- if (LexParent->getSymTag() == PDB_SymType::Exe)
- break;
- if (LexParent->getSymTag() == PDB_SymType::Compiland)
- return LexParentId;
- LexParentId = LexParent->getRawSymbol().getLexicalParentId();
- }
- }
-
- return 0;
-}
+//===- PDBSymbolData.cpp - PDB data (e.g. variable) accessors ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/IPDBSectionContrib.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolData::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+
+std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolData::getLineNumbers() const {
+ auto Len = RawSymbol->getLength();
+ Len = Len ? Len : 1;
+ if (auto RVA = RawSymbol->getRelativeVirtualAddress())
+ return Session.findLineNumbersByRVA(RVA, Len);
+
+ if (auto Section = RawSymbol->getAddressSection())
+ return Session.findLineNumbersBySectOffset(
+ Section, RawSymbol->getAddressOffset(), Len);
+
+ return nullptr;
+}
+
+uint32_t PDBSymbolData::getCompilandId() const {
+ if (auto Lines = getLineNumbers()) {
+ if (auto FirstLine = Lines->getNext())
+ return FirstLine->getCompilandId();
+ }
+
+ uint32_t DataSection = RawSymbol->getAddressSection();
+ uint32_t DataOffset = RawSymbol->getAddressOffset();
+ if (DataSection == 0) {
+ if (auto RVA = RawSymbol->getRelativeVirtualAddress())
+ Session.addressForRVA(RVA, DataSection, DataOffset);
+ }
+
+ if (DataSection) {
+ if (auto SecContribs = Session.getSectionContribs()) {
+ while (auto Section = SecContribs->getNext()) {
+ if (Section->getAddressSection() == DataSection &&
+ Section->getAddressOffset() <= DataOffset &&
+ (Section->getAddressOffset() + Section->getLength()) > DataOffset)
+ return Section->getCompilandId();
+ }
+ }
+ } else {
+ auto LexParentId = RawSymbol->getLexicalParentId();
+ while (auto LexParent = Session.getSymbolById(LexParentId)) {
+ if (LexParent->getSymTag() == PDB_SymType::Exe)
+ break;
+ if (LexParent->getSymTag() == PDB_SymType::Compiland)
+ return LexParentId;
+ LexParentId = LexParent->getRawSymbol().getLexicalParentId();
+ }
+ }
+
+ return 0;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolExe.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolExe.cpp
index c85756c43e..042fd6ef73 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolExe.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolExe.cpp
@@ -1,29 +1,29 @@
-//===- PDBSymbolExe.cpp - ---------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolExe::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
-
-uint32_t PDBSymbolExe::getPointerByteSize() const {
- auto Pointer = findOneChild<PDBSymbolTypePointer>();
- if (Pointer)
- return Pointer->getLength();
-
- if (getMachineType() == PDB_Machine::x86)
- return 4;
- return 8;
-}
+//===- PDBSymbolExe.cpp - ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolExe::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+
+uint32_t PDBSymbolExe::getPointerByteSize() const {
+ auto Pointer = findOneChild<PDBSymbolTypePointer>();
+ if (Pointer)
+ return Pointer->getLength();
+
+ if (getMachineType() == PDB_Machine::x86)
+ return 4;
+ return 8;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFunc.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
index cb0329bc0e..a191a03a02 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFunc.cpp
@@ -1,111 +1,111 @@
-//===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
-
-#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
-#include "llvm/DebugInfo/PDB/PDBTypes.h"
-
-#include <unordered_set>
-#include <utility>
-#include <vector>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-namespace {
-class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
-public:
- typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
-
- FunctionArgEnumerator(const IPDBSession &PDBSession,
- const PDBSymbolFunc &PDBFunc)
- : Session(PDBSession), Func(PDBFunc) {
- // Arguments can appear multiple times if they have live range
- // information, so we only take the first occurrence.
- std::unordered_set<std::string> SeenNames;
- auto DataChildren = Func.findAllChildren<PDBSymbolData>();
- while (auto Child = DataChildren->getNext()) {
- if (Child->getDataKind() == PDB_DataKind::Param) {
- std::string Name = Child->getName();
- if (SeenNames.find(Name) != SeenNames.end())
- continue;
- Args.push_back(std::move(Child));
- SeenNames.insert(Name);
- }
- }
- reset();
- }
-
- uint32_t getChildCount() const override { return Args.size(); }
-
- std::unique_ptr<PDBSymbolData>
- getChildAtIndex(uint32_t Index) const override {
- if (Index >= Args.size())
- return nullptr;
-
- return Session.getConcreteSymbolById<PDBSymbolData>(
- Args[Index]->getSymIndexId());
- }
-
- std::unique_ptr<PDBSymbolData> getNext() override {
- if (CurIter == Args.end())
- return nullptr;
- const auto &Result = **CurIter;
- ++CurIter;
- return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
- }
-
- void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }
-
-private:
- typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
- const IPDBSession &Session;
- const PDBSymbolFunc &Func;
- ArgListType Args;
- ArgListType::const_iterator CurIter;
-};
-}
-
-std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
-PDBSymbolFunc::getArguments() const {
- return std::make_unique<FunctionArgEnumerator>(Session, *this);
-}
-
-void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
-
-bool PDBSymbolFunc::isDestructor() const {
- std::string Name = getName();
- if (Name.empty())
- return false;
- if (Name[0] == '~')
- return true;
- if (Name == "__vecDelDtor")
- return true;
- return false;
-}
-
-std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolFunc::getLineNumbers() const {
- auto Len = RawSymbol->getLength();
- return Session.findLineNumbersByAddress(RawSymbol->getVirtualAddress(),
- Len ? Len : 1);
-}
-
-uint32_t PDBSymbolFunc::getCompilandId() const {
- if (auto Lines = getLineNumbers()) {
- if (auto FirstLine = Lines->getNext()) {
- return FirstLine->getCompilandId();
- }
- }
- return 0;
-}
+//===- PDBSymbolFunc.cpp - --------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+
+#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+
+#include <unordered_set>
+#include <utility>
+#include <vector>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+namespace {
+class FunctionArgEnumerator : public IPDBEnumChildren<PDBSymbolData> {
+public:
+ typedef ConcreteSymbolEnumerator<PDBSymbolData> ArgEnumeratorType;
+
+ FunctionArgEnumerator(const IPDBSession &PDBSession,
+ const PDBSymbolFunc &PDBFunc)
+ : Session(PDBSession), Func(PDBFunc) {
+ // Arguments can appear multiple times if they have live range
+ // information, so we only take the first occurrence.
+ std::unordered_set<std::string> SeenNames;
+ auto DataChildren = Func.findAllChildren<PDBSymbolData>();
+ while (auto Child = DataChildren->getNext()) {
+ if (Child->getDataKind() == PDB_DataKind::Param) {
+ std::string Name = Child->getName();
+ if (SeenNames.find(Name) != SeenNames.end())
+ continue;
+ Args.push_back(std::move(Child));
+ SeenNames.insert(Name);
+ }
+ }
+ reset();
+ }
+
+ uint32_t getChildCount() const override { return Args.size(); }
+
+ std::unique_ptr<PDBSymbolData>
+ getChildAtIndex(uint32_t Index) const override {
+ if (Index >= Args.size())
+ return nullptr;
+
+ return Session.getConcreteSymbolById<PDBSymbolData>(
+ Args[Index]->getSymIndexId());
+ }
+
+ std::unique_ptr<PDBSymbolData> getNext() override {
+ if (CurIter == Args.end())
+ return nullptr;
+ const auto &Result = **CurIter;
+ ++CurIter;
+ return Session.getConcreteSymbolById<PDBSymbolData>(Result.getSymIndexId());
+ }
+
+ void reset() override { CurIter = Args.empty() ? Args.end() : Args.begin(); }
+
+private:
+ typedef std::vector<std::unique_ptr<PDBSymbolData>> ArgListType;
+ const IPDBSession &Session;
+ const PDBSymbolFunc &Func;
+ ArgListType Args;
+ ArgListType::const_iterator CurIter;
+};
+}
+
+std::unique_ptr<IPDBEnumChildren<PDBSymbolData>>
+PDBSymbolFunc::getArguments() const {
+ return std::make_unique<FunctionArgEnumerator>(Session, *this);
+}
+
+void PDBSymbolFunc::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+
+bool PDBSymbolFunc::isDestructor() const {
+ std::string Name = getName();
+ if (Name.empty())
+ return false;
+ if (Name[0] == '~')
+ return true;
+ if (Name == "__vecDelDtor")
+ return true;
+ return false;
+}
+
+std::unique_ptr<IPDBEnumLineNumbers> PDBSymbolFunc::getLineNumbers() const {
+ auto Len = RawSymbol->getLength();
+ return Session.findLineNumbersByAddress(RawSymbol->getVirtualAddress(),
+ Len ? Len : 1);
+}
+
+uint32_t PDBSymbolFunc::getCompilandId() const {
+ if (auto Lines = getLineNumbers()) {
+ if (auto FirstLine = Lines->getNext()) {
+ return FirstLine->getCompilandId();
+ }
+ }
+ return 0;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
index 66433dc17b..000be3331e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugEnd.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolFuncDebugEnd.cpp - ------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolFuncDebugEnd::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolFuncDebugEnd.cpp - ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolFuncDebugEnd::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
index fe32c93c01..fcda5edf68 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolFuncDebugStart.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolFuncDebugStart.cpp - ----------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolFuncDebugStart::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolFuncDebugStart.cpp - ----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolFuncDebugStart::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolLabel.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
index 1fffe69a0c..3c1bc27dd5 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolLabel.cpp
@@ -1,18 +1,18 @@
-//===- PDBSymbolLabel.cpp - -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolLabel::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+//===- PDBSymbolLabel.cpp - -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolLabel.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolLabel::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
index 08697683f6..239b06a765 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolPublicSymbol.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolPublicSymbol.cpp - ------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolPublicSymbol::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolPublicSymbol.cpp - ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolPublicSymbol::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolThunk.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
index 6483858183..1f023654c2 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolThunk.cpp
@@ -1,18 +1,18 @@
-//===- PDBSymbolThunk.cpp - -------------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolThunk::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+//===- PDBSymbolThunk.cpp - -------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolThunk.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolThunk::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
index a0d521abe4..9d80db1370 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeArray.cpp
@@ -1,24 +1,24 @@
-//===- PDBSymbolTypeArray.cpp - ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeArray::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
-
-void PDBSymbolTypeArray::dumpRight(PDBSymDumper &Dumper) const {
- Dumper.dumpRight(*this);
-}
+//===- PDBSymbolTypeArray.cpp - ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeArray::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
+
+void PDBSymbolTypeArray::dumpRight(PDBSymDumper &Dumper) const {
+ Dumper.dumpRight(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
index 08467059b5..9fa5530160 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBaseClass.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolTypeBaseClass.cpp - -----------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeBaseClass::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeBaseClass.cpp - -----------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeBaseClass::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
index a0dd9ef601..f0adad48bf 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeBuiltin.cpp
@@ -1,20 +1,20 @@
-//===- PDBSymbolTypeBuiltin.cpp - ------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeBuiltin::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeBuiltin.cpp - ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeBuiltin::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
index 6723894c90..f68f6e0022 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeCustom.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolTypeCustom.cpp - --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeCustom::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeCustom.cpp - --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeCustom.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeCustom::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
index 4a25a391f2..910c158e97 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeDimension.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolTypeDimension.cpp - --------------------------------*- C++
-//-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-void PDBSymbolTypeDimension::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeDimension.cpp - --------------------------------*- C++
+//-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeDimension.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+void PDBSymbolTypeDimension::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
index b9fdf6aec8..b1de848ffb 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeEnum.cpp
@@ -1,19 +1,19 @@
-//===- PDBSymbolTypeEnum.cpp - --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeEnum::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+//===- PDBSymbolTypeEnum.cpp - --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeEnum::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
index 4ffea42cbb..db3279e407 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFriend.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolTypeFriend.cpp - --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeFriend::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeFriend.cpp - --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFriend.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeFriend::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
index 683e93548f..5a9531061c 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionArg.cpp
@@ -1,20 +1,20 @@
-//===- PDBSymbolTypeFunctionArg.cpp - --------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeFunctionArg::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeFunctionArg.cpp - --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeFunctionArg::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
index 1373615522..2d1e78711f 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeFunctionSig.cpp
@@ -1,93 +1,93 @@
-//===- PDBSymbolTypeFunctionSig.cpp - --------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
-
-#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
-#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-namespace {
-class FunctionArgEnumerator : public IPDBEnumSymbols {
-public:
- typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg> ArgEnumeratorType;
-
- FunctionArgEnumerator(const IPDBSession &PDBSession,
- const PDBSymbolTypeFunctionSig &Sig)
- : Session(PDBSession),
- Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {}
-
- FunctionArgEnumerator(const IPDBSession &PDBSession,
- std::unique_ptr<ArgEnumeratorType> ArgEnumerator)
- : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {}
-
- uint32_t getChildCount() const override {
- return Enumerator->getChildCount();
- }
-
- std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
- auto FunctionArgSymbol = Enumerator->getChildAtIndex(Index);
- if (!FunctionArgSymbol)
- return nullptr;
- return Session.getSymbolById(FunctionArgSymbol->getTypeId());
- }
-
- std::unique_ptr<PDBSymbol> getNext() override {
- auto FunctionArgSymbol = Enumerator->getNext();
- if (!FunctionArgSymbol)
- return nullptr;
- return Session.getSymbolById(FunctionArgSymbol->getTypeId());
- }
-
- void reset() override { Enumerator->reset(); }
-
-private:
- const IPDBSession &Session;
- std::unique_ptr<ArgEnumeratorType> Enumerator;
-};
-}
-
-std::unique_ptr<IPDBEnumSymbols>
-PDBSymbolTypeFunctionSig::getArguments() const {
- return std::make_unique<FunctionArgEnumerator>(Session, *this);
-}
-
-void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
-
-void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const {
- Dumper.dumpRight(*this);
-}
-
-bool PDBSymbolTypeFunctionSig::isCVarArgs() const {
- auto SigArguments = getArguments();
- if (!SigArguments)
- return false;
- uint32_t NumArgs = SigArguments->getChildCount();
- if (NumArgs == 0)
- return false;
- auto Last = SigArguments->getChildAtIndex(NumArgs - 1);
- if (auto Builtin = llvm::dyn_cast_or_null<PDBSymbolTypeBuiltin>(Last.get())) {
- if (Builtin->getBuiltinType() == PDB_BuiltinType::None)
- return true;
- }
-
- // Note that for a variadic template signature, this method always returns
- // false since the parameters of the template are specialized.
- return false;
-}
+//===- PDBSymbolTypeFunctionSig.cpp - --------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h"
+
+#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h"
+#include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+namespace {
+class FunctionArgEnumerator : public IPDBEnumSymbols {
+public:
+ typedef ConcreteSymbolEnumerator<PDBSymbolTypeFunctionArg> ArgEnumeratorType;
+
+ FunctionArgEnumerator(const IPDBSession &PDBSession,
+ const PDBSymbolTypeFunctionSig &Sig)
+ : Session(PDBSession),
+ Enumerator(Sig.findAllChildren<PDBSymbolTypeFunctionArg>()) {}
+
+ FunctionArgEnumerator(const IPDBSession &PDBSession,
+ std::unique_ptr<ArgEnumeratorType> ArgEnumerator)
+ : Session(PDBSession), Enumerator(std::move(ArgEnumerator)) {}
+
+ uint32_t getChildCount() const override {
+ return Enumerator->getChildCount();
+ }
+
+ std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
+ auto FunctionArgSymbol = Enumerator->getChildAtIndex(Index);
+ if (!FunctionArgSymbol)
+ return nullptr;
+ return Session.getSymbolById(FunctionArgSymbol->getTypeId());
+ }
+
+ std::unique_ptr<PDBSymbol> getNext() override {
+ auto FunctionArgSymbol = Enumerator->getNext();
+ if (!FunctionArgSymbol)
+ return nullptr;
+ return Session.getSymbolById(FunctionArgSymbol->getTypeId());
+ }
+
+ void reset() override { Enumerator->reset(); }
+
+private:
+ const IPDBSession &Session;
+ std::unique_ptr<ArgEnumeratorType> Enumerator;
+};
+}
+
+std::unique_ptr<IPDBEnumSymbols>
+PDBSymbolTypeFunctionSig::getArguments() const {
+ return std::make_unique<FunctionArgEnumerator>(Session, *this);
+}
+
+void PDBSymbolTypeFunctionSig::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
+
+void PDBSymbolTypeFunctionSig::dumpRight(PDBSymDumper &Dumper) const {
+ Dumper.dumpRight(*this);
+}
+
+bool PDBSymbolTypeFunctionSig::isCVarArgs() const {
+ auto SigArguments = getArguments();
+ if (!SigArguments)
+ return false;
+ uint32_t NumArgs = SigArguments->getChildCount();
+ if (NumArgs == 0)
+ return false;
+ auto Last = SigArguments->getChildAtIndex(NumArgs - 1);
+ if (auto Builtin = llvm::dyn_cast_or_null<PDBSymbolTypeBuiltin>(Last.get())) {
+ if (Builtin->getBuiltinType() == PDB_BuiltinType::None)
+ return true;
+ }
+
+ // Note that for a variadic template signature, this method always returns
+ // false since the parameters of the template are specialized.
+ return false;
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
index e80e6c7165..8ac467e303 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeManaged.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymboTypelManaged.cpp - ------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeManaged::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymboTypelManaged.cpp - ------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeManaged.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeManaged::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
index 462fc31535..6cfc89a651 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypePointer.cpp
@@ -1,25 +1,25 @@
-//===- PDBSymbolTypePointer.cpp -----------------------------------*- C++ -===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
-
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypePointer::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
-
-void PDBSymbolTypePointer::dumpRight(PDBSymDumper &Dumper) const {
- Dumper.dumpRight(*this);
-}
+//===- PDBSymbolTypePointer.cpp -----------------------------------*- C++ -===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypePointer::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
+
+void PDBSymbolTypePointer::dumpRight(PDBSymDumper &Dumper) const {
+ Dumper.dumpRight(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
index 70749d9bf5..95627d053b 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeTypedef.cpp
@@ -1,20 +1,20 @@
-//===- PDBSymbolTypeTypedef.cpp ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeTypedef::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeTypedef.cpp ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeTypedef::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
index d302c29a3b..91148f9569 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeUDT.cpp
@@ -1,25 +1,25 @@
-//===- PDBSymbolTypeUDT.cpp - --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
-
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeUDT::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+//===- PDBSymbolTypeUDT.cpp - --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolExe.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeUDT::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
index 4e2a45116d..6764df7778 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTable.cpp
@@ -1,20 +1,20 @@
-//===- PDBSymbolTypeVTable.cpp - --------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeVTable::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeVTable.cpp - --------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeVTable::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
index 78957620e0..b3d34c997c 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolTypeVTableShape.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolTypeVTableShape.cpp - ---------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolTypeVTableShape::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolTypeVTableShape.cpp - ---------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTableShape.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolTypeVTableShape::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
index 650d011831..ec557ff8c7 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUnknown.cpp
@@ -1,19 +1,19 @@
-//===- PDBSymbolUnknown.cpp - -----------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolUnknown::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
+//===- PDBSymbolUnknown.cpp - -----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolUnknown.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolUnknown::dump(PDBSymDumper &Dumper) const { Dumper.dump(*this); }
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
index 74afbdb180..f341d48ab0 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/PDBSymbolUsingNamespace.cpp
@@ -1,21 +1,21 @@
-//===- PDBSymbolUsingNamespace.cpp - ------------------- --------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
-
-#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-
-#include <utility>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-void PDBSymbolUsingNamespace::dump(PDBSymDumper &Dumper) const {
- Dumper.dump(*this);
-}
+//===- PDBSymbolUsingNamespace.cpp - ------------------- --------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/PDBSymbolUsingNamespace.h"
+
+#include "llvm/DebugInfo/PDB/PDBSymDumper.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+
+#include <utility>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+void PDBSymbolUsingNamespace::dump(PDBSymDumper &Dumper) const {
+ Dumper.dump(*this);
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp b/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp
index 55854bb498..71d0c66794 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/UDTLayout.cpp
@@ -1,302 +1,302 @@
-//===- UDTLayout.cpp ------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/PDB/UDTLayout.h"
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/BitVector.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
-#include "llvm/DebugInfo/PDB/IPDBSession.h"
-#include "llvm/DebugInfo/PDB/PDBSymbol.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
-#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
-#include "llvm/DebugInfo/PDB/PDBTypes.h"
-#include "llvm/Support/Casting.h"
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <memory>
-
-using namespace llvm;
-using namespace llvm::pdb;
-
-static std::unique_ptr<PDBSymbol> getSymbolType(const PDBSymbol &Symbol) {
- const IPDBSession &Session = Symbol.getSession();
- const IPDBRawSymbol &RawSymbol = Symbol.getRawSymbol();
- uint32_t TypeId = RawSymbol.getTypeId();
- return Session.getSymbolById(TypeId);
-}
-
-static uint32_t getTypeLength(const PDBSymbol &Symbol) {
- auto SymbolType = getSymbolType(Symbol);
- const IPDBRawSymbol &RawType = SymbolType->getRawSymbol();
-
- return RawType.getLength();
-}
-
-LayoutItemBase::LayoutItemBase(const UDTLayoutBase *Parent,
- const PDBSymbol *Symbol, const std::string &Name,
- uint32_t OffsetInParent, uint32_t Size,
- bool IsElided)
- : Symbol(Symbol), Parent(Parent), Name(Name),
- OffsetInParent(OffsetInParent), SizeOf(Size), LayoutSize(Size),
- IsElided(IsElided) {
- UsedBytes.resize(SizeOf, true);
-}
-
-uint32_t LayoutItemBase::deepPaddingSize() const {
- return UsedBytes.size() - UsedBytes.count();
-}
-
-uint32_t LayoutItemBase::tailPadding() const {
- int Last = UsedBytes.find_last();
-
- return UsedBytes.size() - (Last + 1);
-}
-
-DataMemberLayoutItem::DataMemberLayoutItem(
- const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> Member)
- : LayoutItemBase(&Parent, Member.get(), Member->getName(),
- Member->getOffset(), getTypeLength(*Member), false),
- DataMember(std::move(Member)) {
- auto Type = DataMember->getType();
- if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
- UdtLayout = std::make_unique<ClassLayout>(std::move(UDT));
- UsedBytes = UdtLayout->usedBytes();
- }
-}
-
-VBPtrLayoutItem::VBPtrLayoutItem(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeBuiltin> Sym,
- uint32_t Offset, uint32_t Size)
- : LayoutItemBase(&Parent, Sym.get(), "<vbptr>", Offset, Size, false),
- Type(std::move(Sym)) {
-}
-
-const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
- return *cast<PDBSymbolData>(Symbol);
-}
-
-bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
-
-const ClassLayout &DataMemberLayoutItem::getUDTLayout() const {
- return *UdtLayout;
-}
-
-VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
- std::unique_ptr<PDBSymbolTypeVTable> VT)
- : LayoutItemBase(&Parent, VT.get(), "<vtbl>", 0, getTypeLength(*VT), false),
- VTable(std::move(VT)) {
- auto VTableType = cast<PDBSymbolTypePointer>(VTable->getType());
- ElementSize = VTableType->getLength();
-}
-
-UDTLayoutBase::UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
- const std::string &Name, uint32_t OffsetInParent,
- uint32_t Size, bool IsElided)
- : LayoutItemBase(Parent, &Sym, Name, OffsetInParent, Size, IsElided) {
- // UDT storage comes from a union of all the children's storage, so start out
- // uninitialized.
- UsedBytes.reset(0, Size);
-
- initializeChildren(Sym);
- if (LayoutSize < Size)
- UsedBytes.resize(LayoutSize);
-}
-
-uint32_t UDTLayoutBase::tailPadding() const {
- uint32_t Abs = LayoutItemBase::tailPadding();
- if (!LayoutItems.empty()) {
- const LayoutItemBase *Back = LayoutItems.back();
- uint32_t ChildPadding = Back->LayoutItemBase::tailPadding();
- if (Abs < ChildPadding)
- Abs = 0;
- else
- Abs -= ChildPadding;
- }
- return Abs;
-}
-
-ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
- : UDTLayoutBase(nullptr, UDT, UDT.getName(), 0, UDT.getLength(), false),
- UDT(UDT) {
- ImmediateUsedBytes.resize(SizeOf, false);
- for (auto &LI : LayoutItems) {
- uint32_t Begin = LI->getOffsetInParent();
- uint32_t End = Begin + LI->getLayoutSize();
- End = std::min(SizeOf, End);
- ImmediateUsedBytes.set(Begin, End);
- }
-}
-
-ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
- : ClassLayout(*UDT) {
- OwnedStorage = std::move(UDT);
-}
-
-uint32_t ClassLayout::immediatePadding() const {
- return SizeOf - ImmediateUsedBytes.count();
-}
-
-BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
- uint32_t OffsetInParent, bool Elide,
- std::unique_ptr<PDBSymbolTypeBaseClass> B)
- : UDTLayoutBase(&Parent, *B, B->getName(), OffsetInParent, B->getLength(),
- Elide),
- Base(std::move(B)) {
- if (isEmptyBase()) {
- // Special case an empty base so that it doesn't get treated as padding.
- UsedBytes.resize(1);
- UsedBytes.set(0);
- }
- IsVirtualBase = Base->isVirtualBaseClass();
-}
-
-void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
- // Handled bases first, followed by VTables, followed by data members,
- // followed by functions, followed by other. This ordering is necessary
- // so that bases and vtables get initialized before any functions which
- // may override them.
- UniquePtrVector<PDBSymbolTypeBaseClass> Bases;
- UniquePtrVector<PDBSymbolTypeVTable> VTables;
- UniquePtrVector<PDBSymbolData> Members;
- UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBaseSyms;
-
- auto Children = Sym.findAllChildren();
- while (auto Child = Children->getNext()) {
- if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) {
- if (Base->isVirtualBaseClass())
- VirtualBaseSyms.push_back(std::move(Base));
- else
- Bases.push_back(std::move(Base));
- }
- else if (auto Data = unique_dyn_cast<PDBSymbolData>(Child)) {
- if (Data->getDataKind() == PDB_DataKind::Member)
- Members.push_back(std::move(Data));
- else
- Other.push_back(std::move(Data));
- } else if (auto VT = unique_dyn_cast<PDBSymbolTypeVTable>(Child))
- VTables.push_back(std::move(VT));
- else if (auto Func = unique_dyn_cast<PDBSymbolFunc>(Child))
- Funcs.push_back(std::move(Func));
- else {
- Other.push_back(std::move(Child));
- }
- }
-
- // We don't want to have any re-allocations in the list of bases, so make
- // sure to reserve enough space so that our ArrayRefs don't get invalidated.
- AllBases.reserve(Bases.size() + VirtualBaseSyms.size());
-
- // Only add non-virtual bases to the class first. Only at the end of the
- // class, after all non-virtual bases and data members have been added do we
- // add virtual bases. This way the offsets are correctly aligned when we go
- // to lay out virtual bases.
- for (auto &Base : Bases) {
- uint32_t Offset = Base->getOffset();
- // Non-virtual bases never get elided.
- auto BL = std::make_unique<BaseClassLayout>(*this, Offset, false,
- std::move(Base));
-
- AllBases.push_back(BL.get());
- addChildToLayout(std::move(BL));
- }
- NonVirtualBases = AllBases;
-
- assert(VTables.size() <= 1);
- if (!VTables.empty()) {
- auto VTLayout =
- std::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
-
- VTable = VTLayout.get();
-
- addChildToLayout(std::move(VTLayout));
- }
-
- for (auto &Data : Members) {
- auto DM = std::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
-
- addChildToLayout(std::move(DM));
- }
-
- // Make sure add virtual bases before adding functions, since functions may be
- // overrides of virtual functions declared in a virtual base, so the VTables
- // and virtual intros need to be correctly initialized.
- for (auto &VB : VirtualBaseSyms) {
- int VBPO = VB->getVirtualBasePointerOffset();
- if (!hasVBPtrAtOffset(VBPO)) {
- if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
- auto VBPL = std::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
- VBPO, VBP->getLength());
- VBPtr = VBPL.get();
- addChildToLayout(std::move(VBPL));
- }
- }
-
- // Virtual bases always go at the end. So just look for the last place we
- // ended when writing something, and put our virtual base there.
- // Note that virtual bases get elided unless this is a top-most derived
- // class.
- uint32_t Offset = UsedBytes.find_last() + 1;
- bool Elide = (Parent != nullptr);
- auto BL =
- std::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
- AllBases.push_back(BL.get());
-
- // Only lay this virtual base out directly inside of *this* class if this
- // is a top-most derived class. Keep track of it regardless, but only
- // physically lay it out if it's a topmost derived class.
- addChildToLayout(std::move(BL));
- }
- VirtualBases = makeArrayRef(AllBases).drop_front(NonVirtualBases.size());
-
- if (Parent != nullptr)
- LayoutSize = UsedBytes.find_last() + 1;
-}
-
-bool UDTLayoutBase::hasVBPtrAtOffset(uint32_t Off) const {
- if (VBPtr && VBPtr->getOffsetInParent() == Off)
- return true;
- for (BaseClassLayout *BL : AllBases) {
- if (BL->hasVBPtrAtOffset(Off - BL->getOffsetInParent()))
- return true;
- }
- return false;
-}
-
-void UDTLayoutBase::addChildToLayout(std::unique_ptr<LayoutItemBase> Child) {
- uint32_t Begin = Child->getOffsetInParent();
-
- if (!Child->isElided()) {
- BitVector ChildBytes = Child->usedBytes();
-
- // Suppose the child occupies 4 bytes starting at offset 12 in a 32 byte
- // class. When we call ChildBytes.resize(32), the Child's storage will
- // still begin at offset 0, so we need to shift it left by offset bytes
- // to get it into the right position.
- ChildBytes.resize(UsedBytes.size());
- ChildBytes <<= Child->getOffsetInParent();
- UsedBytes |= ChildBytes;
-
- if (ChildBytes.count() > 0) {
+//===- UDTLayout.cpp ------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/PDB/UDTLayout.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/PDB/IPDBRawSymbol.h"
+#include "llvm/DebugInfo/PDB/IPDBSession.h"
+#include "llvm/DebugInfo/PDB/PDBSymbol.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolData.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolFunc.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypePointer.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h"
+#include "llvm/DebugInfo/PDB/PDBSymbolTypeVTable.h"
+#include "llvm/DebugInfo/PDB/PDBTypes.h"
+#include "llvm/Support/Casting.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <memory>
+
+using namespace llvm;
+using namespace llvm::pdb;
+
+static std::unique_ptr<PDBSymbol> getSymbolType(const PDBSymbol &Symbol) {
+ const IPDBSession &Session = Symbol.getSession();
+ const IPDBRawSymbol &RawSymbol = Symbol.getRawSymbol();
+ uint32_t TypeId = RawSymbol.getTypeId();
+ return Session.getSymbolById(TypeId);
+}
+
+static uint32_t getTypeLength(const PDBSymbol &Symbol) {
+ auto SymbolType = getSymbolType(Symbol);
+ const IPDBRawSymbol &RawType = SymbolType->getRawSymbol();
+
+ return RawType.getLength();
+}
+
+LayoutItemBase::LayoutItemBase(const UDTLayoutBase *Parent,
+ const PDBSymbol *Symbol, const std::string &Name,
+ uint32_t OffsetInParent, uint32_t Size,
+ bool IsElided)
+ : Symbol(Symbol), Parent(Parent), Name(Name),
+ OffsetInParent(OffsetInParent), SizeOf(Size), LayoutSize(Size),
+ IsElided(IsElided) {
+ UsedBytes.resize(SizeOf, true);
+}
+
+uint32_t LayoutItemBase::deepPaddingSize() const {
+ return UsedBytes.size() - UsedBytes.count();
+}
+
+uint32_t LayoutItemBase::tailPadding() const {
+ int Last = UsedBytes.find_last();
+
+ return UsedBytes.size() - (Last + 1);
+}
+
+DataMemberLayoutItem::DataMemberLayoutItem(
+ const UDTLayoutBase &Parent, std::unique_ptr<PDBSymbolData> Member)
+ : LayoutItemBase(&Parent, Member.get(), Member->getName(),
+ Member->getOffset(), getTypeLength(*Member), false),
+ DataMember(std::move(Member)) {
+ auto Type = DataMember->getType();
+ if (auto UDT = unique_dyn_cast<PDBSymbolTypeUDT>(Type)) {
+ UdtLayout = std::make_unique<ClassLayout>(std::move(UDT));
+ UsedBytes = UdtLayout->usedBytes();
+ }
+}
+
+VBPtrLayoutItem::VBPtrLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeBuiltin> Sym,
+ uint32_t Offset, uint32_t Size)
+ : LayoutItemBase(&Parent, Sym.get(), "<vbptr>", Offset, Size, false),
+ Type(std::move(Sym)) {
+}
+
+const PDBSymbolData &DataMemberLayoutItem::getDataMember() {
+ return *cast<PDBSymbolData>(Symbol);
+}
+
+bool DataMemberLayoutItem::hasUDTLayout() const { return UdtLayout != nullptr; }
+
+const ClassLayout &DataMemberLayoutItem::getUDTLayout() const {
+ return *UdtLayout;
+}
+
+VTableLayoutItem::VTableLayoutItem(const UDTLayoutBase &Parent,
+ std::unique_ptr<PDBSymbolTypeVTable> VT)
+ : LayoutItemBase(&Parent, VT.get(), "<vtbl>", 0, getTypeLength(*VT), false),
+ VTable(std::move(VT)) {
+ auto VTableType = cast<PDBSymbolTypePointer>(VTable->getType());
+ ElementSize = VTableType->getLength();
+}
+
+UDTLayoutBase::UDTLayoutBase(const UDTLayoutBase *Parent, const PDBSymbol &Sym,
+ const std::string &Name, uint32_t OffsetInParent,
+ uint32_t Size, bool IsElided)
+ : LayoutItemBase(Parent, &Sym, Name, OffsetInParent, Size, IsElided) {
+ // UDT storage comes from a union of all the children's storage, so start out
+ // uninitialized.
+ UsedBytes.reset(0, Size);
+
+ initializeChildren(Sym);
+ if (LayoutSize < Size)
+ UsedBytes.resize(LayoutSize);
+}
+
+uint32_t UDTLayoutBase::tailPadding() const {
+ uint32_t Abs = LayoutItemBase::tailPadding();
+ if (!LayoutItems.empty()) {
+ const LayoutItemBase *Back = LayoutItems.back();
+ uint32_t ChildPadding = Back->LayoutItemBase::tailPadding();
+ if (Abs < ChildPadding)
+ Abs = 0;
+ else
+ Abs -= ChildPadding;
+ }
+ return Abs;
+}
+
+ClassLayout::ClassLayout(const PDBSymbolTypeUDT &UDT)
+ : UDTLayoutBase(nullptr, UDT, UDT.getName(), 0, UDT.getLength(), false),
+ UDT(UDT) {
+ ImmediateUsedBytes.resize(SizeOf, false);
+ for (auto &LI : LayoutItems) {
+ uint32_t Begin = LI->getOffsetInParent();
+ uint32_t End = Begin + LI->getLayoutSize();
+ End = std::min(SizeOf, End);
+ ImmediateUsedBytes.set(Begin, End);
+ }
+}
+
+ClassLayout::ClassLayout(std::unique_ptr<PDBSymbolTypeUDT> UDT)
+ : ClassLayout(*UDT) {
+ OwnedStorage = std::move(UDT);
+}
+
+uint32_t ClassLayout::immediatePadding() const {
+ return SizeOf - ImmediateUsedBytes.count();
+}
+
+BaseClassLayout::BaseClassLayout(const UDTLayoutBase &Parent,
+ uint32_t OffsetInParent, bool Elide,
+ std::unique_ptr<PDBSymbolTypeBaseClass> B)
+ : UDTLayoutBase(&Parent, *B, B->getName(), OffsetInParent, B->getLength(),
+ Elide),
+ Base(std::move(B)) {
+ if (isEmptyBase()) {
+ // Special case an empty base so that it doesn't get treated as padding.
+ UsedBytes.resize(1);
+ UsedBytes.set(0);
+ }
+ IsVirtualBase = Base->isVirtualBaseClass();
+}
+
+void UDTLayoutBase::initializeChildren(const PDBSymbol &Sym) {
+ // Handled bases first, followed by VTables, followed by data members,
+ // followed by functions, followed by other. This ordering is necessary
+ // so that bases and vtables get initialized before any functions which
+ // may override them.
+ UniquePtrVector<PDBSymbolTypeBaseClass> Bases;
+ UniquePtrVector<PDBSymbolTypeVTable> VTables;
+ UniquePtrVector<PDBSymbolData> Members;
+ UniquePtrVector<PDBSymbolTypeBaseClass> VirtualBaseSyms;
+
+ auto Children = Sym.findAllChildren();
+ while (auto Child = Children->getNext()) {
+ if (auto Base = unique_dyn_cast<PDBSymbolTypeBaseClass>(Child)) {
+ if (Base->isVirtualBaseClass())
+ VirtualBaseSyms.push_back(std::move(Base));
+ else
+ Bases.push_back(std::move(Base));
+ }
+ else if (auto Data = unique_dyn_cast<PDBSymbolData>(Child)) {
+ if (Data->getDataKind() == PDB_DataKind::Member)
+ Members.push_back(std::move(Data));
+ else
+ Other.push_back(std::move(Data));
+ } else if (auto VT = unique_dyn_cast<PDBSymbolTypeVTable>(Child))
+ VTables.push_back(std::move(VT));
+ else if (auto Func = unique_dyn_cast<PDBSymbolFunc>(Child))
+ Funcs.push_back(std::move(Func));
+ else {
+ Other.push_back(std::move(Child));
+ }
+ }
+
+ // We don't want to have any re-allocations in the list of bases, so make
+ // sure to reserve enough space so that our ArrayRefs don't get invalidated.
+ AllBases.reserve(Bases.size() + VirtualBaseSyms.size());
+
+ // Only add non-virtual bases to the class first. Only at the end of the
+ // class, after all non-virtual bases and data members have been added do we
+ // add virtual bases. This way the offsets are correctly aligned when we go
+ // to lay out virtual bases.
+ for (auto &Base : Bases) {
+ uint32_t Offset = Base->getOffset();
+ // Non-virtual bases never get elided.
+ auto BL = std::make_unique<BaseClassLayout>(*this, Offset, false,
+ std::move(Base));
+
+ AllBases.push_back(BL.get());
+ addChildToLayout(std::move(BL));
+ }
+ NonVirtualBases = AllBases;
+
+ assert(VTables.size() <= 1);
+ if (!VTables.empty()) {
+ auto VTLayout =
+ std::make_unique<VTableLayoutItem>(*this, std::move(VTables[0]));
+
+ VTable = VTLayout.get();
+
+ addChildToLayout(std::move(VTLayout));
+ }
+
+ for (auto &Data : Members) {
+ auto DM = std::make_unique<DataMemberLayoutItem>(*this, std::move(Data));
+
+ addChildToLayout(std::move(DM));
+ }
+
+ // Make sure add virtual bases before adding functions, since functions may be
+ // overrides of virtual functions declared in a virtual base, so the VTables
+ // and virtual intros need to be correctly initialized.
+ for (auto &VB : VirtualBaseSyms) {
+ int VBPO = VB->getVirtualBasePointerOffset();
+ if (!hasVBPtrAtOffset(VBPO)) {
+ if (auto VBP = VB->getRawSymbol().getVirtualBaseTableType()) {
+ auto VBPL = std::make_unique<VBPtrLayoutItem>(*this, std::move(VBP),
+ VBPO, VBP->getLength());
+ VBPtr = VBPL.get();
+ addChildToLayout(std::move(VBPL));
+ }
+ }
+
+ // Virtual bases always go at the end. So just look for the last place we
+ // ended when writing something, and put our virtual base there.
+ // Note that virtual bases get elided unless this is a top-most derived
+ // class.
+ uint32_t Offset = UsedBytes.find_last() + 1;
+ bool Elide = (Parent != nullptr);
+ auto BL =
+ std::make_unique<BaseClassLayout>(*this, Offset, Elide, std::move(VB));
+ AllBases.push_back(BL.get());
+
+ // Only lay this virtual base out directly inside of *this* class if this
+ // is a top-most derived class. Keep track of it regardless, but only
+ // physically lay it out if it's a topmost derived class.
+ addChildToLayout(std::move(BL));
+ }
+ VirtualBases = makeArrayRef(AllBases).drop_front(NonVirtualBases.size());
+
+ if (Parent != nullptr)
+ LayoutSize = UsedBytes.find_last() + 1;
+}
+
+bool UDTLayoutBase::hasVBPtrAtOffset(uint32_t Off) const {
+ if (VBPtr && VBPtr->getOffsetInParent() == Off)
+ return true;
+ for (BaseClassLayout *BL : AllBases) {
+ if (BL->hasVBPtrAtOffset(Off - BL->getOffsetInParent()))
+ return true;
+ }
+ return false;
+}
+
+void UDTLayoutBase::addChildToLayout(std::unique_ptr<LayoutItemBase> Child) {
+ uint32_t Begin = Child->getOffsetInParent();
+
+ if (!Child->isElided()) {
+ BitVector ChildBytes = Child->usedBytes();
+
+ // Suppose the child occupies 4 bytes starting at offset 12 in a 32 byte
+ // class. When we call ChildBytes.resize(32), the Child's storage will
+ // still begin at offset 0, so we need to shift it left by offset bytes
+ // to get it into the right position.
+ ChildBytes.resize(UsedBytes.size());
+ ChildBytes <<= Child->getOffsetInParent();
+ UsedBytes |= ChildBytes;
+
+ if (ChildBytes.count() > 0) {
auto Loc = llvm::upper_bound(
LayoutItems, Begin, [](uint32_t Off, const LayoutItemBase *Item) {
return (Off < Item->getOffsetInParent());
});
-
- LayoutItems.insert(Loc, Child.get());
- }
- }
-
- ChildStorage.push_back(std::move(Child));
-}
+
+ LayoutItems.insert(Loc, Child.get());
+ }
+ }
+
+ ChildStorage.push_back(std::move(Child));
+}
diff --git a/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make b/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make
index daa2f8ed3a..348345134a 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/PDB/ya.make
@@ -1,124 +1,124 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
OWNER(
orivej
g:cpp-contrib
)
-
+
LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-PEERDIR(
+PEERDIR(
contrib/libs/llvm12
contrib/libs/llvm12/lib/BinaryFormat
contrib/libs/llvm12/lib/DebugInfo/CodeView
contrib/libs/llvm12/lib/DebugInfo/MSF
contrib/libs/llvm12/lib/Object
contrib/libs/llvm12/lib/Support
-)
-
+)
+
ADDINCL(
contrib/libs/llvm12/lib/DebugInfo/PDB
)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
-SRCS(
- GenericError.cpp
- IPDBSourceFile.cpp
- Native/DbiModuleDescriptor.cpp
- Native/DbiModuleDescriptorBuilder.cpp
- Native/DbiModuleList.cpp
- Native/DbiStream.cpp
- Native/DbiStreamBuilder.cpp
- Native/EnumTables.cpp
- Native/GSIStreamBuilder.cpp
- Native/GlobalsStream.cpp
- Native/Hash.cpp
- Native/HashTable.cpp
- Native/InfoStream.cpp
- Native/InfoStreamBuilder.cpp
- Native/InjectedSourceStream.cpp
- Native/ModuleDebugStream.cpp
- Native/NamedStreamMap.cpp
- Native/NativeCompilandSymbol.cpp
- Native/NativeEnumGlobals.cpp
- Native/NativeEnumInjectedSources.cpp
- Native/NativeEnumLineNumbers.cpp
- Native/NativeEnumModules.cpp
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+SRCS(
+ GenericError.cpp
+ IPDBSourceFile.cpp
+ Native/DbiModuleDescriptor.cpp
+ Native/DbiModuleDescriptorBuilder.cpp
+ Native/DbiModuleList.cpp
+ Native/DbiStream.cpp
+ Native/DbiStreamBuilder.cpp
+ Native/EnumTables.cpp
+ Native/GSIStreamBuilder.cpp
+ Native/GlobalsStream.cpp
+ Native/Hash.cpp
+ Native/HashTable.cpp
+ Native/InfoStream.cpp
+ Native/InfoStreamBuilder.cpp
+ Native/InjectedSourceStream.cpp
+ Native/ModuleDebugStream.cpp
+ Native/NamedStreamMap.cpp
+ Native/NativeCompilandSymbol.cpp
+ Native/NativeEnumGlobals.cpp
+ Native/NativeEnumInjectedSources.cpp
+ Native/NativeEnumLineNumbers.cpp
+ Native/NativeEnumModules.cpp
Native/NativeEnumSymbols.cpp
- Native/NativeEnumTypes.cpp
- Native/NativeExeSymbol.cpp
- Native/NativeFunctionSymbol.cpp
+ Native/NativeEnumTypes.cpp
+ Native/NativeExeSymbol.cpp
+ Native/NativeFunctionSymbol.cpp
Native/NativeInlineSiteSymbol.cpp
- Native/NativeLineNumber.cpp
- Native/NativePublicSymbol.cpp
- Native/NativeRawSymbol.cpp
- Native/NativeSession.cpp
- Native/NativeSourceFile.cpp
- Native/NativeSymbolEnumerator.cpp
- Native/NativeTypeArray.cpp
- Native/NativeTypeBuiltin.cpp
- Native/NativeTypeEnum.cpp
- Native/NativeTypeFunctionSig.cpp
- Native/NativeTypePointer.cpp
- Native/NativeTypeTypedef.cpp
- Native/NativeTypeUDT.cpp
- Native/NativeTypeVTShape.cpp
- Native/PDBFile.cpp
- Native/PDBFileBuilder.cpp
- Native/PDBStringTable.cpp
- Native/PDBStringTableBuilder.cpp
- Native/PublicsStream.cpp
- Native/RawError.cpp
- Native/SymbolCache.cpp
- Native/SymbolStream.cpp
- Native/TpiHashing.cpp
- Native/TpiStream.cpp
- Native/TpiStreamBuilder.cpp
- PDB.cpp
- PDBContext.cpp
- PDBExtras.cpp
- PDBInterfaceAnchors.cpp
- PDBSymDumper.cpp
- PDBSymbol.cpp
- PDBSymbolAnnotation.cpp
- PDBSymbolBlock.cpp
- PDBSymbolCompiland.cpp
- PDBSymbolCompilandDetails.cpp
- PDBSymbolCompilandEnv.cpp
- PDBSymbolCustom.cpp
- PDBSymbolData.cpp
- PDBSymbolExe.cpp
- PDBSymbolFunc.cpp
- PDBSymbolFuncDebugEnd.cpp
- PDBSymbolFuncDebugStart.cpp
- PDBSymbolLabel.cpp
- PDBSymbolPublicSymbol.cpp
- PDBSymbolThunk.cpp
- PDBSymbolTypeArray.cpp
- PDBSymbolTypeBaseClass.cpp
- PDBSymbolTypeBuiltin.cpp
- PDBSymbolTypeCustom.cpp
- PDBSymbolTypeDimension.cpp
- PDBSymbolTypeEnum.cpp
- PDBSymbolTypeFriend.cpp
- PDBSymbolTypeFunctionArg.cpp
- PDBSymbolTypeFunctionSig.cpp
- PDBSymbolTypeManaged.cpp
- PDBSymbolTypePointer.cpp
- PDBSymbolTypeTypedef.cpp
- PDBSymbolTypeUDT.cpp
- PDBSymbolTypeVTable.cpp
- PDBSymbolTypeVTableShape.cpp
- PDBSymbolUnknown.cpp
- PDBSymbolUsingNamespace.cpp
- UDTLayout.cpp
-)
-
-END()
+ Native/NativeLineNumber.cpp
+ Native/NativePublicSymbol.cpp
+ Native/NativeRawSymbol.cpp
+ Native/NativeSession.cpp
+ Native/NativeSourceFile.cpp
+ Native/NativeSymbolEnumerator.cpp
+ Native/NativeTypeArray.cpp
+ Native/NativeTypeBuiltin.cpp
+ Native/NativeTypeEnum.cpp
+ Native/NativeTypeFunctionSig.cpp
+ Native/NativeTypePointer.cpp
+ Native/NativeTypeTypedef.cpp
+ Native/NativeTypeUDT.cpp
+ Native/NativeTypeVTShape.cpp
+ Native/PDBFile.cpp
+ Native/PDBFileBuilder.cpp
+ Native/PDBStringTable.cpp
+ Native/PDBStringTableBuilder.cpp
+ Native/PublicsStream.cpp
+ Native/RawError.cpp
+ Native/SymbolCache.cpp
+ Native/SymbolStream.cpp
+ Native/TpiHashing.cpp
+ Native/TpiStream.cpp
+ Native/TpiStreamBuilder.cpp
+ PDB.cpp
+ PDBContext.cpp
+ PDBExtras.cpp
+ PDBInterfaceAnchors.cpp
+ PDBSymDumper.cpp
+ PDBSymbol.cpp
+ PDBSymbolAnnotation.cpp
+ PDBSymbolBlock.cpp
+ PDBSymbolCompiland.cpp
+ PDBSymbolCompilandDetails.cpp
+ PDBSymbolCompilandEnv.cpp
+ PDBSymbolCustom.cpp
+ PDBSymbolData.cpp
+ PDBSymbolExe.cpp
+ PDBSymbolFunc.cpp
+ PDBSymbolFuncDebugEnd.cpp
+ PDBSymbolFuncDebugStart.cpp
+ PDBSymbolLabel.cpp
+ PDBSymbolPublicSymbol.cpp
+ PDBSymbolThunk.cpp
+ PDBSymbolTypeArray.cpp
+ PDBSymbolTypeBaseClass.cpp
+ PDBSymbolTypeBuiltin.cpp
+ PDBSymbolTypeCustom.cpp
+ PDBSymbolTypeDimension.cpp
+ PDBSymbolTypeEnum.cpp
+ PDBSymbolTypeFriend.cpp
+ PDBSymbolTypeFunctionArg.cpp
+ PDBSymbolTypeFunctionSig.cpp
+ PDBSymbolTypeManaged.cpp
+ PDBSymbolTypePointer.cpp
+ PDBSymbolTypeTypedef.cpp
+ PDBSymbolTypeUDT.cpp
+ PDBSymbolTypeVTable.cpp
+ PDBSymbolTypeVTableShape.cpp
+ PDBSymbolUnknown.cpp
+ PDBSymbolUsingNamespace.cpp
+ UDTLayout.cpp
+)
+
+END()
diff --git a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp
index 01dc31d849..84bf1c177e 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -1,157 +1,157 @@
-//===- lib/DebugInfo/Symbolize/DIPrinter.cpp ------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file defines the DIPrinter class, which is responsible for printing
-// structures defined in DebugInfo/DIContext.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/Symbolize/DIPrinter.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/Support/ErrorOr.h"
-#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>
-#include <cstddef>
-#include <cstdint>
-#include <memory>
-#include <string>
-
-namespace llvm {
-namespace symbolize {
-
-// Prints source code around in the FileName the Line.
-void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
- if (PrintSourceContext <= 0)
- return;
-
- ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
- MemoryBuffer::getFile(FileName);
- if (!BufOrErr)
- return;
-
- std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
- int64_t FirstLine =
- std::max(static_cast<int64_t>(1), Line - PrintSourceContext / 2);
- int64_t LastLine = FirstLine + PrintSourceContext;
- size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
-
- for (line_iterator I = line_iterator(*Buf, false);
- !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
- int64_t L = I.line_number();
- if (L >= FirstLine && L <= LastLine) {
- OS << format_decimal(L, MaxLineNumberWidth);
- if (L == Line)
- OS << " >: ";
- else
- OS << " : ";
- OS << *I << "\n";
- }
- }
-}
-
-void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
- if (PrintFunctionNames) {
- std::string FunctionName = Info.FunctionName;
- if (FunctionName == DILineInfo::BadString)
- FunctionName = DILineInfo::Addr2LineBadString;
-
- StringRef Delimiter = PrintPretty ? " at " : "\n";
- StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
- OS << Prefix << FunctionName << Delimiter;
- }
- std::string Filename = Info.FileName;
- if (Filename == DILineInfo::BadString)
- Filename = DILineInfo::Addr2LineBadString;
- if (!Verbose) {
- OS << Filename << ":" << Info.Line;
- if (Style == OutputStyle::LLVM)
- OS << ":" << Info.Column;
- else if (Style == OutputStyle::GNU && Info.Discriminator != 0)
- OS << " (discriminator " << Info.Discriminator << ")";
- OS << "\n";
- printContext(Filename, Info.Line);
- return;
- }
- OS << " Filename: " << Filename << "\n";
+//===- lib/DebugInfo/Symbolize/DIPrinter.cpp ------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the DIPrinter class, which is responsible for printing
+// structures defined in DebugInfo/DIContext.h
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/Symbolize/DIPrinter.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/Support/ErrorOr.h"
+#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>
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <string>
+
+namespace llvm {
+namespace symbolize {
+
+// Prints source code around in the FileName the Line.
+void DIPrinter::printContext(const std::string &FileName, int64_t Line) {
+ if (PrintSourceContext <= 0)
+ return;
+
+ ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr =
+ MemoryBuffer::getFile(FileName);
+ if (!BufOrErr)
+ return;
+
+ std::unique_ptr<MemoryBuffer> Buf = std::move(BufOrErr.get());
+ int64_t FirstLine =
+ std::max(static_cast<int64_t>(1), Line - PrintSourceContext / 2);
+ int64_t LastLine = FirstLine + PrintSourceContext;
+ size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
+
+ for (line_iterator I = line_iterator(*Buf, false);
+ !I.is_at_eof() && I.line_number() <= LastLine; ++I) {
+ int64_t L = I.line_number();
+ if (L >= FirstLine && L <= LastLine) {
+ OS << format_decimal(L, MaxLineNumberWidth);
+ if (L == Line)
+ OS << " >: ";
+ else
+ OS << " : ";
+ OS << *I << "\n";
+ }
+ }
+}
+
+void DIPrinter::print(const DILineInfo &Info, bool Inlined) {
+ if (PrintFunctionNames) {
+ std::string FunctionName = Info.FunctionName;
+ if (FunctionName == DILineInfo::BadString)
+ FunctionName = DILineInfo::Addr2LineBadString;
+
+ StringRef Delimiter = PrintPretty ? " at " : "\n";
+ StringRef Prefix = (PrintPretty && Inlined) ? " (inlined by) " : "";
+ OS << Prefix << FunctionName << Delimiter;
+ }
+ std::string Filename = Info.FileName;
+ if (Filename == DILineInfo::BadString)
+ Filename = DILineInfo::Addr2LineBadString;
+ if (!Verbose) {
+ OS << Filename << ":" << Info.Line;
+ if (Style == OutputStyle::LLVM)
+ OS << ":" << Info.Column;
+ else if (Style == OutputStyle::GNU && Info.Discriminator != 0)
+ OS << " (discriminator " << Info.Discriminator << ")";
+ OS << "\n";
+ printContext(Filename, Info.Line);
+ return;
+ }
+ OS << " Filename: " << Filename << "\n";
if (Info.StartLine) {
OS << " Function start filename: " << Info.StartFileName << "\n";
OS << " Function start line: " << Info.StartLine << "\n";
}
- OS << " Line: " << Info.Line << "\n";
- OS << " Column: " << Info.Column << "\n";
- if (Info.Discriminator)
- OS << " Discriminator: " << Info.Discriminator << "\n";
-}
-
-DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
- print(Info, false);
- return *this;
-}
-
-DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
- uint32_t FramesNum = Info.getNumberOfFrames();
- if (FramesNum == 0) {
- print(DILineInfo(), false);
- return *this;
- }
- for (uint32_t i = 0; i < FramesNum; i++)
- print(Info.getFrame(i), i > 0);
- return *this;
-}
-
-DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
- std::string Name = Global.Name;
- if (Name == DILineInfo::BadString)
- Name = DILineInfo::Addr2LineBadString;
- OS << Name << "\n";
- OS << Global.Start << " " << Global.Size << "\n";
- return *this;
-}
-
-DIPrinter &DIPrinter::operator<<(const DILocal &Local) {
- if (Local.FunctionName.empty())
- OS << "??\n";
- else
- OS << Local.FunctionName << '\n';
-
- if (Local.Name.empty())
- OS << "??\n";
- else
- 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
+ OS << " Line: " << Info.Line << "\n";
+ OS << " Column: " << Info.Column << "\n";
+ if (Info.Discriminator)
+ OS << " Discriminator: " << Info.Discriminator << "\n";
+}
+
+DIPrinter &DIPrinter::operator<<(const DILineInfo &Info) {
+ print(Info, false);
+ return *this;
+}
+
+DIPrinter &DIPrinter::operator<<(const DIInliningInfo &Info) {
+ uint32_t FramesNum = Info.getNumberOfFrames();
+ if (FramesNum == 0) {
+ print(DILineInfo(), false);
+ return *this;
+ }
+ for (uint32_t i = 0; i < FramesNum; i++)
+ print(Info.getFrame(i), i > 0);
+ return *this;
+}
+
+DIPrinter &DIPrinter::operator<<(const DIGlobal &Global) {
+ std::string Name = Global.Name;
+ if (Name == DILineInfo::BadString)
+ Name = DILineInfo::Addr2LineBadString;
+ OS << Name << "\n";
+ OS << Global.Start << " " << Global.Size << "\n";
+ return *this;
+}
+
+DIPrinter &DIPrinter::operator<<(const DILocal &Local) {
+ if (Local.FunctionName.empty())
+ OS << "??\n";
+ else
+ OS << Local.FunctionName << '\n';
+
+ if (Local.Name.empty())
+ OS << "??\n";
+ else
+ 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/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
index 93d05e4e27..604cd7e393 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.cpp
@@ -1,318 +1,318 @@
-//===- SymbolizableObjectFile.cpp -----------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Implementation of SymbolizableObjectFile class.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SymbolizableObjectFile.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Triple.h"
-#include "llvm/BinaryFormat/COFF.h"
-#include "llvm/DebugInfo/DWARF/DWARFContext.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/SymbolSize.h"
-#include "llvm/Support/Casting.h"
-#include "llvm/Support/DataExtractor.h"
-#include <algorithm>
-
-using namespace llvm;
-using namespace object;
-using namespace symbolize;
-
-Expected<std::unique_ptr<SymbolizableObjectFile>>
-SymbolizableObjectFile::create(const object::ObjectFile *Obj,
- std::unique_ptr<DIContext> DICtx,
- bool UntagAddresses) {
- assert(DICtx);
- std::unique_ptr<SymbolizableObjectFile> res(
- new SymbolizableObjectFile(Obj, std::move(DICtx), UntagAddresses));
- std::unique_ptr<DataExtractor> OpdExtractor;
- uint64_t OpdAddress = 0;
- // Find the .opd (function descriptor) section if any, for big-endian
- // PowerPC64 ELF.
- if (Obj->getArch() == Triple::ppc64) {
- for (section_iterator Section : Obj->sections()) {
- Expected<StringRef> NameOrErr = Section->getName();
- if (!NameOrErr)
- return NameOrErr.takeError();
-
- if (*NameOrErr == ".opd") {
- Expected<StringRef> E = Section->getContents();
- if (!E)
- return E.takeError();
- OpdExtractor.reset(new DataExtractor(*E, Obj->isLittleEndian(),
- Obj->getBytesInAddress()));
- OpdAddress = Section->getAddress();
- break;
- }
- }
- }
- std::vector<std::pair<SymbolRef, uint64_t>> Symbols =
- computeSymbolSizes(*Obj);
- for (auto &P : Symbols)
- if (Error E =
- res->addSymbol(P.first, P.second, OpdExtractor.get(), OpdAddress))
- return std::move(E);
-
- // If this is a COFF object and we didn't find any symbols, try the export
- // table.
- if (Symbols.empty()) {
- if (auto *CoffObj = dyn_cast<COFFObjectFile>(Obj))
- if (Error E = res->addCoffExportSymbols(CoffObj))
- return std::move(E);
- }
-
- 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(const ObjectFile *Obj,
- std::unique_ptr<DIContext> DICtx,
- bool UntagAddresses)
- : Module(Obj), DebugInfoContext(std::move(DICtx)),
- UntagAddresses(UntagAddresses) {}
-
-namespace {
-
-struct OffsetNamePair {
- uint32_t Offset;
- StringRef Name;
-
- bool operator<(const OffsetNamePair &R) const {
- return Offset < R.Offset;
- }
-};
-
-} // end anonymous namespace
-
-Error SymbolizableObjectFile::addCoffExportSymbols(
- const COFFObjectFile *CoffObj) {
- // Get all export names and offsets.
- std::vector<OffsetNamePair> ExportSyms;
- for (const ExportDirectoryEntryRef &Ref : CoffObj->export_directories()) {
- StringRef Name;
- uint32_t Offset;
- if (auto EC = Ref.getSymbolName(Name))
- return EC;
- if (auto EC = Ref.getExportRVA(Offset))
- return EC;
- ExportSyms.push_back(OffsetNamePair{Offset, Name});
- }
- if (ExportSyms.empty())
- return Error::success();
-
- // Sort by ascending offset.
- array_pod_sort(ExportSyms.begin(), ExportSyms.end());
-
- // Approximate the symbol sizes by assuming they run to the next symbol.
- // FIXME: This assumes all exports are functions.
- uint64_t ImageBase = CoffObj->getImageBase();
- for (auto I = ExportSyms.begin(), E = ExportSyms.end(); I != E; ++I) {
- OffsetNamePair &Export = *I;
- // FIXME: The last export has a one byte size now.
- uint32_t NextOffset = I != E ? I->Offset : Export.Offset + 1;
- uint64_t SymbolStart = ImageBase + Export.Offset;
- uint64_t SymbolSize = NextOffset - Export.Offset;
- SymbolDesc SD = {SymbolStart, SymbolSize};
- Functions.emplace_back(SD, Export.Name);
- }
- return Error::success();
-}
-
-Error 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 Error::success();
- Expected<SymbolRef::Type> SymbolTypeOrErr = Symbol.getType();
- if (!SymbolTypeOrErr)
- return SymbolTypeOrErr.takeError();
- SymbolRef::Type SymbolType = *SymbolTypeOrErr;
- if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data)
- return Error::success();
- Expected<uint64_t> SymbolAddressOrErr = Symbol.getAddress();
- if (!SymbolAddressOrErr)
- return SymbolAddressOrErr.takeError();
- uint64_t SymbolAddress = *SymbolAddressOrErr;
- if (UntagAddresses) {
- // For kernel addresses, bits 56-63 need to be set, so we sign extend bit 55
- // into bits 56-63 instead of masking them out.
- SymbolAddress &= (1ull << 56) - 1;
- SymbolAddress = (int64_t(SymbolAddress) << 8) >> 8;
- }
- if (OpdExtractor) {
- // For big-endian PowerPC64 ELF, symbols in the .opd section refer to
- // function descriptors. The first word of the descriptor is a pointer to
- // the function's code.
- // For the purposes of symbolization, pretend the symbol's address is that
- // of the function's code, not the descriptor.
- uint64_t OpdOffset = SymbolAddress - OpdAddress;
- if (OpdExtractor->isValidOffsetForAddress(OpdOffset))
- SymbolAddress = OpdExtractor->getAddress(&OpdOffset);
- }
- Expected<StringRef> SymbolNameOrErr = Symbol.getName();
- if (!SymbolNameOrErr)
- return SymbolNameOrErr.takeError();
- StringRef SymbolName = *SymbolNameOrErr;
- // Mach-O symbol table names have leading underscore, skip it.
- if (Module->isMachO() && !SymbolName.empty() && SymbolName[0] == '_')
- SymbolName = SymbolName.drop_front();
- // FIXME: If a function has alias, there are two entries in symbol table
- // with same address size. Make sure we choose the correct one.
- auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
- SymbolDesc SD = { SymbolAddress, SymbolSize };
- M.emplace_back(SD, SymbolName);
- return Error::success();
-}
-
-// Return true if this is a 32-bit x86 PE COFF module.
-bool SymbolizableObjectFile::isWin32Module() const {
- auto *CoffObject = dyn_cast<COFFObjectFile>(Module);
- return CoffObject && CoffObject->getMachine() == COFF::IMAGE_FILE_MACHINE_I386;
-}
-
-uint64_t SymbolizableObjectFile::getModulePreferredBase() const {
- if (auto *CoffObject = dyn_cast<COFFObjectFile>(Module))
- return CoffObject->getImageBase();
- return 0;
-}
-
-bool SymbolizableObjectFile::getNameFromSymbolTable(SymbolRef::Type Type,
- uint64_t Address,
- std::string &Name,
- uint64_t &Addr,
- uint64_t &Size) const {
- 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 &&
- SymbolIterator->first.Addr + SymbolIterator->first.Size <= Address)
- return false;
- Name = SymbolIterator->second.str();
- Addr = SymbolIterator->first.Addr;
- Size = SymbolIterator->first.Size;
- return true;
-}
-
-bool SymbolizableObjectFile::shouldOverrideWithSymbolTable(
- FunctionNameKind FNKind, bool UseSymbolTable) const {
- // When DWARF is used with -gline-tables-only / -gmlt, the symbol table gives
- // better answers for linkage names than the DIContext. Otherwise, we are
- // probably using PEs and PDBs, and we shouldn't do the override. PE files
- // generally only contain the names of exported symbols.
- return FNKind == FunctionNameKind::LinkageName && UseSymbolTable &&
- isa<DWARFContext>(DebugInfoContext.get());
-}
-
-DILineInfo
-SymbolizableObjectFile::symbolizeCode(object::SectionedAddress ModuleOffset,
- DILineInfoSpecifier LineInfoSpecifier,
- bool UseSymbolTable) const {
- if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection)
- ModuleOffset.SectionIndex =
- getModuleSectionIndexForAddress(ModuleOffset.Address);
- DILineInfo LineInfo =
- DebugInfoContext->getLineInfoForAddress(ModuleOffset, LineInfoSpecifier);
-
- // Override function name from symbol table if necessary.
- if (shouldOverrideWithSymbolTable(LineInfoSpecifier.FNKind, UseSymbolTable)) {
- std::string FunctionName;
- uint64_t Start, Size;
- if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address,
- FunctionName, Start, Size)) {
- LineInfo.FunctionName = FunctionName;
- }
- }
- return LineInfo;
-}
-
-DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
- object::SectionedAddress ModuleOffset,
- DILineInfoSpecifier LineInfoSpecifier, bool UseSymbolTable) const {
- if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection)
- ModuleOffset.SectionIndex =
- getModuleSectionIndexForAddress(ModuleOffset.Address);
- DIInliningInfo InlinedContext = DebugInfoContext->getInliningInfoForAddress(
- ModuleOffset, LineInfoSpecifier);
-
- // Make sure there is at least one frame in context.
- if (InlinedContext.getNumberOfFrames() == 0)
- InlinedContext.addFrame(DILineInfo());
-
- // Override the function name in lower frame with name from symbol table.
- if (shouldOverrideWithSymbolTable(LineInfoSpecifier.FNKind, UseSymbolTable)) {
- std::string FunctionName;
- uint64_t Start, Size;
- if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address,
- FunctionName, Start, Size)) {
- InlinedContext.getMutableFrame(InlinedContext.getNumberOfFrames() - 1)
- ->FunctionName = FunctionName;
- }
- }
-
- return InlinedContext;
-}
-
-DIGlobal SymbolizableObjectFile::symbolizeData(
- object::SectionedAddress ModuleOffset) const {
- DIGlobal Res;
- 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;
-}
+//===- SymbolizableObjectFile.cpp -----------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of SymbolizableObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolizableObjectFile.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/BinaryFormat/COFF.h"
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/SymbolSize.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/DataExtractor.h"
+#include <algorithm>
+
+using namespace llvm;
+using namespace object;
+using namespace symbolize;
+
+Expected<std::unique_ptr<SymbolizableObjectFile>>
+SymbolizableObjectFile::create(const object::ObjectFile *Obj,
+ std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses) {
+ assert(DICtx);
+ std::unique_ptr<SymbolizableObjectFile> res(
+ new SymbolizableObjectFile(Obj, std::move(DICtx), UntagAddresses));
+ std::unique_ptr<DataExtractor> OpdExtractor;
+ uint64_t OpdAddress = 0;
+ // Find the .opd (function descriptor) section if any, for big-endian
+ // PowerPC64 ELF.
+ if (Obj->getArch() == Triple::ppc64) {
+ for (section_iterator Section : Obj->sections()) {
+ Expected<StringRef> NameOrErr = Section->getName();
+ if (!NameOrErr)
+ return NameOrErr.takeError();
+
+ if (*NameOrErr == ".opd") {
+ Expected<StringRef> E = Section->getContents();
+ if (!E)
+ return E.takeError();
+ OpdExtractor.reset(new DataExtractor(*E, Obj->isLittleEndian(),
+ Obj->getBytesInAddress()));
+ OpdAddress = Section->getAddress();
+ break;
+ }
+ }
+ }
+ std::vector<std::pair<SymbolRef, uint64_t>> Symbols =
+ computeSymbolSizes(*Obj);
+ for (auto &P : Symbols)
+ if (Error E =
+ res->addSymbol(P.first, P.second, OpdExtractor.get(), OpdAddress))
+ return std::move(E);
+
+ // If this is a COFF object and we didn't find any symbols, try the export
+ // table.
+ if (Symbols.empty()) {
+ if (auto *CoffObj = dyn_cast<COFFObjectFile>(Obj))
+ if (Error E = res->addCoffExportSymbols(CoffObj))
+ return std::move(E);
+ }
+
+ 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(const ObjectFile *Obj,
+ std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses)
+ : Module(Obj), DebugInfoContext(std::move(DICtx)),
+ UntagAddresses(UntagAddresses) {}
+
+namespace {
+
+struct OffsetNamePair {
+ uint32_t Offset;
+ StringRef Name;
+
+ bool operator<(const OffsetNamePair &R) const {
+ return Offset < R.Offset;
+ }
+};
+
+} // end anonymous namespace
+
+Error SymbolizableObjectFile::addCoffExportSymbols(
+ const COFFObjectFile *CoffObj) {
+ // Get all export names and offsets.
+ std::vector<OffsetNamePair> ExportSyms;
+ for (const ExportDirectoryEntryRef &Ref : CoffObj->export_directories()) {
+ StringRef Name;
+ uint32_t Offset;
+ if (auto EC = Ref.getSymbolName(Name))
+ return EC;
+ if (auto EC = Ref.getExportRVA(Offset))
+ return EC;
+ ExportSyms.push_back(OffsetNamePair{Offset, Name});
+ }
+ if (ExportSyms.empty())
+ return Error::success();
+
+ // Sort by ascending offset.
+ array_pod_sort(ExportSyms.begin(), ExportSyms.end());
+
+ // Approximate the symbol sizes by assuming they run to the next symbol.
+ // FIXME: This assumes all exports are functions.
+ uint64_t ImageBase = CoffObj->getImageBase();
+ for (auto I = ExportSyms.begin(), E = ExportSyms.end(); I != E; ++I) {
+ OffsetNamePair &Export = *I;
+ // FIXME: The last export has a one byte size now.
+ uint32_t NextOffset = I != E ? I->Offset : Export.Offset + 1;
+ uint64_t SymbolStart = ImageBase + Export.Offset;
+ uint64_t SymbolSize = NextOffset - Export.Offset;
+ SymbolDesc SD = {SymbolStart, SymbolSize};
+ Functions.emplace_back(SD, Export.Name);
+ }
+ return Error::success();
+}
+
+Error 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 Error::success();
+ Expected<SymbolRef::Type> SymbolTypeOrErr = Symbol.getType();
+ if (!SymbolTypeOrErr)
+ return SymbolTypeOrErr.takeError();
+ SymbolRef::Type SymbolType = *SymbolTypeOrErr;
+ if (SymbolType != SymbolRef::ST_Function && SymbolType != SymbolRef::ST_Data)
+ return Error::success();
+ Expected<uint64_t> SymbolAddressOrErr = Symbol.getAddress();
+ if (!SymbolAddressOrErr)
+ return SymbolAddressOrErr.takeError();
+ uint64_t SymbolAddress = *SymbolAddressOrErr;
+ if (UntagAddresses) {
+ // For kernel addresses, bits 56-63 need to be set, so we sign extend bit 55
+ // into bits 56-63 instead of masking them out.
+ SymbolAddress &= (1ull << 56) - 1;
+ SymbolAddress = (int64_t(SymbolAddress) << 8) >> 8;
+ }
+ if (OpdExtractor) {
+ // For big-endian PowerPC64 ELF, symbols in the .opd section refer to
+ // function descriptors. The first word of the descriptor is a pointer to
+ // the function's code.
+ // For the purposes of symbolization, pretend the symbol's address is that
+ // of the function's code, not the descriptor.
+ uint64_t OpdOffset = SymbolAddress - OpdAddress;
+ if (OpdExtractor->isValidOffsetForAddress(OpdOffset))
+ SymbolAddress = OpdExtractor->getAddress(&OpdOffset);
+ }
+ Expected<StringRef> SymbolNameOrErr = Symbol.getName();
+ if (!SymbolNameOrErr)
+ return SymbolNameOrErr.takeError();
+ StringRef SymbolName = *SymbolNameOrErr;
+ // Mach-O symbol table names have leading underscore, skip it.
+ if (Module->isMachO() && !SymbolName.empty() && SymbolName[0] == '_')
+ SymbolName = SymbolName.drop_front();
+ // FIXME: If a function has alias, there are two entries in symbol table
+ // with same address size. Make sure we choose the correct one.
+ auto &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects;
+ SymbolDesc SD = { SymbolAddress, SymbolSize };
+ M.emplace_back(SD, SymbolName);
+ return Error::success();
+}
+
+// Return true if this is a 32-bit x86 PE COFF module.
+bool SymbolizableObjectFile::isWin32Module() const {
+ auto *CoffObject = dyn_cast<COFFObjectFile>(Module);
+ return CoffObject && CoffObject->getMachine() == COFF::IMAGE_FILE_MACHINE_I386;
+}
+
+uint64_t SymbolizableObjectFile::getModulePreferredBase() const {
+ if (auto *CoffObject = dyn_cast<COFFObjectFile>(Module))
+ return CoffObject->getImageBase();
+ return 0;
+}
+
+bool SymbolizableObjectFile::getNameFromSymbolTable(SymbolRef::Type Type,
+ uint64_t Address,
+ std::string &Name,
+ uint64_t &Addr,
+ uint64_t &Size) const {
+ 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 &&
+ SymbolIterator->first.Addr + SymbolIterator->first.Size <= Address)
+ return false;
+ Name = SymbolIterator->second.str();
+ Addr = SymbolIterator->first.Addr;
+ Size = SymbolIterator->first.Size;
+ return true;
+}
+
+bool SymbolizableObjectFile::shouldOverrideWithSymbolTable(
+ FunctionNameKind FNKind, bool UseSymbolTable) const {
+ // When DWARF is used with -gline-tables-only / -gmlt, the symbol table gives
+ // better answers for linkage names than the DIContext. Otherwise, we are
+ // probably using PEs and PDBs, and we shouldn't do the override. PE files
+ // generally only contain the names of exported symbols.
+ return FNKind == FunctionNameKind::LinkageName && UseSymbolTable &&
+ isa<DWARFContext>(DebugInfoContext.get());
+}
+
+DILineInfo
+SymbolizableObjectFile::symbolizeCode(object::SectionedAddress ModuleOffset,
+ DILineInfoSpecifier LineInfoSpecifier,
+ bool UseSymbolTable) const {
+ if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection)
+ ModuleOffset.SectionIndex =
+ getModuleSectionIndexForAddress(ModuleOffset.Address);
+ DILineInfo LineInfo =
+ DebugInfoContext->getLineInfoForAddress(ModuleOffset, LineInfoSpecifier);
+
+ // Override function name from symbol table if necessary.
+ if (shouldOverrideWithSymbolTable(LineInfoSpecifier.FNKind, UseSymbolTable)) {
+ std::string FunctionName;
+ uint64_t Start, Size;
+ if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address,
+ FunctionName, Start, Size)) {
+ LineInfo.FunctionName = FunctionName;
+ }
+ }
+ return LineInfo;
+}
+
+DIInliningInfo SymbolizableObjectFile::symbolizeInlinedCode(
+ object::SectionedAddress ModuleOffset,
+ DILineInfoSpecifier LineInfoSpecifier, bool UseSymbolTable) const {
+ if (ModuleOffset.SectionIndex == object::SectionedAddress::UndefSection)
+ ModuleOffset.SectionIndex =
+ getModuleSectionIndexForAddress(ModuleOffset.Address);
+ DIInliningInfo InlinedContext = DebugInfoContext->getInliningInfoForAddress(
+ ModuleOffset, LineInfoSpecifier);
+
+ // Make sure there is at least one frame in context.
+ if (InlinedContext.getNumberOfFrames() == 0)
+ InlinedContext.addFrame(DILineInfo());
+
+ // Override the function name in lower frame with name from symbol table.
+ if (shouldOverrideWithSymbolTable(LineInfoSpecifier.FNKind, UseSymbolTable)) {
+ std::string FunctionName;
+ uint64_t Start, Size;
+ if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset.Address,
+ FunctionName, Start, Size)) {
+ InlinedContext.getMutableFrame(InlinedContext.getNumberOfFrames() - 1)
+ ->FunctionName = FunctionName;
+ }
+ }
+
+ return InlinedContext;
+}
+
+DIGlobal SymbolizableObjectFile::symbolizeData(
+ object::SectionedAddress ModuleOffset) const {
+ DIGlobal Res;
+ 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/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
index be3c66df05..cdab521100 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/SymbolizableObjectFile.h
@@ -1,97 +1,97 @@
-//===- SymbolizableObjectFile.h ---------------------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file declares the SymbolizableObjectFile class.
-//
-//===----------------------------------------------------------------------===//
-#ifndef LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
-#define LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/DebugInfo/DIContext.h"
-#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
+//===- SymbolizableObjectFile.h ---------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file declares the SymbolizableObjectFile class.
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
+#define LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/DebugInfo/Symbolize/SymbolizableModule.h"
#include "llvm/Support/Error.h"
-#include <cstdint>
-#include <memory>
-#include <string>
+#include <cstdint>
+#include <memory>
+#include <string>
#include <utility>
#include <vector>
-
-namespace llvm {
-
-class DataExtractor;
-
-namespace symbolize {
-
-class SymbolizableObjectFile : public SymbolizableModule {
-public:
- static Expected<std::unique_ptr<SymbolizableObjectFile>>
- create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx,
- bool UntagAddresses);
-
- DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
- DILineInfoSpecifier LineInfoSpecifier,
- bool UseSymbolTable) const override;
- DIInliningInfo symbolizeInlinedCode(object::SectionedAddress ModuleOffset,
- DILineInfoSpecifier LineInfoSpecifier,
- bool UseSymbolTable) 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;
-
- // Returns the preferred base of the module, i.e. where the loader would place
- // it in memory assuming there were no conflicts.
- uint64_t getModulePreferredBase() const override;
-
-private:
- bool shouldOverrideWithSymbolTable(FunctionNameKind FNKind,
- bool UseSymbolTable) const;
-
- bool getNameFromSymbolTable(object::SymbolRef::Type Type, uint64_t Address,
- std::string &Name, uint64_t &Addr,
- uint64_t &Size) const;
- // For big-endian PowerPC64 ELF, OpdAddress is the address of the .opd
- // (function descriptor) section and OpdExtractor refers to its contents.
- Error addSymbol(const object::SymbolRef &Symbol, uint64_t SymbolSize,
- DataExtractor *OpdExtractor = nullptr,
- uint64_t OpdAddress = 0);
- Error addCoffExportSymbols(const object::COFFObjectFile *CoffObj);
-
- /// 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;
- bool UntagAddresses;
-
- struct SymbolDesc {
- uint64_t Addr;
- // If size is 0, assume that symbol occupies the whole memory range up to
- // the following symbol.
- uint64_t Size;
-
- bool operator<(const SymbolDesc &RHS) const {
- return Addr != RHS.Addr ? Addr < RHS.Addr : Size < RHS.Size;
- }
- };
- std::vector<std::pair<SymbolDesc, StringRef>> Functions;
- std::vector<std::pair<SymbolDesc, StringRef>> Objects;
-
- SymbolizableObjectFile(const object::ObjectFile *Obj,
- std::unique_ptr<DIContext> DICtx,
- bool UntagAddresses);
-};
-
-} // end namespace symbolize
-
-} // end namespace llvm
-
-#endif // LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
+
+namespace llvm {
+
+class DataExtractor;
+
+namespace symbolize {
+
+class SymbolizableObjectFile : public SymbolizableModule {
+public:
+ static Expected<std::unique_ptr<SymbolizableObjectFile>>
+ create(const object::ObjectFile *Obj, std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses);
+
+ DILineInfo symbolizeCode(object::SectionedAddress ModuleOffset,
+ DILineInfoSpecifier LineInfoSpecifier,
+ bool UseSymbolTable) const override;
+ DIInliningInfo symbolizeInlinedCode(object::SectionedAddress ModuleOffset,
+ DILineInfoSpecifier LineInfoSpecifier,
+ bool UseSymbolTable) 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;
+
+ // Returns the preferred base of the module, i.e. where the loader would place
+ // it in memory assuming there were no conflicts.
+ uint64_t getModulePreferredBase() const override;
+
+private:
+ bool shouldOverrideWithSymbolTable(FunctionNameKind FNKind,
+ bool UseSymbolTable) const;
+
+ bool getNameFromSymbolTable(object::SymbolRef::Type Type, uint64_t Address,
+ std::string &Name, uint64_t &Addr,
+ uint64_t &Size) const;
+ // For big-endian PowerPC64 ELF, OpdAddress is the address of the .opd
+ // (function descriptor) section and OpdExtractor refers to its contents.
+ Error addSymbol(const object::SymbolRef &Symbol, uint64_t SymbolSize,
+ DataExtractor *OpdExtractor = nullptr,
+ uint64_t OpdAddress = 0);
+ Error addCoffExportSymbols(const object::COFFObjectFile *CoffObj);
+
+ /// 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;
+ bool UntagAddresses;
+
+ struct SymbolDesc {
+ uint64_t Addr;
+ // If size is 0, assume that symbol occupies the whole memory range up to
+ // the following symbol.
+ uint64_t Size;
+
+ bool operator<(const SymbolDesc &RHS) const {
+ return Addr != RHS.Addr ? Addr < RHS.Addr : Size < RHS.Size;
+ }
+ };
+ std::vector<std::pair<SymbolDesc, StringRef>> Functions;
+ std::vector<std::pair<SymbolDesc, StringRef>> Objects;
+
+ SymbolizableObjectFile(const object::ObjectFile *Obj,
+ std::unique_ptr<DIContext> DICtx,
+ bool UntagAddresses);
+};
+
+} // end namespace symbolize
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_DEBUGINFO_SYMBOLIZE_SYMBOLIZABLEOBJECTFILE_H
diff --git a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp
index da157a5a25..6142d0ed38 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/Symbolize.cpp
@@ -1,640 +1,640 @@
-//===-- LLVMSymbolize.cpp -------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// Implementation for LLVM symbolization library.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/DebugInfo/Symbolize/Symbolize.h"
-
-#include "SymbolizableObjectFile.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/BinaryFormat/COFF.h"
+//===-- LLVMSymbolize.cpp -------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation for LLVM symbolization library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/DebugInfo/Symbolize/Symbolize.h"
+
+#include "SymbolizableObjectFile.h"
+
+#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"
-#include "llvm/Demangle/Demangle.h"
-#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"
-#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Path.h"
-#include <algorithm>
-#include <cassert>
-#include <cstring>
-
-namespace llvm {
-namespace symbolize {
-
-Expected<DILineInfo>
-LLVMSymbolizer::symbolizeCodeCommon(SymbolizableModule *Info,
- object::SectionedAddress ModuleOffset) {
- // A null module means an error has already been reported. Return an empty
- // result.
- if (!Info)
- return DILineInfo();
-
- // 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();
-
- DILineInfo LineInfo = Info->symbolizeCode(
- ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions),
- Opts.UseSymbolTable);
- if (Opts.Demangle)
- LineInfo.FunctionName = DemangleName(LineInfo.FunctionName, Info);
- 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);
- 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,
- 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 DIInliningInfo();
-
- // 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();
-
- DIInliningInfo InlinedContext = Info->symbolizeInlinedCode(
- ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions),
- Opts.UseSymbolTable);
- if (Opts.Demangle) {
- for (int i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
- auto *Frame = InlinedContext.getMutableFrame(i);
- Frame->FunctionName = DemangleName(Frame->FunctionName, Info);
- }
- }
- return InlinedContext;
-}
-
-Expected<DIGlobal>
-LLVMSymbolizer::symbolizeData(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 DIGlobal();
-
- // 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();
-
- DIGlobal Global = Info->symbolizeData(ModuleOffset);
- if (Opts.Demangle)
- Global.Name = DemangleName(Global.Name, Info);
- 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();
- ObjectPairForPathArch.clear();
- Modules.clear();
-}
-
-namespace {
-
-// For Path="/path/to/foo" and Basename="foo" assume that debug info is in
-// /path/to/foo.dSYM/Contents/Resources/DWARF/foo.
-// For Path="/path/to/bar.dSYM" and Basename="foo" assume that debug info is in
-// /path/to/bar.dSYM/Contents/Resources/DWARF/foo.
-std::string getDarwinDWARFResourceForPath(
- const std::string &Path, const std::string &Basename) {
- SmallString<16> ResourceName = StringRef(Path);
- if (sys::path::extension(Path) != ".dSYM") {
- ResourceName += ".dSYM";
- }
- sys::path::append(ResourceName, "Contents", "Resources", "DWARF");
- sys::path::append(ResourceName, Basename);
- return std::string(ResourceName.str());
-}
-
-bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFileOrSTDIN(Path);
- if (!MB)
- return false;
- return CRCHash == llvm::crc32(arrayRefFromStringRef(MB.get()->getBuffer()));
-}
-
-bool findDebugBinary(const std::string &OrigPath,
- const std::string &DebuglinkName, uint32_t CRCHash,
- const std::string &FallbackDebugPath,
- std::string &Result) {
- SmallString<16> OrigDir(OrigPath);
- llvm::sys::path::remove_filename(OrigDir);
- SmallString<16> DebugPath = OrigDir;
- // Try relative/path/to/original_binary/debuglink_name
- llvm::sys::path::append(DebugPath, DebuglinkName);
- if (checkFileCRC(DebugPath, CRCHash)) {
- Result = std::string(DebugPath.str());
- return true;
- }
- // Try relative/path/to/original_binary/.debug/debuglink_name
- DebugPath = OrigDir;
- llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
- if (checkFileCRC(DebugPath, CRCHash)) {
- Result = std::string(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/absolute/path/to/original_binary/debuglink_name
- DebugPath = "/usr/libdata/debug";
-#else
- // 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)) {
- Result = std::string(DebugPath.str());
- return true;
- }
- return false;
-}
-
-bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName,
- uint32_t &CRCHash) {
- if (!Obj)
- return false;
- for (const SectionRef &Section : Obj->sections()) {
- StringRef Name;
- if (Expected<StringRef> NameOrErr = Section.getName())
- Name = *NameOrErr;
- else
- consumeError(NameOrErr.takeError());
-
- Name = Name.substr(Name.find_first_not_of("._"));
- if (Name == "gnu_debuglink") {
- Expected<StringRef> ContentsOrErr = Section.getContents();
- if (!ContentsOrErr) {
- consumeError(ContentsOrErr.takeError());
- return false;
- }
- DataExtractor DE(*ContentsOrErr, Obj->isLittleEndian(), 0);
- uint64_t Offset = 0;
- if (const char *DebugNameStr = DE.getCStr(&Offset)) {
- // 4-byte align the offset.
- Offset = (Offset + 3) & ~0x3;
- if (DE.isValidOffsetForDataOfSize(Offset, 4)) {
- DebugName = DebugNameStr;
- CRCHash = DE.getU32(&Offset);
- return true;
- }
- }
- break;
- }
- }
- return false;
-}
-
-bool darwinDsymMatchesBinary(const MachOObjectFile *DbgObj,
- const MachOObjectFile *Obj) {
- ArrayRef<uint8_t> dbg_uuid = DbgObj->getUuid();
- ArrayRef<uint8_t> bin_uuid = Obj->getUuid();
- if (dbg_uuid.empty() || bin_uuid.empty())
- return false;
- return !memcmp(dbg_uuid.data(), bin_uuid.data(), dbg_uuid.size());
-}
-
-template <typename ELFT>
+#include "llvm/DebugInfo/DWARF/DWARFContext.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
+#include "llvm/DebugInfo/PDB/PDBContext.h"
+#include "llvm/Demangle/Demangle.h"
+#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"
+#include "llvm/Support/Errc.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include <algorithm>
+#include <cassert>
+#include <cstring>
+
+namespace llvm {
+namespace symbolize {
+
+Expected<DILineInfo>
+LLVMSymbolizer::symbolizeCodeCommon(SymbolizableModule *Info,
+ object::SectionedAddress ModuleOffset) {
+ // A null module means an error has already been reported. Return an empty
+ // result.
+ if (!Info)
+ return DILineInfo();
+
+ // 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();
+
+ DILineInfo LineInfo = Info->symbolizeCode(
+ ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions),
+ Opts.UseSymbolTable);
+ if (Opts.Demangle)
+ LineInfo.FunctionName = DemangleName(LineInfo.FunctionName, Info);
+ 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);
+ 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,
+ 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 DIInliningInfo();
+
+ // 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();
+
+ DIInliningInfo InlinedContext = Info->symbolizeInlinedCode(
+ ModuleOffset, DILineInfoSpecifier(Opts.PathStyle, Opts.PrintFunctions),
+ Opts.UseSymbolTable);
+ if (Opts.Demangle) {
+ for (int i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
+ auto *Frame = InlinedContext.getMutableFrame(i);
+ Frame->FunctionName = DemangleName(Frame->FunctionName, Info);
+ }
+ }
+ return InlinedContext;
+}
+
+Expected<DIGlobal>
+LLVMSymbolizer::symbolizeData(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 DIGlobal();
+
+ // 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();
+
+ DIGlobal Global = Info->symbolizeData(ModuleOffset);
+ if (Opts.Demangle)
+ Global.Name = DemangleName(Global.Name, Info);
+ 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();
+ ObjectPairForPathArch.clear();
+ Modules.clear();
+}
+
+namespace {
+
+// For Path="/path/to/foo" and Basename="foo" assume that debug info is in
+// /path/to/foo.dSYM/Contents/Resources/DWARF/foo.
+// For Path="/path/to/bar.dSYM" and Basename="foo" assume that debug info is in
+// /path/to/bar.dSYM/Contents/Resources/DWARF/foo.
+std::string getDarwinDWARFResourceForPath(
+ const std::string &Path, const std::string &Basename) {
+ SmallString<16> ResourceName = StringRef(Path);
+ if (sys::path::extension(Path) != ".dSYM") {
+ ResourceName += ".dSYM";
+ }
+ sys::path::append(ResourceName, "Contents", "Resources", "DWARF");
+ sys::path::append(ResourceName, Basename);
+ return std::string(ResourceName.str());
+}
+
+bool checkFileCRC(StringRef Path, uint32_t CRCHash) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
+ MemoryBuffer::getFileOrSTDIN(Path);
+ if (!MB)
+ return false;
+ return CRCHash == llvm::crc32(arrayRefFromStringRef(MB.get()->getBuffer()));
+}
+
+bool findDebugBinary(const std::string &OrigPath,
+ const std::string &DebuglinkName, uint32_t CRCHash,
+ const std::string &FallbackDebugPath,
+ std::string &Result) {
+ SmallString<16> OrigDir(OrigPath);
+ llvm::sys::path::remove_filename(OrigDir);
+ SmallString<16> DebugPath = OrigDir;
+ // Try relative/path/to/original_binary/debuglink_name
+ llvm::sys::path::append(DebugPath, DebuglinkName);
+ if (checkFileCRC(DebugPath, CRCHash)) {
+ Result = std::string(DebugPath.str());
+ return true;
+ }
+ // Try relative/path/to/original_binary/.debug/debuglink_name
+ DebugPath = OrigDir;
+ llvm::sys::path::append(DebugPath, ".debug", DebuglinkName);
+ if (checkFileCRC(DebugPath, CRCHash)) {
+ Result = std::string(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/absolute/path/to/original_binary/debuglink_name
+ DebugPath = "/usr/libdata/debug";
+#else
+ // 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)) {
+ Result = std::string(DebugPath.str());
+ return true;
+ }
+ return false;
+}
+
+bool getGNUDebuglinkContents(const ObjectFile *Obj, std::string &DebugName,
+ uint32_t &CRCHash) {
+ if (!Obj)
+ return false;
+ for (const SectionRef &Section : Obj->sections()) {
+ StringRef Name;
+ if (Expected<StringRef> NameOrErr = Section.getName())
+ Name = *NameOrErr;
+ else
+ consumeError(NameOrErr.takeError());
+
+ Name = Name.substr(Name.find_first_not_of("._"));
+ if (Name == "gnu_debuglink") {
+ Expected<StringRef> ContentsOrErr = Section.getContents();
+ if (!ContentsOrErr) {
+ consumeError(ContentsOrErr.takeError());
+ return false;
+ }
+ DataExtractor DE(*ContentsOrErr, Obj->isLittleEndian(), 0);
+ uint64_t Offset = 0;
+ if (const char *DebugNameStr = DE.getCStr(&Offset)) {
+ // 4-byte align the offset.
+ Offset = (Offset + 3) & ~0x3;
+ if (DE.isValidOffsetForDataOfSize(Offset, 4)) {
+ DebugName = DebugNameStr;
+ CRCHash = DE.getU32(&Offset);
+ return true;
+ }
+ }
+ break;
+ }
+ }
+ return false;
+}
+
+bool darwinDsymMatchesBinary(const MachOObjectFile *DbgObj,
+ const MachOObjectFile *Obj) {
+ ArrayRef<uint8_t> dbg_uuid = DbgObj->getUuid();
+ ArrayRef<uint8_t> bin_uuid = Obj->getUuid();
+ if (dbg_uuid.empty() || bin_uuid.empty())
+ return false;
+ return !memcmp(dbg_uuid.data(), bin_uuid.data(), dbg_uuid.size());
+}
+
+template <typename ELFT>
Optional<ArrayRef<uint8_t>> getBuildID(const ELFFile<ELFT> &Obj) {
auto PhdrsOrErr = Obj.program_headers();
- if (!PhdrsOrErr) {
- consumeError(PhdrsOrErr.takeError());
- return {};
- }
- for (const auto &P : *PhdrsOrErr) {
- if (P.p_type != ELF::PT_NOTE)
- continue;
- Error Err = Error::success();
+ if (!PhdrsOrErr) {
+ consumeError(PhdrsOrErr.takeError());
+ return {};
+ }
+ for (const auto &P : *PhdrsOrErr) {
+ if (P.p_type != ELF::PT_NOTE)
+ continue;
+ Error Err = Error::success();
for (auto N : Obj.notes(P, Err))
- if (N.getType() == ELF::NT_GNU_BUILD_ID && N.getName() == ELF::ELF_NOTE_GNU)
- return N.getDesc();
- consumeError(std::move(Err));
- }
- return {};
-}
-
-Optional<ArrayRef<uint8_t>> getBuildID(const ELFObjectFileBase *Obj) {
- Optional<ArrayRef<uint8_t>> BuildID;
- if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Obj))
- BuildID = getBuildID(O->getELFFile());
- else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Obj))
- BuildID = getBuildID(O->getELFFile());
- else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Obj))
- BuildID = getBuildID(O->getELFFile());
- else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))
- BuildID = getBuildID(O->getELFFile());
- else
- llvm_unreachable("unsupported file format");
- return BuildID;
-}
-
-bool findDebugBinary(const std::vector<std::string> &DebugFileDirectory,
- const ArrayRef<uint8_t> BuildID,
- std::string &Result) {
- auto getDebugPath = [&](StringRef Directory) {
- SmallString<128> Path{Directory};
- sys::path::append(Path, ".build-id",
- llvm::toHex(BuildID[0], /*LowerCase=*/true),
- llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));
- Path += ".debug";
- return Path;
- };
- if (DebugFileDirectory.empty()) {
- SmallString<128> Path = getDebugPath(
-#if defined(__NetBSD__)
- // Try /usr/libdata/debug/.build-id/../...
- "/usr/libdata/debug"
-#else
- // Try /usr/lib/debug/.build-id/../...
- "/usr/lib/debug"
-#endif
- );
- if (llvm::sys::fs::exists(Path)) {
- Result = std::string(Path.str());
- return true;
- }
- } else {
- for (const auto &Directory : DebugFileDirectory) {
- // Try <debug-file-directory>/.build-id/../...
- SmallString<128> Path = getDebugPath(Directory);
- if (llvm::sys::fs::exists(Path)) {
- Result = std::string(Path.str());
- return true;
- }
- }
- }
- return false;
-}
-
-} // end anonymous namespace
-
-ObjectFile *LLVMSymbolizer::lookUpDsymFile(const std::string &ExePath,
- const MachOObjectFile *MachExeObj, const std::string &ArchName) {
- // On Darwin we may find DWARF in separate object file in
- // resource directory.
- std::vector<std::string> DsymPaths;
- StringRef Filename = sys::path::filename(ExePath);
- DsymPaths.push_back(
- getDarwinDWARFResourceForPath(ExePath, std::string(Filename)));
- for (const auto &Path : Opts.DsymHints) {
- DsymPaths.push_back(
- getDarwinDWARFResourceForPath(Path, std::string(Filename)));
- }
- for (const auto &Path : DsymPaths) {
- auto DbgObjOrErr = getOrCreateObject(Path, ArchName);
- if (!DbgObjOrErr) {
- // Ignore errors, the file might not exist.
- consumeError(DbgObjOrErr.takeError());
- continue;
- }
- ObjectFile *DbgObj = DbgObjOrErr.get();
- if (!DbgObj)
- continue;
- const MachOObjectFile *MachDbgObj = dyn_cast<const MachOObjectFile>(DbgObj);
- if (!MachDbgObj)
- continue;
- if (darwinDsymMatchesBinary(MachDbgObj, MachExeObj))
- return DbgObj;
- }
- return nullptr;
-}
-
-ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path,
- const ObjectFile *Obj,
- const std::string &ArchName) {
- std::string DebuglinkName;
- uint32_t CRCHash;
- std::string DebugBinaryPath;
- if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash))
- return nullptr;
- if (!findDebugBinary(Path, DebuglinkName, CRCHash, Opts.FallbackDebugPath,
- DebugBinaryPath))
- return nullptr;
- auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
- if (!DbgObjOrErr) {
- // Ignore errors, the file might not exist.
- consumeError(DbgObjOrErr.takeError());
- return nullptr;
- }
- return DbgObjOrErr.get();
-}
-
-ObjectFile *LLVMSymbolizer::lookUpBuildIDObject(const std::string &Path,
- const ELFObjectFileBase *Obj,
- const std::string &ArchName) {
- auto BuildID = getBuildID(Obj);
- if (!BuildID)
- return nullptr;
- if (BuildID->size() < 2)
- return nullptr;
- std::string DebugBinaryPath;
- if (!findDebugBinary(Opts.DebugFileDirectory, *BuildID, DebugBinaryPath))
- return nullptr;
- auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
- if (!DbgObjOrErr) {
- consumeError(DbgObjOrErr.takeError());
- return nullptr;
- }
- return DbgObjOrErr.get();
-}
-
-Expected<LLVMSymbolizer::ObjectPair>
-LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
- const std::string &ArchName) {
- auto I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
- if (I != ObjectPairForPathArch.end())
- return I->second;
-
- auto ObjOrErr = getOrCreateObject(Path, ArchName);
- if (!ObjOrErr) {
- ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName),
- ObjectPair(nullptr, nullptr));
- return ObjOrErr.takeError();
- }
-
- ObjectFile *Obj = ObjOrErr.get();
- assert(Obj != nullptr);
- ObjectFile *DbgObj = nullptr;
-
- if (auto MachObj = dyn_cast<const MachOObjectFile>(Obj))
- DbgObj = lookUpDsymFile(Path, MachObj, ArchName);
- else if (auto ELFObj = dyn_cast<const ELFObjectFileBase>(Obj))
- DbgObj = lookUpBuildIDObject(Path, ELFObj, ArchName);
- if (!DbgObj)
- DbgObj = lookUpDebuglinkObject(Path, Obj, ArchName);
- if (!DbgObj)
- DbgObj = Obj;
- ObjectPair Res = std::make_pair(Obj, DbgObj);
- ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res);
- return Res;
-}
-
-Expected<ObjectFile *>
-LLVMSymbolizer::getOrCreateObject(const std::string &Path,
- const std::string &ArchName) {
- 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)
- return BinOrErr.takeError();
- 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)) {
- auto I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName));
- if (I != ObjectForUBPathAndArch.end())
- return I->second.get();
-
- Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
- UB->getMachOObjectForArch(ArchName);
- if (!ObjOrErr) {
- ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
- std::unique_ptr<ObjectFile>());
- return ObjOrErr.takeError();
- }
- ObjectFile *Res = ObjOrErr->get();
- ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
- std::move(ObjOrErr.get()));
- return Res;
- }
- if (Bin->isObject()) {
- return cast<ObjectFile>(Bin);
- }
- return errorCodeToError(object_error::arch_not_found);
-}
-
-Expected<SymbolizableModule *>
-LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
- std::unique_ptr<DIContext> Context,
- StringRef ModuleName) {
- auto InfoOrErr = SymbolizableObjectFile::create(Obj, std::move(Context),
- Opts.UntagAddresses);
- std::unique_ptr<SymbolizableModule> SymMod;
- if (InfoOrErr)
- SymMod = std::move(*InfoOrErr);
- auto InsertResult = Modules.insert(
- std::make_pair(std::string(ModuleName), std::move(SymMod)));
- assert(InsertResult.second);
- if (!InfoOrErr)
- return InfoOrErr.takeError();
- 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(':');
- // Verify that substring after colon form a valid arch name.
- if (ColonPos != std::string::npos) {
- std::string ArchStr = ModuleName.substr(ColonPos + 1);
- if (Triple(ArchStr).getArch() != Triple::UnknownArch) {
- BinaryName = ModuleName.substr(0, ColonPos);
- ArchName = ArchStr;
- }
- }
- auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName);
- if (!ObjectsOrErr) {
- // Failed to find valid object file.
- Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
- return ObjectsOrErr.takeError();
- }
- ObjectPair Objects = ObjectsOrErr.get();
-
- std::unique_ptr<DIContext> Context;
- // If this is a COFF object containing PDB info, use a PDBContext to
- // symbolize. Otherwise, use DWARF.
- if (auto CoffObject = dyn_cast<COFFObjectFile>(Objects.first)) {
- const codeview::DebugInfo *DebugInfo;
- StringRef PDBFileName;
- auto EC = CoffObject->getDebugPDBInfo(DebugInfo, PDBFileName);
- if (!EC && DebugInfo != nullptr && !PDBFileName.empty()) {
- using namespace pdb;
- std::unique_ptr<IPDBSession> Session;
+ if (N.getType() == ELF::NT_GNU_BUILD_ID && N.getName() == ELF::ELF_NOTE_GNU)
+ return N.getDesc();
+ consumeError(std::move(Err));
+ }
+ return {};
+}
+
+Optional<ArrayRef<uint8_t>> getBuildID(const ELFObjectFileBase *Obj) {
+ Optional<ArrayRef<uint8_t>> BuildID;
+ if (auto *O = dyn_cast<ELFObjectFile<ELF32LE>>(Obj))
+ BuildID = getBuildID(O->getELFFile());
+ else if (auto *O = dyn_cast<ELFObjectFile<ELF32BE>>(Obj))
+ BuildID = getBuildID(O->getELFFile());
+ else if (auto *O = dyn_cast<ELFObjectFile<ELF64LE>>(Obj))
+ BuildID = getBuildID(O->getELFFile());
+ else if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))
+ BuildID = getBuildID(O->getELFFile());
+ else
+ llvm_unreachable("unsupported file format");
+ return BuildID;
+}
+
+bool findDebugBinary(const std::vector<std::string> &DebugFileDirectory,
+ const ArrayRef<uint8_t> BuildID,
+ std::string &Result) {
+ auto getDebugPath = [&](StringRef Directory) {
+ SmallString<128> Path{Directory};
+ sys::path::append(Path, ".build-id",
+ llvm::toHex(BuildID[0], /*LowerCase=*/true),
+ llvm::toHex(BuildID.slice(1), /*LowerCase=*/true));
+ Path += ".debug";
+ return Path;
+ };
+ if (DebugFileDirectory.empty()) {
+ SmallString<128> Path = getDebugPath(
+#if defined(__NetBSD__)
+ // Try /usr/libdata/debug/.build-id/../...
+ "/usr/libdata/debug"
+#else
+ // Try /usr/lib/debug/.build-id/../...
+ "/usr/lib/debug"
+#endif
+ );
+ if (llvm::sys::fs::exists(Path)) {
+ Result = std::string(Path.str());
+ return true;
+ }
+ } else {
+ for (const auto &Directory : DebugFileDirectory) {
+ // Try <debug-file-directory>/.build-id/../...
+ SmallString<128> Path = getDebugPath(Directory);
+ if (llvm::sys::fs::exists(Path)) {
+ Result = std::string(Path.str());
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+} // end anonymous namespace
+
+ObjectFile *LLVMSymbolizer::lookUpDsymFile(const std::string &ExePath,
+ const MachOObjectFile *MachExeObj, const std::string &ArchName) {
+ // On Darwin we may find DWARF in separate object file in
+ // resource directory.
+ std::vector<std::string> DsymPaths;
+ StringRef Filename = sys::path::filename(ExePath);
+ DsymPaths.push_back(
+ getDarwinDWARFResourceForPath(ExePath, std::string(Filename)));
+ for (const auto &Path : Opts.DsymHints) {
+ DsymPaths.push_back(
+ getDarwinDWARFResourceForPath(Path, std::string(Filename)));
+ }
+ for (const auto &Path : DsymPaths) {
+ auto DbgObjOrErr = getOrCreateObject(Path, ArchName);
+ if (!DbgObjOrErr) {
+ // Ignore errors, the file might not exist.
+ consumeError(DbgObjOrErr.takeError());
+ continue;
+ }
+ ObjectFile *DbgObj = DbgObjOrErr.get();
+ if (!DbgObj)
+ continue;
+ const MachOObjectFile *MachDbgObj = dyn_cast<const MachOObjectFile>(DbgObj);
+ if (!MachDbgObj)
+ continue;
+ if (darwinDsymMatchesBinary(MachDbgObj, MachExeObj))
+ return DbgObj;
+ }
+ return nullptr;
+}
+
+ObjectFile *LLVMSymbolizer::lookUpDebuglinkObject(const std::string &Path,
+ const ObjectFile *Obj,
+ const std::string &ArchName) {
+ std::string DebuglinkName;
+ uint32_t CRCHash;
+ std::string DebugBinaryPath;
+ if (!getGNUDebuglinkContents(Obj, DebuglinkName, CRCHash))
+ return nullptr;
+ if (!findDebugBinary(Path, DebuglinkName, CRCHash, Opts.FallbackDebugPath,
+ DebugBinaryPath))
+ return nullptr;
+ auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
+ if (!DbgObjOrErr) {
+ // Ignore errors, the file might not exist.
+ consumeError(DbgObjOrErr.takeError());
+ return nullptr;
+ }
+ return DbgObjOrErr.get();
+}
+
+ObjectFile *LLVMSymbolizer::lookUpBuildIDObject(const std::string &Path,
+ const ELFObjectFileBase *Obj,
+ const std::string &ArchName) {
+ auto BuildID = getBuildID(Obj);
+ if (!BuildID)
+ return nullptr;
+ if (BuildID->size() < 2)
+ return nullptr;
+ std::string DebugBinaryPath;
+ if (!findDebugBinary(Opts.DebugFileDirectory, *BuildID, DebugBinaryPath))
+ return nullptr;
+ auto DbgObjOrErr = getOrCreateObject(DebugBinaryPath, ArchName);
+ if (!DbgObjOrErr) {
+ consumeError(DbgObjOrErr.takeError());
+ return nullptr;
+ }
+ return DbgObjOrErr.get();
+}
+
+Expected<LLVMSymbolizer::ObjectPair>
+LLVMSymbolizer::getOrCreateObjectPair(const std::string &Path,
+ const std::string &ArchName) {
+ auto I = ObjectPairForPathArch.find(std::make_pair(Path, ArchName));
+ if (I != ObjectPairForPathArch.end())
+ return I->second;
+
+ auto ObjOrErr = getOrCreateObject(Path, ArchName);
+ if (!ObjOrErr) {
+ ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName),
+ ObjectPair(nullptr, nullptr));
+ return ObjOrErr.takeError();
+ }
+
+ ObjectFile *Obj = ObjOrErr.get();
+ assert(Obj != nullptr);
+ ObjectFile *DbgObj = nullptr;
+
+ if (auto MachObj = dyn_cast<const MachOObjectFile>(Obj))
+ DbgObj = lookUpDsymFile(Path, MachObj, ArchName);
+ else if (auto ELFObj = dyn_cast<const ELFObjectFileBase>(Obj))
+ DbgObj = lookUpBuildIDObject(Path, ELFObj, ArchName);
+ if (!DbgObj)
+ DbgObj = lookUpDebuglinkObject(Path, Obj, ArchName);
+ if (!DbgObj)
+ DbgObj = Obj;
+ ObjectPair Res = std::make_pair(Obj, DbgObj);
+ ObjectPairForPathArch.emplace(std::make_pair(Path, ArchName), Res);
+ return Res;
+}
+
+Expected<ObjectFile *>
+LLVMSymbolizer::getOrCreateObject(const std::string &Path,
+ const std::string &ArchName) {
+ 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)
+ return BinOrErr.takeError();
+ 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)) {
+ auto I = ObjectForUBPathAndArch.find(std::make_pair(Path, ArchName));
+ if (I != ObjectForUBPathAndArch.end())
+ return I->second.get();
+
+ Expected<std::unique_ptr<ObjectFile>> ObjOrErr =
+ UB->getMachOObjectForArch(ArchName);
+ if (!ObjOrErr) {
+ ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
+ std::unique_ptr<ObjectFile>());
+ return ObjOrErr.takeError();
+ }
+ ObjectFile *Res = ObjOrErr->get();
+ ObjectForUBPathAndArch.emplace(std::make_pair(Path, ArchName),
+ std::move(ObjOrErr.get()));
+ return Res;
+ }
+ if (Bin->isObject()) {
+ return cast<ObjectFile>(Bin);
+ }
+ return errorCodeToError(object_error::arch_not_found);
+}
+
+Expected<SymbolizableModule *>
+LLVMSymbolizer::createModuleInfo(const ObjectFile *Obj,
+ std::unique_ptr<DIContext> Context,
+ StringRef ModuleName) {
+ auto InfoOrErr = SymbolizableObjectFile::create(Obj, std::move(Context),
+ Opts.UntagAddresses);
+ std::unique_ptr<SymbolizableModule> SymMod;
+ if (InfoOrErr)
+ SymMod = std::move(*InfoOrErr);
+ auto InsertResult = Modules.insert(
+ std::make_pair(std::string(ModuleName), std::move(SymMod)));
+ assert(InsertResult.second);
+ if (!InfoOrErr)
+ return InfoOrErr.takeError();
+ 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(':');
+ // Verify that substring after colon form a valid arch name.
+ if (ColonPos != std::string::npos) {
+ std::string ArchStr = ModuleName.substr(ColonPos + 1);
+ if (Triple(ArchStr).getArch() != Triple::UnknownArch) {
+ BinaryName = ModuleName.substr(0, ColonPos);
+ ArchName = ArchStr;
+ }
+ }
+ auto ObjectsOrErr = getOrCreateObjectPair(BinaryName, ArchName);
+ if (!ObjectsOrErr) {
+ // Failed to find valid object file.
+ Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
+ return ObjectsOrErr.takeError();
+ }
+ ObjectPair Objects = ObjectsOrErr.get();
+
+ std::unique_ptr<DIContext> Context;
+ // If this is a COFF object containing PDB info, use a PDBContext to
+ // symbolize. Otherwise, use DWARF.
+ if (auto CoffObject = dyn_cast<COFFObjectFile>(Objects.first)) {
+ const codeview::DebugInfo *DebugInfo;
+ StringRef PDBFileName;
+ auto EC = CoffObject->getDebugPDBInfo(DebugInfo, PDBFileName);
+ if (!EC && DebugInfo != nullptr && !PDBFileName.empty()) {
+ using namespace pdb;
+ std::unique_ptr<IPDBSession> Session;
PDB_ReaderType ReaderType =
Opts.UseDIA ? PDB_ReaderType::DIA : PDB_ReaderType::Native;
- if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(),
- Session)) {
- Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
- // Return along the PDB filename to provide more context
- return createFileError(PDBFileName, std::move(Err));
- }
- Context.reset(new PDBContext(*CoffObject, std::move(Session)));
- }
- }
- if (!Context)
- Context = DWARFContext::create(*Objects.second, nullptr, Opts.DWPName);
- return createModuleInfo(Objects.first, std::move(Context), ModuleName);
-}
-
-namespace {
-
-// Undo these various manglings for Win32 extern "C" functions:
-// cdecl - _foo
-// stdcall - _foo@12
-// fastcall - @foo@12
-// vectorcall - foo@@12
-// These are all different linkage names for 'foo'.
-StringRef demanglePE32ExternCFunc(StringRef SymbolName) {
- // Remove any '_' or '@' prefix.
- char Front = SymbolName.empty() ? '\0' : SymbolName[0];
- if (Front == '_' || Front == '@')
- SymbolName = SymbolName.drop_front();
-
- // Remove any '@[0-9]+' suffix.
- if (Front != '?') {
- size_t AtPos = SymbolName.rfind('@');
- if (AtPos != StringRef::npos &&
+ if (auto Err = loadDataForEXE(ReaderType, Objects.first->getFileName(),
+ Session)) {
+ Modules.emplace(ModuleName, std::unique_ptr<SymbolizableModule>());
+ // Return along the PDB filename to provide more context
+ return createFileError(PDBFileName, std::move(Err));
+ }
+ Context.reset(new PDBContext(*CoffObject, std::move(Session)));
+ }
+ }
+ if (!Context)
+ Context = DWARFContext::create(*Objects.second, nullptr, Opts.DWPName);
+ return createModuleInfo(Objects.first, std::move(Context), ModuleName);
+}
+
+namespace {
+
+// Undo these various manglings for Win32 extern "C" functions:
+// cdecl - _foo
+// stdcall - _foo@12
+// fastcall - @foo@12
+// vectorcall - foo@@12
+// These are all different linkage names for 'foo'.
+StringRef demanglePE32ExternCFunc(StringRef SymbolName) {
+ // Remove any '_' or '@' prefix.
+ char Front = SymbolName.empty() ? '\0' : SymbolName[0];
+ if (Front == '_' || Front == '@')
+ SymbolName = SymbolName.drop_front();
+
+ // Remove any '@[0-9]+' suffix.
+ if (Front != '?') {
+ size_t AtPos = SymbolName.rfind('@');
+ if (AtPos != StringRef::npos &&
all_of(drop_begin(SymbolName, AtPos + 1), isDigit))
- SymbolName = SymbolName.substr(0, AtPos);
- }
-
- // Remove any ending '@' for vectorcall.
- if (SymbolName.endswith("@"))
- SymbolName = SymbolName.drop_back();
-
- return SymbolName;
-}
-
-} // end anonymous namespace
-
-std::string
-LLVMSymbolizer::DemangleName(const std::string &Name,
- const SymbolizableModule *DbiModuleDescriptor) {
- // We can spoil names of symbols with C linkage, so use an heuristic
- // approach to check if the name should be demangled.
- if (Name.substr(0, 2) == "_Z") {
- int status = 0;
- char *DemangledName = itaniumDemangle(Name.c_str(), nullptr, nullptr, &status);
- if (status != 0)
- return Name;
- std::string Result = DemangledName;
- free(DemangledName);
- return Result;
- }
-
- if (!Name.empty() && Name.front() == '?') {
- // Only do MSVC C++ demangling on symbols starting with '?'.
- int status = 0;
- char *DemangledName = microsoftDemangle(
- Name.c_str(), nullptr, nullptr, nullptr, &status,
- MSDemangleFlags(MSDF_NoAccessSpecifier | MSDF_NoCallingConvention |
- MSDF_NoMemberType | MSDF_NoReturnType));
- if (status != 0)
- return Name;
- std::string Result = DemangledName;
- free(DemangledName);
- return Result;
- }
-
- if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module())
- return std::string(demanglePE32ExternCFunc(Name));
- return Name;
-}
-
-} // namespace symbolize
-} // namespace llvm
+ SymbolName = SymbolName.substr(0, AtPos);
+ }
+
+ // Remove any ending '@' for vectorcall.
+ if (SymbolName.endswith("@"))
+ SymbolName = SymbolName.drop_back();
+
+ return SymbolName;
+}
+
+} // end anonymous namespace
+
+std::string
+LLVMSymbolizer::DemangleName(const std::string &Name,
+ const SymbolizableModule *DbiModuleDescriptor) {
+ // We can spoil names of symbols with C linkage, so use an heuristic
+ // approach to check if the name should be demangled.
+ if (Name.substr(0, 2) == "_Z") {
+ int status = 0;
+ char *DemangledName = itaniumDemangle(Name.c_str(), nullptr, nullptr, &status);
+ if (status != 0)
+ return Name;
+ std::string Result = DemangledName;
+ free(DemangledName);
+ return Result;
+ }
+
+ if (!Name.empty() && Name.front() == '?') {
+ // Only do MSVC C++ demangling on symbols starting with '?'.
+ int status = 0;
+ char *DemangledName = microsoftDemangle(
+ Name.c_str(), nullptr, nullptr, nullptr, &status,
+ MSDemangleFlags(MSDF_NoAccessSpecifier | MSDF_NoCallingConvention |
+ MSDF_NoMemberType | MSDF_NoReturnType));
+ if (status != 0)
+ return Name;
+ std::string Result = DemangledName;
+ free(DemangledName);
+ return Result;
+ }
+
+ if (DbiModuleDescriptor && DbiModuleDescriptor->isWin32Module())
+ return std::string(demanglePE32ExternCFunc(Name));
+ return Name;
+}
+
+} // namespace symbolize
+} // namespace llvm
diff --git a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make
index b627533f82..a64d342a87 100644
--- a/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make
+++ b/contrib/libs/llvm12/lib/DebugInfo/Symbolize/ya.make
@@ -1,37 +1,37 @@
-# Generated by devtools/yamaker.
-
-LIBRARY()
-
+# Generated by devtools/yamaker.
+
+LIBRARY()
+
OWNER(
orivej
g:cpp-contrib
)
-
+
LICENSE(Apache-2.0 WITH LLVM-exception)
LICENSE_TEXTS(.yandex_meta/licenses.list.txt)
-PEERDIR(
+PEERDIR(
contrib/libs/llvm12
contrib/libs/llvm12/lib/DebugInfo/DWARF
contrib/libs/llvm12/lib/DebugInfo/PDB
contrib/libs/llvm12/lib/Demangle
contrib/libs/llvm12/lib/Object
contrib/libs/llvm12/lib/Support
-)
-
+)
+
ADDINCL(
contrib/libs/llvm12/lib/DebugInfo/Symbolize
)
-
-NO_COMPILER_WARNINGS()
-
-NO_UTIL()
-
-SRCS(
- DIPrinter.cpp
- SymbolizableObjectFile.cpp
- Symbolize.cpp
-)
-
-END()
+
+NO_COMPILER_WARNINGS()
+
+NO_UTIL()
+
+SRCS(
+ DIPrinter.cpp
+ SymbolizableObjectFile.cpp
+ Symbolize.cpp
+)
+
+END()