diff options
-rw-r--r-- | llvm/include/llvm/DebugInfo/CodeView/CVDebugRecord.h | 55 | ||||
-rw-r--r-- | llvm/include/llvm/Object/COFF.h | 14 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/Symbolize/Symbolize.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 18 | ||||
-rw-r--r-- | llvm/tools/llvm-readobj/COFFDumper.cpp | 14 |
5 files changed, 79 insertions, 28 deletions
diff --git a/llvm/include/llvm/DebugInfo/CodeView/CVDebugRecord.h b/llvm/include/llvm/DebugInfo/CodeView/CVDebugRecord.h new file mode 100644 index 00000000000..5a0bb4266ba --- /dev/null +++ b/llvm/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 : uint32_t { + 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 + diff --git a/llvm/include/llvm/Object/COFF.h b/llvm/include/llvm/Object/COFF.h index d34cd0b73de..c5637477658 100644 --- a/llvm/include/llvm/Object/COFF.h +++ b/llvm/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 @@ struct debug_directory { 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 <typename IntTy> struct import_lookup_table_entry { IntTy Data; @@ -868,14 +860,14 @@ public: /// 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; diff --git a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp index adbe0cb69ed..31a0086f6fc 100644 --- a/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp +++ b/llvm/lib/DebugInfo/Symbolize/Symbolize.cpp @@ -391,10 +391,10 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { // If this is a COFF object containing PDB info, use a PDBContext to // symbolize. Otherwise, use DWARF. if (auto CoffObject = dyn_cast<COFFObjectFile>(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<IPDBSession> Session; if (auto Err = loadDataForEXE(PDB_ReaderType::DIA, diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 668f4d04a51..a43eca6f976 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -487,17 +487,18 @@ std::error_code COFFObjectFile::getHintName(uint32_t Rva, uint16_t &Hint, 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<uint8_t> 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<const debug_pdb_info *>(InfoBytes.data()); - InfoBytes = InfoBytes.drop_front(sizeof(debug_pdb_info)); + PDBInfo = reinterpret_cast<const codeview::DebugInfo *>(InfoBytes.data()); + InfoBytes = InfoBytes.drop_front(sizeof(*PDBInfo)); PDBFileName = StringRef(reinterpret_cast<const char *>(InfoBytes.data()), InfoBytes.size()); // Truncate the name at the first null byte. Ignore any padding. @@ -505,8 +506,9 @@ std::error_code COFFObjectFile::getDebugPDBInfo(const debug_directory *DebugDir, 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); diff --git a/llvm/tools/llvm-readobj/COFFDumper.cpp b/llvm/tools/llvm-readobj/COFFDumper.cpp index 28addfabd6e..529ebabaaf7 100644 --- a/llvm/tools/llvm-readobj/COFFDumper.cpp +++ b/llvm/tools/llvm-readobj/COFFDumper.cpp @@ -670,14 +670,16 @@ void COFFDumper::printCOFFDebugDirectory() { 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. |