summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo/CodeView
diff options
context:
space:
mode:
authorAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-11-05 19:20:47 +0000
committerAlexandre Ganea <alexandre.ganea@ubisoft.com>2018-11-05 19:20:47 +0000
commit71c43ceaf862a5d9c9654f079fcaf82ed7ba40b4 (patch)
treeae3e1dce36e7fa3945ff04b63a697d387134cc5f /llvm/lib/DebugInfo/CodeView
parent1a9b0723385c8426bf9f7cca169bf3d4bbd1e729 (diff)
downloadbcm5719-llvm-71c43ceaf862a5d9c9654f079fcaf82ed7ba40b4.tar.gz
bcm5719-llvm-71c43ceaf862a5d9c9654f079fcaf82ed7ba40b4.zip
[COFF][LLD] Add link support for Microsoft precompiled headers OBJs
This change allows for link-time merging of debugging information from Microsoft precompiled types OBJs compiled with cl.exe /Z7 /Yc and /Yu. This fixes llvm.org/PR34278 Differential Revision: https://reviews.llvm.org/D45213 llvm-svn: 346154
Diffstat (limited to 'llvm/lib/DebugInfo/CodeView')
-rw-r--r--llvm/lib/DebugInfo/CodeView/CodeViewError.cpp4
-rw-r--r--llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp113
2 files changed, 82 insertions, 35 deletions
diff --git a/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
index 914157ef0c1..2a9753add31 100644
--- a/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
+++ b/llvm/lib/DebugInfo/CodeView/CodeViewError.cpp
@@ -41,6 +41,8 @@ public:
};
static llvm::ManagedStatic<CodeViewErrorCategory> CodeViewErrCategory;
-const std::error_category &llvm::codeview::CVErrorCategory() { return *CodeViewErrCategory; }
+const std::error_category &llvm::codeview::CVErrorCategory() {
+ return *CodeViewErrCategory;
+}
char CodeViewError::ID;
diff --git a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
index 1a1d516ff3c..803818226e5 100644
--- a/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
+++ b/llvm/lib/DebugInfo/CodeView/TypeStreamMerger.cpp
@@ -12,6 +12,7 @@
#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"
@@ -63,7 +64,12 @@ class TypeStreamMerger {
public:
explicit TypeStreamMerger(SmallVectorImpl<TypeIndex> &SourceToDest)
: IndexMap(SourceToDest) {
- SourceToDest.clear();
+ // 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;
@@ -71,7 +77,8 @@ public:
// Local hashing entry points
Error mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
MergingTypeTableBuilder &DestTypes,
- const CVTypeArray &IdsAndTypes);
+ const CVTypeArray &IdsAndTypes,
+ Optional<EndPrecompRecord> &EP);
Error mergeIdRecords(MergingTypeTableBuilder &Dest,
ArrayRef<TypeIndex> TypeSourceToDest,
const CVTypeArray &Ids);
@@ -82,13 +89,15 @@ public:
Error mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
GlobalTypeTableBuilder &DestTypes,
const CVTypeArray &IdsAndTypes,
- ArrayRef<GloballyHashedType> Hashes);
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<EndPrecompRecord> &EP);
Error mergeIdRecords(GlobalTypeTableBuilder &Dest,
ArrayRef<TypeIndex> TypeSourceToDest,
const CVTypeArray &Ids,
ArrayRef<GloballyHashedType> Hashes);
Error mergeTypeRecords(GlobalTypeTableBuilder &Dest, const CVTypeArray &Types,
- ArrayRef<GloballyHashedType> Hashes);
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<EndPrecompRecord> &EP);
private:
Error doit(const CVTypeArray &Types);
@@ -156,6 +165,8 @@ private:
return llvm::make_error<CodeViewError>(cv_error_code::corrupt_record);
}
+ Expected<bool> shouldRemapType(const CVType &Type);
+
Optional<Error> LastError;
bool UseGlobalHashes = false;
@@ -185,6 +196,8 @@ private:
/// Temporary storage that we use to copy a record's data while re-writing
/// its type indices.
SmallVector<uint8_t, 256> RemapStorage;
+
+ Optional<EndPrecompRecord> EndPrecomp;
};
} // end anonymous namespace
@@ -261,22 +274,27 @@ Error TypeStreamMerger::mergeIdRecords(MergingTypeTableBuilder &Dest,
Error TypeStreamMerger::mergeTypesAndIds(MergingTypeTableBuilder &DestIds,
MergingTypeTableBuilder &DestTypes,
- const CVTypeArray &IdsAndTypes) {
+ const CVTypeArray &IdsAndTypes,
+ Optional<EndPrecompRecord> &EP) {
DestIdStream = &DestIds;
DestTypeStream = &DestTypes;
UseGlobalHashes = false;
- return doit(IdsAndTypes);
+ auto Err = doit(IdsAndTypes);
+ EP = EndPrecomp;
+ return Err;
}
// Global hashing entry points
Error TypeStreamMerger::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
const CVTypeArray &Types,
- ArrayRef<GloballyHashedType> Hashes) {
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<EndPrecompRecord> &EP) {
DestGlobalTypeStream = &Dest;
UseGlobalHashes = true;
GlobalHashes = Hashes;
-
- return doit(Types);
+ auto Err = doit(Types);
+ EP = EndPrecomp;
+ return Err;
}
Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest,
@@ -294,12 +312,15 @@ Error TypeStreamMerger::mergeIdRecords(GlobalTypeTableBuilder &Dest,
Error TypeStreamMerger::mergeTypesAndIds(GlobalTypeTableBuilder &DestIds,
GlobalTypeTableBuilder &DestTypes,
const CVTypeArray &IdsAndTypes,
- ArrayRef<GloballyHashedType> Hashes) {
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<EndPrecompRecord> &EP) {
DestGlobalIdStream = &DestIds;
DestGlobalTypeStream = &DestTypes;
UseGlobalHashes = true;
GlobalHashes = Hashes;
- return doit(IdsAndTypes);
+ auto Err = doit(IdsAndTypes);
+ EP = EndPrecomp;
+ return Err;
}
Error TypeStreamMerger::doit(const CVTypeArray &Types) {
@@ -345,25 +366,30 @@ Error TypeStreamMerger::remapAllTypes(const CVTypeArray &Types) {
}
Error TypeStreamMerger::remapType(const CVType &Type) {
- auto DoSerialize =
- [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> {
- return remapIndices(Type, Storage);
- };
+ auto R = shouldRemapType(Type);
+ if (!R)
+ return R.takeError();
TypeIndex DestIdx = Untranslated;
- if (LLVM_LIKELY(UseGlobalHashes)) {
- GlobalTypeTableBuilder &Dest =
- isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
- GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
- DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize);
- } else {
- MergingTypeTableBuilder &Dest =
- isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
-
- RemapStorage.resize(Type.RecordData.size());
- ArrayRef<uint8_t> Result = DoSerialize(RemapStorage);
- if (!Result.empty())
- DestIdx = Dest.insertRecordBytes(Result);
+ if (*R) {
+ auto DoSerialize =
+ [this, Type](MutableArrayRef<uint8_t> Storage) -> ArrayRef<uint8_t> {
+ return remapIndices(Type, Storage);
+ };
+ if (LLVM_LIKELY(UseGlobalHashes)) {
+ GlobalTypeTableBuilder &Dest =
+ isIdRecord(Type.kind()) ? *DestGlobalIdStream : *DestGlobalTypeStream;
+ GloballyHashedType H = GlobalHashes[CurIndex.toArrayIndex()];
+ DestIdx = Dest.insertRecordAs(H, Type.RecordData.size(), DoSerialize);
+ } else {
+ MergingTypeTableBuilder &Dest =
+ isIdRecord(Type.kind()) ? *DestIdStream : *DestTypeStream;
+
+ RemapStorage.resize(Type.RecordData.size());
+ ArrayRef<uint8_t> Result = DoSerialize(RemapStorage);
+ if (!Result.empty())
+ DestIdx = Dest.insertRecordBytes(Result);
+ }
}
addMapping(DestIdx);
@@ -418,25 +444,29 @@ Error llvm::codeview::mergeIdRecords(MergingTypeTableBuilder &Dest,
Error llvm::codeview::mergeTypeAndIdRecords(
MergingTypeTableBuilder &DestIds, MergingTypeTableBuilder &DestTypes,
- SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes) {
+ SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes,
+ Optional<EndPrecompRecord> &EndPrecomp) {
TypeStreamMerger M(SourceToDest);
- return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes);
+ return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, EndPrecomp);
}
Error llvm::codeview::mergeTypeAndIdRecords(
GlobalTypeTableBuilder &DestIds, GlobalTypeTableBuilder &DestTypes,
SmallVectorImpl<TypeIndex> &SourceToDest, const CVTypeArray &IdsAndTypes,
- ArrayRef<GloballyHashedType> Hashes) {
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<EndPrecompRecord> &EndPrecomp) {
TypeStreamMerger M(SourceToDest);
- return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes);
+ return M.mergeTypesAndIds(DestIds, DestTypes, IdsAndTypes, Hashes,
+ EndPrecomp);
}
Error llvm::codeview::mergeTypeRecords(GlobalTypeTableBuilder &Dest,
SmallVectorImpl<TypeIndex> &SourceToDest,
const CVTypeArray &Types,
- ArrayRef<GloballyHashedType> Hashes) {
+ ArrayRef<GloballyHashedType> Hashes,
+ Optional<EndPrecompRecord> &EndPrecomp) {
TypeStreamMerger M(SourceToDest);
- return M.mergeTypeRecords(Dest, Types, Hashes);
+ return M.mergeTypeRecords(Dest, Types, Hashes, EndPrecomp);
}
Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest,
@@ -447,3 +477,18 @@ Error llvm::codeview::mergeIdRecords(GlobalTypeTableBuilder &Dest,
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) {
+ assert(!EndPrecomp);
+ EndPrecomp.emplace();
+ if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type),
+ EndPrecomp.getValue()))
+ return joinErrors(std::move(EC), errorCorruptRecord());
+ return false;
+ }
+ return true;
+}
OpenPOWER on IntegriCloud