Index: COFF/PDB.cpp =================================================================== --- COFF/PDB.cpp +++ COFF/PDB.cpp @@ -165,7 +165,7 @@ /// List of TypeServer PDBs which cannot be loaded. /// Cached to prevent repeated load attempts. - std::set MissingTypeServerPDBs; + std::map MissingTypeServerPDBs; }; } @@ -326,21 +326,22 @@ // 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::pdb_error_code::type_server_not_found, TSPath); + return make_error(pdb::pdb_error_code::signature_out_of_date); return std::move(NS); } Expected PDBLinker::maybeMergeTypeServerPDB(ObjFile *File, TypeServer2Record &TS) { - const GUID& TSId = TS.getGuid(); + const GUID &TSId = TS.getGuid(); StringRef TSPath = TS.getName(); // First, check if the PDB has previously failed to load. - if (MissingTypeServerPDBs.count(TSId)) - return make_error( - pdb::pdb_error_code::type_server_not_found, TSPath); + auto PrevErr = MissingTypeServerPDBs.find(TSId); + if (PrevErr != MissingTypeServerPDBs.end()) + return createFileError( + TSPath, std::move(make_error(PrevErr->second, + inconvertibleErrorCode()))); // Second, check if we already loaded a PDB with this GUID. Return the type // index mapping if we have it. @@ -355,20 +356,37 @@ // Check for a PDB at: // 1. The given file path // 2. Next to the object file or archive file - auto ExpectedSession = tryToLoadPDB(TSId, TSPath); - 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(TSPath, sys::path::Style::windows)); - ExpectedSession = tryToLoadPDB(TSId, Path); - } + auto ExpectedSession = handleExpected( + tryToLoadPDB(TSId, TSPath), + [&]() { + StringRef LocalPath = + !File->ParentName.empty() ? File->ParentName : File->getName(); + SmallString<128> Path = sys::path::parent_path(LocalPath); + sys::path::append( + Path, sys::path::filename(TSPath, sys::path::Style::windows)); + return tryToLoadPDB(TSId, Path); + }, + [&](std::unique_ptr EC) -> Error { + auto SysErr = EC->convertToErrorCode(); + // Only re-try loading if the previous error was "No such file or + // directory" + if (SysErr.category() == std::generic_category() && + SysErr.value() == ENOENT) + return Error::success(); + return Error(std::move(EC)); + }); + if (auto E = ExpectedSession.takeError()) { TypeServerIndexMappings.erase(TSId); - MissingTypeServerPDBs.emplace(TSId); - return std::move(E); + + // Flatten the error to a string, for later display, if the error occurs + // again on the same PDB. + std::string ErrMsg; + raw_string_ostream S(ErrMsg); + S << E; + auto It = MissingTypeServerPDBs.emplace(TSId, S.str()); + + return createFileError(TSPath, std::move(E)); } pdb::NativeSession *Session = ExpectedSession->get(); @@ -837,8 +855,10 @@ // If the .debug$T sections fail to merge, assume there is no debug info. if (!IndexMapResult) { - warn("Type server PDB for " + Name + " is invalid, ignoring debug info. " + - toString(IndexMapResult.takeError())); + auto FileName = sys::path::filename(Path); + warn("Cannot use debug info for '" + FileName + "'\n" + + ">>> failed to load reference " + + StringRef(toString(IndexMapResult.takeError()))); return; } Index: test/COFF/Inputs/bad-block-size.pdb =================================================================== --- test/COFF/Inputs/bad-block-size.pdb +++ test/COFF/Inputs/bad-block-size.pdb @@ -0,0 +1,2 @@ +Microsoft C/C++ MSF 7.00 +DS \ No newline at end of file Index: test/COFF/Inputs/pdb-type-server-missing-2.yaml =================================================================== --- test/COFF/Inputs/pdb-type-server-missing-2.yaml +++ test/COFF/Inputs/pdb-type-server-missing-2.yaml @@ -0,0 +1,32 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - 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: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' + Age: 18 + Name: 'C:\src\llvm-project\build\definitely_not_found_for_sure.pdb' + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 33C0C3 +symbols: + - Name: '.debug$T' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 564 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 +... Index: test/COFF/Inputs/pdb-type-server-valid-signature.yaml =================================================================== --- test/COFF/Inputs/pdb-type-server-valid-signature.yaml +++ test/COFF/Inputs/pdb-type-server-valid-signature.yaml @@ -0,0 +1,121 @@ +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Subsections: + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 3 + DbgStart: 0 + DbgEnd: 2 + FunctionType: 4199 + Flags: [ ] + DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 0 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 3 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'c:\src\llvm-project\build\t.c' + Lines: + - Offset: 0 + LineStart: 1 + IsStatement: true + EndDelta: 0 + Columns: + - !FileChecksums + Checksums: + - FileName: 'c:\src\llvm-project\build\t.c' + Kind: MD5 + Checksum: 270A878DCC1B845655B162F56C4F5020 + - !StringTable + Strings: + - 'c:\src\llvm-project\build\t.c' + Relocations: + - VirtualAddress: 44 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 48 + SymbolName: main + Type: IMAGE_REL_AMD64_SECTION + - VirtualAddress: 100 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 104 + 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: '{8DABD2A0-28FF-CB43-9BAF-175B77B76414}' + Age: 18 + Name: 'pdb-diff-cl.pdb' + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 33C0C3 +symbols: + - Name: '.debug$S' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 328 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$T' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 564 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 3 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 4021952397 + Number: 0 + - Name: main + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: test/COFF/pdb-type-server-invalid-signature.yaml =================================================================== --- test/COFF/pdb-type-server-invalid-signature.yaml +++ test/COFF/pdb-type-server-invalid-signature.yaml @@ -0,0 +1,140 @@ + +# RUN: cd %S/Inputs +# RUN: yaml2obj %s -o %t.obj +# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s +# RUN: cd %S + +# CHECK: warning: Cannot use debug info for {{.*}}.obj +# CHECK-NEXT: The signature does not match; the file(s) might be out of date + +# Also test a valid match + +# RUN: cd %S/Inputs +# RUN: yaml2obj %S/Inputs/pdb-type-server-valid-signature.yaml -o %t2.obj +# RUN: lld-link %t2.obj -out:%t2.exe -debug -pdb:%t2.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -check-prefix=VALID-SIGNATURE -allow-empty +# RUN: cd %S + +# VALID-SIGNATURE-NOT: warning: Cannot use debug info for {{.*}}.obj +# VALID-SIGNATURE-NOT: The signature does not match; the file(s) might be out of date + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Subsections: + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 3 + DbgStart: 0 + DbgEnd: 2 + FunctionType: 4199 + Flags: [ ] + DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 0 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 3 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'c:\src\llvm-project\build\t.c' + Lines: + - Offset: 0 + LineStart: 1 + IsStatement: true + EndDelta: 0 + Columns: + - !FileChecksums + Checksums: + - FileName: 'c:\src\llvm-project\build\t.c' + Kind: MD5 + Checksum: 270A878DCC1B845655B162F56C4F5020 + - !StringTable + Strings: + - 'c:\src\llvm-project\build\t.c' + Relocations: + - VirtualAddress: 44 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 48 + SymbolName: main + Type: IMAGE_REL_AMD64_SECTION + - VirtualAddress: 100 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 104 + 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: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' + Age: 18 + Name: 'pdb-diff-cl.pdb' + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 33C0C3 +symbols: + - Name: '.debug$S' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 328 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$T' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 564 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 3 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 4021952397 + Number: 0 + - Name: main + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +... Index: test/COFF/pdb-type-server-missing.yaml =================================================================== --- test/COFF/pdb-type-server-missing.yaml +++ test/COFF/pdb-type-server-missing.yaml @@ -1,10 +1,16 @@ # 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. +# Also try linking another OBJ with a reference to the same PDB -# RUN: yaml2obj %s -o %t.obj -# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s +# RUN: yaml2obj %s -o %t1.obj +# RUN: yaml2obj %p/Inputs/pdb-type-server-missing-2.yaml -o %t2.obj +# RUN: lld-link %t1.obj %t2.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s -# CHECK: warning: Type server PDB for {{.*}}.obj is invalid, ignoring debug info. +# CHECK: warning: Cannot use debug info for {{.*}}.obj +# CHECK-NEXT: {{N|n}}o such file or directory + +# CHECK: warning: Cannot use debug info for {{.*}}.obj +# CHECK-NEXT: {{N|n}}o such file or directory --- !COFF header: Index: test/COFF/pdb-type-server-native-errors.yaml =================================================================== --- test/COFF/pdb-type-server-native-errors.yaml +++ test/COFF/pdb-type-server-native-errors.yaml @@ -0,0 +1,130 @@ + +# RUN: cd %S/Inputs +# RUN: yaml2obj %s -o %t.obj +# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s +# RUN: cd %S + +# CHECK: warning: Cannot use debug info for {{.*}}.obj +# CHECK-NEXT: The PDB file is corrupt. MSF superblock is missing + +--- !COFF +header: + Machine: IMAGE_FILE_MACHINE_AMD64 + Characteristics: [ ] +sections: + - Name: '.debug$S' + Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ] + Alignment: 1 + Subsections: + - !Symbols + Records: + - Kind: S_GPROC32_ID + ProcSym: + CodeSize: 3 + DbgStart: 0 + DbgEnd: 2 + FunctionType: 4199 + Flags: [ ] + DisplayName: main + - Kind: S_FRAMEPROC + FrameProcSym: + TotalFrameBytes: 0 + PaddingFrameBytes: 0 + OffsetToPadding: 0 + BytesOfCalleeSavedRegisters: 0 + OffsetOfExceptionHandler: 0 + SectionIdOfExceptionHandler: 0 + Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ] + - Kind: S_PROC_ID_END + ScopeEndSym: + - !Lines + CodeSize: 3 + Flags: [ ] + RelocOffset: 0 + RelocSegment: 0 + Blocks: + - FileName: 'c:\src\llvm-project\build\t.c' + Lines: + - Offset: 0 + LineStart: 1 + IsStatement: true + EndDelta: 0 + Columns: + - !FileChecksums + Checksums: + - FileName: 'c:\src\llvm-project\build\t.c' + Kind: MD5 + Checksum: 270A878DCC1B845655B162F56C4F5020 + - !StringTable + Strings: + - 'c:\src\llvm-project\build\t.c' + Relocations: + - VirtualAddress: 44 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 48 + SymbolName: main + Type: IMAGE_REL_AMD64_SECTION + - VirtualAddress: 100 + SymbolName: main + Type: IMAGE_REL_AMD64_SECREL + - VirtualAddress: 104 + 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: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}' + Age: 18 + Name: 'bad-block-size.pdb' + - Name: '.text$mn' + Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ] + Alignment: 16 + SectionData: 33C0C3 +symbols: + - Name: '.debug$S' + Value: 0 + SectionNumber: 1 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 328 + NumberOfRelocations: 4 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.debug$T' + Value: 0 + SectionNumber: 2 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 564 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 0 + Number: 0 + - Name: '.text$mn' + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_NULL + StorageClass: IMAGE_SYM_CLASS_STATIC + SectionDefinition: + Length: 3 + NumberOfRelocations: 0 + NumberOfLinenumbers: 0 + CheckSum: 4021952397 + Number: 0 + - Name: main + Value: 0 + SectionNumber: 3 + SimpleType: IMAGE_SYM_TYPE_NULL + ComplexType: IMAGE_SYM_DTYPE_FUNCTION + StorageClass: IMAGE_SYM_CLASS_EXTERNAL +...