[lld] r308235 - [PDB] Merge in types and items from type servers (/Zi)

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Mon Jul 17 17:21:25 PDT 2017


Author: rnk
Date: Mon Jul 17 17:21:25 2017
New Revision: 308235

URL: http://llvm.org/viewvc/llvm-project?rev=308235&view=rev
Log:
[PDB] Merge in types and items from type servers (/Zi)

Summary:
Object files compiled with /Zi emit type information into a type server
PDB. The .debug$S section will contain a single TypeServer2Record with
the absolute path and GUID of the type server. LLD needs to load the
type server PDB and merge all types and items it finds in it into the
destination PDB.

Depends on D35495

Reviewers: ruiu, inglorion

Subscribers: zturner, llvm-commits

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

Added:
    lld/trunk/test/COFF/Inputs/pdb-type-server-simple-a.yaml
    lld/trunk/test/COFF/Inputs/pdb-type-server-simple-b.yaml
    lld/trunk/test/COFF/Inputs/pdb-type-server-simple-ts.yaml
    lld/trunk/test/COFF/pdb-type-server-simple.test
Modified:
    lld/trunk/COFF/PDB.cpp
    lld/trunk/test/COFF/pdb-type-server-missing.yaml

Modified: lld/trunk/COFF/PDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/PDB.cpp?rev=308235&r1=308234&r2=308235&view=diff
==============================================================================
--- lld/trunk/COFF/PDB.cpp (original)
+++ lld/trunk/COFF/PDB.cpp Mon Jul 17 17:21:25 2017
@@ -14,27 +14,29 @@
 #include "SymbolTable.h"
 #include "Symbols.h"
 #include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
-#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
 #include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
-#include "llvm/DebugInfo/CodeView/DebugSubsectionVisitor.h"
 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
 #include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
+#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
 #include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
 #include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
 #include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
 #include "llvm/DebugInfo/MSF/MSFBuilder.h"
 #include "llvm/DebugInfo/MSF/MSFCommon.h"
+#include "llvm/DebugInfo/PDB/GenericError.h"
 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
 #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
 #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
 #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
+#include "llvm/DebugInfo/PDB/PDB.h"
 #include "llvm/Object/COFF.h"
 #include "llvm/Support/BinaryByteStream.h"
 #include "llvm/Support/Endian.h"
@@ -53,6 +55,14 @@ using llvm::object::coff_section;
 static ExitOnError ExitOnErr;
 
 namespace {
+/// Map from type index and item index in a type server PDB to the
+/// corresponding index in the destination PDB.
+struct CVIndexMap {
+  SmallVector<TypeIndex, 0> TPIMap;
+  SmallVector<TypeIndex, 0> IPIMap;
+  bool IsTypeServerMap = false;
+};
+
 class PDBLinker {
 public:
   PDBLinker(SymbolTable *Symtab)
@@ -68,10 +78,21 @@ public:
   /// Link CodeView from a single object file into the PDB.
   void addObjectFile(ObjectFile *File);
 
-  /// Merge the type information from the .debug$T section in the given object
-  /// file. Produce a mapping from object file type indices to type or
-  /// item indices in the final PDB.
-  void mergeDebugT(ObjectFile *File, SmallVectorImpl<TypeIndex> &TypeIndexMap);
+  /// Produce a mapping from the type and item indices used in the object
+  /// file to those in the destination PDB.
+  ///
+  /// If the object file uses a type server PDB (compiled with /Zi), merge TPI
+  /// and IPI from the type server PDB and return a map for it. Each unique type
+  /// server PDB is merged at most once, so this may return an existing index
+  /// mapping.
+  ///
+  /// If the object does not use a type server PDB (compiled with /Z7), we merge
+  /// all the type and item records from the .debug$S stream and fill in the
+  /// caller-provided ObjectIndexMap.
+  const CVIndexMap &mergeDebugT(ObjectFile *File, CVIndexMap &ObjectIndexMap);
+
+  const CVIndexMap &maybeMergeTypeServerPDB(ObjectFile *File,
+                                            TypeServer2Record &TS);
 
   /// Add the section map and section contributions to the PDB.
   void addSections(ArrayRef<uint8_t> SectionTable);
@@ -99,6 +120,9 @@ private:
   llvm::SmallString<128> NativePath;
 
   std::vector<pdb::SecMapEntry> SectionMap;
+
+  /// Type index mappings of type server PDBs that we've loaded so far.
+  std::map<GUID, CVIndexMap> TypeServerIndexMappings;
 };
 }
 
