Skip to content

Commit

Permalink
[PDB] Use two DBs when dumping the IPI stream
Browse files Browse the repository at this point in the history
Summary:
When dumping these records from an object file section, we should use
only one type database. However, when dumping from a PDB, we should use
two: one for the type stream and one for the IPI stream.

Certain type records that normally live in the .debug$T object file
section get moved over to the IPI stream of the PDB file and they get
new indices.

So far, I've noticed that the MSVC linker always moves these records
into IPI:
- LF_FUNC_ID
- LF_MFUNC_ID
- LF_STRING_ID
- LF_SUBSTR_LIST
- LF_BUILDINFO
- LF_UDT_MOD_SRC_LINE

These records have index fields that can point into TPI or IPI. In
particular, LF_SUBSTR_LIST and LF_BUILDINFO point to LF_STRING_ID
records to describe compilation command lines.

I've modified the dumper to have an optional pointer to the item DB, and
to do type name lookup of these fields in that DB. See printItemIndex.
The result is that our pdbdump-headers.test is more faithful to the PDB
contents and the output is less confusing.

Reviewers: ruiu

Subscribers: amccarth, zturner, llvm-commits

Differential Revision: https://reviews.llvm.org/D31309

llvm-svn: 298649
  • Loading branch information
rnk committed Mar 23, 2017
1 parent acffa28 commit a5d187b
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 37 deletions.
14 changes: 14 additions & 0 deletions llvm/include/llvm/DebugInfo/CodeView/TypeDumpVisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,16 @@ class TypeDumpVisitor : public TypeVisitorCallbacks {
TypeDumpVisitor(TypeDatabase &TypeDB, ScopedPrinter *W, bool PrintRecordBytes)
: W(W), PrintRecordBytes(PrintRecordBytes), TypeDB(TypeDB) {}

/// When dumping types from an IPI stream in a PDB, a type index may refer to
/// a type or an item ID. The dumper will lookup the "name" of the index in
/// the item database if appropriate. If ItemDB is null, it will use TypeDB,
/// which is correct when dumping types from an object file (/Z7).
void setItemDB(TypeDatabase &DB) { ItemDB = &DB; }

void printTypeIndex(StringRef FieldName, TypeIndex TI) const;

void printItemIndex(StringRef FieldName, TypeIndex TI) const;

/// Action to take on unknown types. By default, they are ignored.
Error visitUnknownType(CVType &Record) override;
Error visitUnknownMember(CVMemberRecord &Record) override;
Expand All @@ -54,11 +62,17 @@ class TypeDumpVisitor : public TypeVisitorCallbacks {
void printMemberAttributes(MemberAccess Access, MethodKind Kind,
MethodOptions Options);

/// Get the database of indices for the stream that we are dumping. If ItemDB
/// is set, then we must be dumping an item (IPI) stream. This will also
/// always get the appropriate DB for printing item names.
TypeDatabase &getSourceDB() const { return ItemDB ? *ItemDB : TypeDB; }

ScopedPrinter *W;

bool PrintRecordBytes = false;

TypeDatabase &TypeDB;
TypeDatabase *ItemDB = nullptr;
};

} // end namespace codeview
Expand Down
17 changes: 11 additions & 6 deletions llvm/lib/DebugInfo/CodeView/TypeDumpVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,9 +164,14 @@ void TypeDumpVisitor::printTypeIndex(StringRef FieldName, TypeIndex TI) const {
CVTypeDumper::printTypeIndex(*W, FieldName, TI, TypeDB);
}

void TypeDumpVisitor::printItemIndex(StringRef FieldName, TypeIndex TI) const {
CVTypeDumper::printTypeIndex(*W, FieldName, TI, getSourceDB());
}

Error TypeDumpVisitor::visitTypeBegin(CVType &Record) {
W->startLine() << getLeafTypeName(Record.Type);
W->getOStream() << " (" << HexNumber(TypeDB.getNextTypeIndex().getIndex())
W->getOStream() << " ("
<< HexNumber(getSourceDB().getNextTypeIndex().getIndex())
<< ")";
W->getOStream() << " {\n";
W->indent();
Expand Down Expand Up @@ -212,7 +217,7 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
}

Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, StringIdRecord &String) {
printTypeIndex("Id", String.getId());
printItemIndex("Id", String.getId());
W->printString("StringData", String.getString());
return Error::success();
}
Expand Down Expand Up @@ -341,7 +346,7 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
}

Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, FuncIdRecord &Func) {
printTypeIndex("ParentScope", Func.getParentScope());
printItemIndex("ParentScope", Func.getParentScope());
printTypeIndex("FunctionType", Func.getFunctionType());
W->printString("Name", Func.getName());
return Error::success();
Expand Down Expand Up @@ -402,15 +407,15 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
UdtSourceLineRecord &Line) {
printTypeIndex("UDT", Line.getUDT());
printTypeIndex("SourceFile", Line.getSourceFile());
printItemIndex("SourceFile", Line.getSourceFile());
W->printNumber("LineNumber", Line.getLineNumber());
return Error::success();
}

Error TypeDumpVisitor::visitKnownRecord(CVType &CVR,
UdtModSourceLineRecord &Line) {
printTypeIndex("UDT", Line.getUDT());
printTypeIndex("SourceFile", Line.getSourceFile());
printItemIndex("SourceFile", Line.getSourceFile());
W->printNumber("LineNumber", Line.getLineNumber());
W->printNumber("Module", Line.getModule());
return Error::success();
Expand All @@ -421,7 +426,7 @@ Error TypeDumpVisitor::visitKnownRecord(CVType &CVR, BuildInfoRecord &Args) {

ListScope Arguments(*W, "Arguments");
for (auto Arg : Args.getArgs()) {
printTypeIndex("ArgType", Arg);
printItemIndex("ArgType", Arg);
}
return Error::success();
}
Expand Down
Loading

0 comments on commit a5d187b

Please sign in to comment.