Index: include/llvm/DebugInfo/CodeView/CVDebugRecord.h =================================================================== --- /dev/null +++ include/llvm/DebugInfo/CodeView/CVDebugRecord.h @@ -0,0 +1,55 @@ +//===- CVDebugRecord.h ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_CVDEBUGRECORD_H +#define LLVM_DEBUGINFO_CODEVIEW_CVDEBUGRECORD_H + +#include "llvm/Support/Endian.h" + +namespace llvm { +namespace OMF { +struct Signature { + enum ID { + PDB70 = 0x53445352, // RSDS + PDB20 = 0x3031424e, // NB10 + CV50 = 0x3131424e, // NB11 + CV41 = 0x3930424e, // NB09 + }; + + support::ulittle32_t CVSignature; + support::ulittle32_t Offset; +}; +} + +namespace codeview { +struct PDB70DebugInfo { + support::ulittle32_t CVSignature; + uint8_t Signature[16]; + support::ulittle32_t Age; + // char PDBFileName[]; +}; + +struct PDB20DebugInfo { + support::ulittle32_t CVSignature; + support::ulittle32_t Offset; + support::ulittle32_t Signature; + support::ulittle32_t Age; + // char PDBFileName[]; +}; + +union DebugInfo { + struct OMF::Signature Signature; + struct PDB20DebugInfo PDB20; + struct PDB70DebugInfo PDB70; +}; +} +} + +#endif + Index: include/llvm/Object/COFF.h =================================================================== --- include/llvm/Object/COFF.h +++ include/llvm/Object/COFF.h @@ -15,6 +15,7 @@ #define LLVM_OBJECT_COFF_H #include "llvm/ADT/PointerUnion.h" +#include "llvm/DebugInfo/CodeView/CVDebugRecord.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/COFF.h" #include "llvm/Support/Endian.h" @@ -172,15 +173,6 @@ support::ulittle32_t PointerToRawData; }; -/// Information that is resent in debug_directory::AddressOfRawData if Type is -/// IMAGE_DEBUG_TYPE_CODEVIEW. -struct debug_pdb_info { - support::ulittle32_t Signature; - uint8_t Guid[16]; - support::ulittle32_t Age; - // PDBFileName: The null-terminated PDB file name follows. -}; - template struct import_lookup_table_entry { IntTy Data; @@ -868,14 +860,14 @@ /// Get PDB information out of a codeview debug directory entry. std::error_code getDebugPDBInfo(const debug_directory *DebugDir, - const debug_pdb_info *&Info, + const codeview::DebugInfo *&Info, StringRef &PDBFileName) const; /// Get PDB information from an executable. If the information is not present, /// Info will be set to nullptr and PDBFileName will be empty. An error is /// returned only on corrupt object files. Convenience accessor that can be /// used if the debug directory is not already handy. - std::error_code getDebugPDBInfo(const debug_pdb_info *&Info, + std::error_code getDebugPDBInfo(const codeview::DebugInfo *&Info, StringRef &PDBFileName) const; bool isRelocatableObject() const override; Index: lib/DebugInfo/Symbolize/Symbolize.cpp =================================================================== --- lib/DebugInfo/Symbolize/Symbolize.cpp +++ lib/DebugInfo/Symbolize/Symbolize.cpp @@ -391,10 +391,10 @@ // If this is a COFF object containing PDB info, use a PDBContext to // symbolize. Otherwise, use DWARF. if (auto CoffObject = dyn_cast(Objects.first)) { - const debug_pdb_info *PDBInfo; + const codeview::DebugInfo *DebugInfo; StringRef PDBFileName; - auto EC = CoffObject->getDebugPDBInfo(PDBInfo, PDBFileName); - if (!EC && PDBInfo != nullptr) { + auto EC = CoffObject->getDebugPDBInfo(DebugInfo, PDBFileName); + if (!EC && DebugInfo != nullptr) { using namespace pdb; std::unique_ptr Session; if (auto Err = loadDataForEXE(PDB_ReaderType::DIA, Index: lib/Object/COFFObjectFile.cpp =================================================================== --- lib/Object/COFFObjectFile.cpp +++ lib/Object/COFFObjectFile.cpp @@ -487,17 +487,18 @@ return std::error_code(); } -std::error_code COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir, - const debug_pdb_info *&PDBInfo, - StringRef &PDBFileName) const { +std::error_code +COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir, + const codeview::DebugInfo *&PDBInfo, + StringRef &PDBFileName) const { ArrayRef InfoBytes; if (std::error_code EC = getRvaAndSizeAsBytes( DebugDir->AddressOfRawData, DebugDir->SizeOfData, InfoBytes)) return EC; - if (InfoBytes.size() < sizeof(debug_pdb_info) + 1) + if (InfoBytes.size() < sizeof(*PDBInfo) + 1) return object_error::parse_failed; - PDBInfo = reinterpret_cast(InfoBytes.data()); - InfoBytes = InfoBytes.drop_front(sizeof(debug_pdb_info)); + PDBInfo = reinterpret_cast(InfoBytes.data()); + InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo)); PDBFileName = StringRef(reinterpret_cast(InfoBytes.data()), InfoBytes.size()); // Truncate the name at the first null byte. Ignore any padding. @@ -505,8 +506,9 @@ return std::error_code(); } -std::error_code COFFObjectFile::getDebugPDBInfo(const debug_pdb_info *&PDBInfo, - StringRef &PDBFileName) const { +std::error_code +COFFObjectFile::getDebugPDBInfo(const codeview::DebugInfo *&PDBInfo, + StringRef &PDBFileName) const { for (const debug_directory &D : debug_directories()) if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW) return getDebugPDBInfo(&D, PDBInfo, PDBFileName); Index: tools/llvm-readobj/COFFDumper.cpp =================================================================== --- tools/llvm-readobj/COFFDumper.cpp +++ tools/llvm-readobj/COFFDumper.cpp @@ -670,14 +670,16 @@ W.printHex("AddressOfRawData", D.AddressOfRawData); W.printHex("PointerToRawData", D.PointerToRawData); if (D.Type == COFF::IMAGE_DEBUG_TYPE_CODEVIEW) { - const debug_pdb_info *PDBInfo; + const codeview::DebugInfo *DebugInfo; StringRef PDBFileName; - error(Obj->getDebugPDBInfo(&D, PDBInfo, PDBFileName)); + error(Obj->getDebugPDBInfo(&D, DebugInfo, PDBFileName)); DictScope PDBScope(W, "PDBInfo"); - W.printHex("PDBSignature", PDBInfo->Signature); - W.printBinary("PDBGUID", makeArrayRef(PDBInfo->Guid)); - W.printNumber("PDBAge", PDBInfo->Age); - W.printString("PDBFileName", PDBFileName); + W.printHex("PDBSignature", DebugInfo->Signature.CVSignature); + if (DebugInfo->Signature.CVSignature == OMF::Signature::PDB70) { + W.printBinary("PDBGUID", makeArrayRef(DebugInfo->PDB70.Signature)); + W.printNumber("PDBAge", DebugInfo->PDB70.Age); + W.printString("PDBFileName", PDBFileName); + } } else { // FIXME: Type values of 12 and 13 are commonly observed but are not in // the documented type enum. Figure out what they mean.