@@ -146,25 +170,114 @@ static void addTypeInfo(pdb::TpiStreamBu
   });
 }
 
-void PDBLinker::mergeDebugT(ObjectFile *File,
-                            SmallVectorImpl<TypeIndex> &TypeIndexMap) {
+static Optional<TypeServer2Record>
+maybeReadTypeServerRecord(CVTypeArray &Types) {
+  auto I = Types.begin();
+  if (I == Types.end())
+    return None;
+  const CVType &Type = *I;
+  if (Type.kind() != LF_TYPESERVER2)
+    return None;
+  TypeServer2Record TS;
+  if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), TS))
+    fatal(EC, "error reading type server record");
+  return std::move(TS);
+}
+
+const CVIndexMap &PDBLinker::mergeDebugT(ObjectFile *File,
+                                         CVIndexMap &ObjectIndexMap) {
   ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
   if (Data.empty())
-    return;
-
-  // Look for type server PDBs next to the input file. If this file has a parent
-  // archive, look next to the archive path.
-  StringRef LocalPath =
-      !File->ParentName.empty() ? File->ParentName : File->getName();
-  (void)LocalPath; // FIXME: Implement type server handling here.
+    return ObjectIndexMap;
 
   BinaryByteStream Stream(Data, support::little);
   CVTypeArray Types;
   BinaryStreamReader Reader(Stream);
   if (auto EC = Reader.readArray(Types, Reader.getLength()))
     fatal(EC, "Reader::readArray failed");
-  if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable, TypeIndexMap, Types))
-    fatal(Err, "codeview::mergeTypeStreams failed");
+
+  // Look through type servers. If we've already seen this type server, don't
+  // merge any type information.
+  if (Optional<TypeServer2Record> TS = maybeReadTypeServerRecord(Types))
+    return maybeMergeTypeServerPDB(File, *TS);
+
+  // This is a /Z7 object. Fill in the temporary, caller-provided
+  // ObjectIndexMap.
+  if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
+                                       ObjectIndexMap.TPIMap, Types))
+    fatal(Err, "codeview::mergeTypeAndIdRecords failed");
+  return ObjectIndexMap;
+}
+
+static Expected<std::unique_ptr<pdb::NativeSession>>
+tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
+  std::unique_ptr<pdb::IPDBSession> ThisSession;
+  if (auto EC =
+          pdb::loadDataForPDB(pdb::PDB_ReaderType::Native, TSPath, ThisSession))
+    return std::move(EC);
+
+  std::unique_ptr<pdb::NativeSession> NS(
+      static_cast<pdb::NativeSession *>(ThisSession.release()));
+  pdb::PDBFile &File = NS->getPDBFile();
+  auto ExpectedInfo = File.getPDBInfoStream();
+  // All PDB Files should have an Info stream.
+  if (!ExpectedInfo)
+    return ExpectedInfo.takeError();
+
+  // Just because a file with a matching name was found and it was an actual
+  // PDB file doesn't mean it matches.  For it to match the InfoStream's GUID
+  // must match the GUID specified in the TypeServer2 record.
+  if (ExpectedInfo->getGuid() != GuidFromObj)
+    return make_error<pdb::GenericError>(
+        pdb::generic_error_code::type_server_not_found, TSPath);
+
+  return std::move(NS);
+}
+
+const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjectFile *File,
+                                                     TypeServer2Record &TS) {
+  // First, check if we already loaded a PDB with this GUID. Return the type
+  // index mapping if we have it.
+  auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()});
+  CVIndexMap &IndexMap = Insertion.first->second;
+  if (!Insertion.second)
+    return IndexMap;
+
+  // Mark this map as a type server map.
+  IndexMap.IsTypeServerMap = true;
+
+  // Check for a PDB at:
+  // 1. The given file path
+  // 2. Next to the object file or archive file
+  auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName());
+  if (!ExpectedSession) {
+    consumeError(ExpectedSession.takeError());
+    StringRef LocalPath =
+        !File->ParentName.empty() ? File->ParentName : File->getName();
+    SmallString<128> Path = sys::path::parent_path(LocalPath);
+    sys::path::append(Path, sys::path::filename(TS.getName()));
+    ExpectedSession = tryToLoadPDB(TS.getGuid(), Path);
+  }
+  if (auto E = ExpectedSession.takeError())
+    fatal(E, "Type server PDB was not found");
+
+  // Merge TPI first, because the IPI stream will reference type indices.
+  auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
+  if (auto E = ExpectedTpi.takeError())
+    fatal(E, "Type server does not have TPI stream");
+  if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap,
+                                  ExpectedTpi->typeArray()))
+    fatal(Err, "codeview::mergeTypeRecords failed");
+
+  // Merge IPI.
+  auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream();
+  if (auto E = ExpectedIpi.takeError())
+    fatal(E, "Type server does not have TPI stream");
+  if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap,
+                                ExpectedIpi->typeArray()))
+    fatal(Err, "codeview::mergeIdRecords failed");
+
+  return IndexMap;
 }
 
 static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
@@ -178,16 +291,22 @@ static bool remapTypeIndex(TypeIndex &TI
 
 static void remapTypesInSymbolRecord(ObjectFile *File,
                                      MutableArrayRef<uint8_t> Contents,
-                                     ArrayRef<TypeIndex> TypeIndexMap,
+                                     const CVIndexMap &IndexMap,
                                      ArrayRef<TiReference> TypeRefs) {
   for (const TiReference &Ref : TypeRefs) {
     unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
     if (Contents.size() < Ref.Offset + ByteSize)
       fatal("symbol record too short");
+
+    // This can be an item index or a type index. Choose the appropriate map.
+    ArrayRef<TypeIndex> TypeOrItemMap = IndexMap.TPIMap;
+    if (Ref.Kind == TiRefKind::IndexRef && IndexMap.IsTypeServerMap)
+      TypeOrItemMap = IndexMap.IPIMap;
+
     MutableArrayRef<TypeIndex> TIs(
         reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count);
     for (TypeIndex &TI : TIs) {
-      if (!remapTypeIndex(TI, TypeIndexMap)) {
+      if (!remapTypeIndex(TI, TypeOrItemMap)) {
         TI = TypeIndex(SimpleTypeKind::NotTranslated);
         log("ignoring symbol record in " + File->getName() +
             " with bad type index 0x" + utohexstr(TI.getIndex()));
@@ -292,7 +411,7 @@ static void scopeStackClose(SmallVectorI
 }
 
 static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File,
-                               ArrayRef<TypeIndex> TypeIndexMap,
+                               const CVIndexMap &IndexMap,
                                BinaryStreamRef SymData) {
   // FIXME: Improve error recovery by warning and skipping records when
   // possible.
@@ -315,7 +434,7 @@ static void mergeSymbolRecords(BumpPtrAl
     // Re-map all the type index references.
     MutableArrayRef<uint8_t> Contents =
         NewData.drop_front(sizeof(RecordPrefix));
-    remapTypesInSymbolRecord(File, Contents, TypeIndexMap, TypeRefs);
+    remapTypesInSymbolRecord(File, Contents, IndexMap, TypeRefs);
 
     // Fill in "Parent" and "End" fields by maintaining a stack of scopes.
     CVSymbol NewSym(Sym.kind(), NewData);
@@ -358,8 +477,8 @@ void PDBLinker::addObjectFile(ObjectFile
   // type information, file checksums, and the string table.  Add type info to
   // the PDB first, so that we can get the map from object file type and item
   // indices to PDB type and item indices.
-  SmallVector<TypeIndex, 128> TypeIndexMap;
-  mergeDebugT(File, TypeIndexMap);
+  CVIndexMap ObjectIndexMap;
+  const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap);
 
   // Now do all live .debug$S sections.
   for (SectionChunk *DebugChunk : File->getDebugChunks()) {
@@ -391,7 +510,7 @@ void PDBLinker::addObjectFile(ObjectFile
         File->ModuleDBI->addDebugSubsection(SS);
         break;
       case DebugSubsectionKind::Symbols:
-        mergeSymbolRecords(Alloc, File, TypeIndexMap, SS.getRecordData());
+        mergeSymbolRecords(Alloc, File, IndexMap, SS.getRecordData());
         break;
       default:
         // FIXME: Process the rest of the subsections.

Added: lld/trunk/test/COFF/Inputs/pdb-type-server-simple-a.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/pdb-type-server-simple-a.yaml?rev=308235&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/pdb-type-server-simple-a.yaml (added)
+++ lld/trunk/test/COFF/Inputs/pdb-type-server-simple-a.yaml Mon Jul 17 17:21:25 2017
@@ -0,0 +1,255 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       1
+    SectionData:     2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Subsections:
+      - !Symbols
+        Records:
+          - Kind:            S_OBJNAME
+            ObjNameSym:
+              Signature:       0
+              ObjectName:      'C:\src\llvm-project\build\a.obj'
+          - Kind:            S_COMPILE3
+            Compile3Sym:
+              Flags:           [ SecurityChecks, HotPatch ]
+              Machine:         X64
+              FrontendMajor:   19
+              FrontendMinor:   0
+              FrontendBuild:   24215
+              FrontendQFE:     1
+              BackendMajor:    19
+              BackendMinor:    0
+              BackendBuild:    24215
+              BackendQFE:      1
+              Version:         'Microsoft (R) Optimizing Compiler'
+      - !Symbols
+        Records:
+          - Kind:            S_GPROC32_ID
+            ProcSym:
+              CodeSize:        27
+              DbgStart:        4
+              DbgEnd:          22
+              FunctionType:    4098
+              Flags:           [  ]
+              DisplayName:     main
+          - Kind:            S_FRAMEPROC
+            FrameProcSym:
+              TotalFrameBytes: 56
+              PaddingFrameBytes: 0
+              OffsetToPadding: 0
+              BytesOfCalleeSavedRegisters: 0
+              OffsetOfExceptionHandler: 0
+              SectionIdOfExceptionHandler: 0
+              Flags:           [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+          - Kind:            S_REGREL32
+            RegRelativeSym:
+              Offset:          32
+              Type:            4102
+              Register:        RSP
+              VarName:         f
+          - Kind:            S_PROC_ID_END
+            ScopeEndSym:
+      - !Lines
+        CodeSize:        27
+        Flags:           [  ]
+        RelocOffset:     0
+        RelocSegment:    0
+        Blocks:
+          - FileName:        'c:\src\llvm-project\build\a.c'
+            Lines:
+              - Offset:          0
+                LineStart:       3
+                IsStatement:     true
+                EndDelta:        0
+              - Offset:          4
+                LineStart:       4
+                IsStatement:     true
+                EndDelta:        0
+              - Offset:          12
+                LineStart:       5
+                IsStatement:     true
+                EndDelta:        0
+              - Offset:          22
+                LineStart:       6
+                IsStatement:     true
+                EndDelta:        0
+            Columns:
+      - !Symbols
+        Records:
+          - Kind:            S_UDT
+            UDTSym:
+              Type:            4102
+              UDTName:         Foo
+      - !FileChecksums
+        Checksums:
+          - FileName:        'c:\src\llvm-project\build\a.c'
+            Kind:            MD5
+            Checksum:        BF69E7E933074E1B7ED1FE8FB395965B
+      - !StringTable
+        Strings:
+          - 'c:\src\llvm-project\build\a.c'
+      - !Symbols
+        Records:
+          - Kind:            S_BUILDINFO
+            BuildInfoSym:
+              BuildId:         4107
+    Relocations:
+      - VirtualAddress:  152
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  156
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+      - VirtualAddress:  224
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  228
+        SymbolName:      main
+        Type:            IMAGE_REL_AMD64_SECTION
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Types:
+      - Kind:            LF_TYPESERVER2
+        TypeServer2:
+          Guid:            '{41414141-4141-4141-4141-414141414141}'
+          Age:             1
+          Name:            'C:\src\llvm-project\build\ts.pdb'
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     4883EC38C74424202A000000488D4C2420E8000000004883C438C3
+    Relocations:
+      - VirtualAddress:  18
+        SymbolName:      g
+        Type:            IMAGE_REL_AMD64_REL32
+  - Name:            .xdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     '0104010004620000'
+  - Name:            .pdata
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
+    Alignment:       4
+    SectionData:     000000001B00000000000000
+    Relocations:
+      - VirtualAddress:  0
+        SymbolName:      '$LN3'
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  4
+        SymbolName:      '$LN3'
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+      - VirtualAddress:  8
+        SymbolName:      '$unwind$main'
+        Type:            IMAGE_REL_AMD64_ADDR32NB
+symbols:
+  - Name:            .drectve
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          47
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          388
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$T'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          64
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.text$mn'
+    Value:           0
+    SectionNumber:   4
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          27
+      NumberOfRelocations: 1
+      NumberOfLinenumbers: 0
+      CheckSum:        1939996292
+      Number:          0
+  - Name:            g
+    Value:           0
+    SectionNumber:   0
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            main
+    Value:           0
+    SectionNumber:   4
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+  - Name:            '$LN3'
+    Value:           0
+    SectionNumber:   4
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_LABEL
+  - Name:            .xdata
+    Value:           0
+    SectionNumber:   5
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          8
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        931692337
+      Number:          0
+  - Name:            '$unwind$main'
+    Value:           0
+    SectionNumber:   5
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+  - Name:            .pdata
+    Value:           0
+    SectionNumber:   6
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          12
+      NumberOfRelocations: 3
+      NumberOfLinenumbers: 0
+      CheckSum:        567356797
+      Number:          0
+  - Name:            '$pdata$main'
+    Value:           0
+    SectionNumber:   6
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+...

Added: lld/trunk/test/COFF/Inputs/pdb-type-server-simple-b.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/pdb-type-server-simple-b.yaml?rev=308235&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/pdb-type-server-simple-b.yaml (added)
+++ lld/trunk/test/COFF/Inputs/pdb-type-server-simple-b.yaml Mon Jul 17 17:21:25 2017
@@ -0,0 +1,173 @@
+--- !COFF
+header:
+  Machine:         IMAGE_FILE_MACHINE_AMD64
+  Characteristics: [  ]
+sections:
+  - Name:            .drectve
+    Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
+    Alignment:       1
+    SectionData:     2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
+  - Name:            '.debug$S'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Subsections:
+      - !Symbols
+        Records:
+          - Kind:            S_OBJNAME
+            ObjNameSym:
+              Signature:       0
+              ObjectName:      'C:\src\llvm-project\build\b.obj'
+          - Kind:            S_COMPILE3
+            Compile3Sym:
+              Flags:           [ SecurityChecks, HotPatch ]
+              Machine:         X64
+              FrontendMajor:   19
+              FrontendMinor:   0
+              FrontendBuild:   24215
+              FrontendQFE:     1
+              BackendMajor:    19
+              BackendMinor:    0
+              BackendBuild:    24215
+              BackendQFE:      1
+              Version:         'Microsoft (R) Optimizing Compiler'
+      - !Symbols
+        Records:
+          - Kind:            S_GPROC32_ID
+            ProcSym:
+              CodeSize:        13
+              DbgStart:        5
+              DbgEnd:          12
+              FunctionType:    4099
+              Flags:           [  ]
+              DisplayName:     g
+          - Kind:            S_FRAMEPROC
+            FrameProcSym:
+              TotalFrameBytes: 0
+              PaddingFrameBytes: 0
+              OffsetToPadding: 0
+              BytesOfCalleeSavedRegisters: 0
+              OffsetOfExceptionHandler: 0
+              SectionIdOfExceptionHandler: 0
+              Flags:           [ AsynchronousExceptionHandling, OptimizedForSpeed ]
+          - Kind:            S_REGREL32
+            RegRelativeSym:
+              Offset:          8
+              Type:            4097
+              Register:        RSP
+              VarName:         p
+          - Kind:            S_PROC_ID_END
+            ScopeEndSym:
+      - !Lines
+        CodeSize:        13
+        Flags:           [  ]
+        RelocOffset:     0
+        RelocSegment:    0
+        Blocks:
+          - FileName:        'c:\src\llvm-project\build\b.c'
+            Lines:
+              - Offset:          0
+                LineStart:       2
+                IsStatement:     true
+                EndDelta:        0
+            Columns:
+      - !Symbols
+        Records:
+          - Kind:            S_UDT
+            UDTSym:
+              Type:            4102
+              UDTName:         Foo
+      - !FileChecksums
+        Checksums:
+          - FileName:        'c:\src\llvm-project\build\b.c'
+            Kind:            MD5
+            Checksum:        DDF8FD35CD67990C5D4147516BE10D0C
+      - !StringTable
+        Strings:
+          - 'c:\src\llvm-project\build\b.c'
+      - !Symbols
+        Records:
+          - Kind:            S_BUILDINFO
+            BuildInfoSym:
+              BuildId:         4111
+    Relocations:
+      - VirtualAddress:  152
+        SymbolName:      g
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  156
+        SymbolName:      g
+        Type:            IMAGE_REL_AMD64_SECTION
+      - VirtualAddress:  220
+        SymbolName:      g
+        Type:            IMAGE_REL_AMD64_SECREL
+      - VirtualAddress:  224
+        SymbolName:      g
+        Type:            IMAGE_REL_AMD64_SECTION
+  - Name:            '.debug$T'
+    Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
+    Alignment:       1
+    Types:
+      - Kind:            LF_TYPESERVER2
+        TypeServer2:
+          Guid:            '{41414141-4141-4141-4141-414141414141}'
+          Age:             1
+          Name:            'C:\src\llvm-project\build\ts.pdb'
+  - Name:            '.text$mn'
+    Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
+    Alignment:       16
+    SectionData:     48894C2408488B4424088B00C3
+symbols:
+  - Name:            .drectve
+    Value:           0
+    SectionNumber:   1
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          47
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$S'
+    Value:           0
+    SectionNumber:   2
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          360
+      NumberOfRelocations: 4
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.debug$T'
+    Value:           0
+    SectionNumber:   3
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          64
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        0
+      Number:          0
+  - Name:            '.text$mn'
+    Value:           0
+    SectionNumber:   4
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_NULL
+    StorageClass:    IMAGE_SYM_CLASS_STATIC
+    SectionDefinition:
+      Length:          13
+      NumberOfRelocations: 0
+      NumberOfLinenumbers: 0
+      CheckSum:        3246683207
+      Number:          0
+  - Name:            g
+    Value:           0
+    SectionNumber:   4
+    SimpleType:      IMAGE_SYM_TYPE_NULL
+    ComplexType:     IMAGE_SYM_DTYPE_FUNCTION
+    StorageClass:    IMAGE_SYM_CLASS_EXTERNAL
+...

Added: lld/trunk/test/COFF/Inputs/pdb-type-server-simple-ts.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/Inputs/pdb-type-server-simple-ts.yaml?rev=308235&view=auto
==============================================================================
--- lld/trunk/test/COFF/Inputs/pdb-type-server-simple-ts.yaml (added)
+++ lld/trunk/test/COFF/Inputs/pdb-type-server-simple-ts.yaml Mon Jul 17 17:21:25 2017
@@ -0,0 +1,147 @@
+---
+MSF:
+  SuperBlock:
+    BlockSize:       4096
+    FreeBlockMap:    1
+    NumBlocks:       19
+    NumDirectoryBytes: 64
+    Unknown1:        0
+    BlockMapAddr:    17
+  NumDirectoryBlocks: 1
+  DirectoryBlocks: [ 16 ]
+  NumStreams:      0
+  FileSize:        77824
+PdbStream:
+  Age:             1
+  Guid:            '{41414141-4141-4141-4141-414141414141}'
+  Signature:       1500053944
+  Features:        [ VC140 ]
+  Version:         VC70
+TpiStream:
+  Version:         VC80
+  Records:
+    - Kind:            LF_STRUCTURE
+      Class:
+        MemberCount:     0
+        Options:         [ None, ForwardReference, HasUniqueName ]
+        FieldList:       0
+        Name:            Foo
+        UniqueName:      '.?AUFoo@@'
+        DerivationList:  0
+        VTableShape:     0
+        Size:            0
+    - Kind:            LF_POINTER
+      Pointer:
+        ReferentType:    4096
+        Attrs:           65548
+    - Kind:            LF_ARGLIST
+      ArgList:
+        ArgIndices:      [ 4097 ]
+    - Kind:            LF_PROCEDURE
+      Procedure:
+        ReturnType:      116
+        CallConv:        NearC
+        Options:         [ None ]
+        ParameterCount:  1
+        ArgumentList:    4098
+    - Kind:            LF_POINTER
+      Pointer:
+        ReferentType:    4099
+        Attrs:           65548
+    - Kind:            LF_FIELDLIST
+      FieldList:
+        - Kind:            LF_MEMBER
+          DataMember:
+            Attrs:           3
+            Type:            116
+            FieldOffset:     0
+            Name:            x
+    - Kind:            LF_STRUCTURE
+      Class:
+        MemberCount:     1
+        Options:         [ None, HasUniqueName ]
+        FieldList:       4101
+        Name:            Foo
+        UniqueName:      '.?AUFoo@@'
+        DerivationList:  0
+        VTableShape:     0
+        Size:            4
+    - Kind:            LF_ARGLIST
+      ArgList:
+        ArgIndices:      [ 0 ]
+    - Kind:            LF_PROCEDURE
+      Procedure:
+        ReturnType:      116
+        CallConv:        NearC
+        Options:         [ None ]
+        ParameterCount:  0
+        ArgumentList:    4103
+IpiStream:
+  Version:         VC80
+  Records:
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          'c:\src\llvm-project\build\a.c'
+    - Kind:            LF_UDT_SRC_LINE
+      UdtSourceLine:
+        UDT:             4102
+        SourceFile:      4096
+        LineNumber:      1
+    - Kind:            LF_FUNC_ID
+      FuncId:
+        ParentScope:     0
+        FunctionType:    4104
+        Name:            main
+    - Kind:            LF_FUNC_ID
+      FuncId:
+        ParentScope:     0
+        FunctionType:    4099
+        Name:            g
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          'C:\src\llvm-project\build'
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          '-c -Zi -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
+    - Kind:            LF_SUBSTR_LIST
+      StringList:
+        StringIndices:   [ 4102 ]
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              4103
+        String:          ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          a.c
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          'C:\src\llvm-project\build\ts.pdb'
+    - Kind:            LF_BUILDINFO
+      BuildInfo:
+        ArgIndices:      [ 4100, 4101, 4105, 4106, 4104 ]
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          'c:\src\llvm-project\build\b.c'
+    - Kind:            LF_UDT_SRC_LINE
+      UdtSourceLine:
+        UDT:             4102
+        SourceFile:      4108
+        LineNumber:      1
+    - Kind:            LF_STRING_ID
+      StringId:
+        Id:              0
+        String:          b.c
+    - Kind:            LF_BUILDINFO
+      BuildInfo:
+        ArgIndices:      [ 4100, 4101, 4110, 4106, 4104 ]
+...

Modified: lld/trunk/test/COFF/pdb-type-server-missing.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/pdb-type-server-missing.yaml?rev=308235&r1=308234&r2=308235&view=diff
==============================================================================
--- lld/trunk/test/COFF/pdb-type-server-missing.yaml (original)
+++ lld/trunk/test/COFF/pdb-type-server-missing.yaml Mon Jul 17 17:21:25 2017
@@ -1,16 +1,13 @@
 # This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
 # adjacent type server PDB. Test that LLD fails gracefully on it.
 
-# FIXME: Type server handling was removed from LLVM.
-# XFAIL: *
-
 # FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug
 # info in the object with the missing PDB.
 
 # RUN: yaml2obj %s -o %t.obj
 # RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
 
-# CHECK: error: {{.*}} Type server PDB was not found
+# CHECK: error: Type server PDB was not found
 
 --- !COFF
 header:

Added: lld/trunk/test/COFF/pdb-type-server-simple.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/pdb-type-server-simple.test?rev=308235&view=auto
==============================================================================
--- lld/trunk/test/COFF/pdb-type-server-simple.test (added)
+++ lld/trunk/test/COFF/pdb-type-server-simple.test Mon Jul 17 17:21:25 2017
@@ -0,0 +1,91 @@
+Replicate this scenario:
+
+$ cat a.c
+struct Foo { int x; };
+int g(struct Foo *p);
+int main() {
+  struct Foo f = {42};
+  return g(&f);
+}
+
+$ cat b.c
+struct Foo { int x; };
+int g(struct Foo *p) { return p->x; }
+
+$ cl -c a.c b.c -Zi -Fdts.pdb
+
+$ lld-link a.obj b.obj -debug -entry:main -nodefaultlib -out:t.exe
+
+RUN: rm -rf %t && mkdir -p %t && cd %t
+RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj
+RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj
+RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
+RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib
+RUN: llvm-pdbutil dump -symbols -types -ids %t/t.pdb | FileCheck %s
+
+
+CHECK-LABEL: Types (TPI Stream)
+CHECK: ============================================================
+
+CHECK:   [[FOO_DECL:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
+
+CHECK:   [[FOO_PTR:[^ ]*]] | LF_POINTER [size = 12]
+CHECK-NEXT:            referent = [[FOO_DECL]]
+
+CHECK:   [[G_ARGS:[^ ]*]] | LF_ARGLIST [size = 12]
+CHECK-NEXT:            [[FOO_PTR]]: `Foo*`
+
+CHECK:   [[G_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
+CHECK-NEXT:       return type = 0x0074 (int), # args = 1, param list = [[G_ARGS]]
+CHECK-NEXT:       calling conv = cdecl, options = None
+
+CHECK:   [[FOO_COMPLETE:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
+CHECK-NEXT:       unique name: `.?AUFoo@@`
+CHECK-NEXT:       vtable: <no type>, base list: <no type>, field list: 0x{{.*}}
+CHECK:            options: has unique name
+CHECK:   [[MAIN_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
+CHECK:            return type = 0x0074 (int), # args = 0, param list = 0x{{.*}}
+CHECK:            calling conv = cdecl, options = None
+
+
+CHECK-LABEL:                      Types (IPI Stream)
+CHECK: ============================================================
+CHECK:   [[MAIN_ID:[^ ]*]] | LF_FUNC_ID [size = 20]
+CHECK:            name = main, type = [[MAIN_PROTO]], parent scope = <no type>
+CHECK:   [[G_ID:[^ ]*]] | LF_FUNC_ID [size = 16]
+CHECK:            name = g, type = [[G_PROTO]], parent scope = <no type>
+CHECK:   [[A_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
+CHECK:            {{.*}}: `a.c`
+CHECK:   [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
+CHECK:            {{.*}}: `b.c`
+
+CHECK-LABEL:                           Symbols
+CHECK: ============================================================
+CHECK-LABEL:   Mod 0000 | `{{.*}}a.obj`:
+CHECK:        4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj`
+CHECK:      104 | S_GPROC32_ID [size = 44] `main`
+CHECK:            parent = 0, end = 196, addr = 0002:0000, code size = 27
+CHECK:            type = {{.*}}, debug start = 4, debug end = 22, flags = none
+CHECK:      200 | S_UDT [size = 12] `Foo`
+CHECK:            original type = [[FOO_COMPLETE]]
+CHECK:      212 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]`
+CHECK-LABEL:   Mod 0001 | `{{.*}}b.obj`:
+CHECK:        4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj`
+CHECK:       44 | S_COMPILE3 [size = 60]
+CHECK:            machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
+CHECK:            frontend = 19.0.24215.1, backend = 19.0.24215.1
+CHECK:            flags = security checks | hot patchable
+CHECK:      104 | S_GPROC32_ID [size = 44] `g`
+CHECK:            parent = 0, end = 196, addr = 0002:0032, code size = 13
+CHECK:            type = {{.*}}, debug start = 5, debug end = 12, flags = none
+CHECK:      148 | S_FRAMEPROC [size = 32]
+CHECK:            size = 0, padding size = 0, offset to padding = 0
+CHECK:            bytes of callee saved registers = 0, exception handler addr = 0000:0000
+CHECK:            flags = has async eh | opt speed
+CHECK:      180 | S_REGREL32 [size = 16] `p`
+CHECK:            type = [[FOO_PTR]] (Foo*), register = rsp, offset = 8
+CHECK:      196 | S_END [size = 4]
+CHECK:      200 | S_UDT [size = 12] `Foo`
+CHECK:            original type = [[FOO_COMPLETE]]
+CHECK:      212 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
+CHECK-LABEL:   Mod 0002 | `* Linker *`:




More information about the llvm-commits mailing list