mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-24 11:36:10 +00:00
CodeView: extract the OMF Directory Header
The DebugDirectory contains a pointer to the CodeView info structure which is a derivative of the OMF debug directory. The structure has evolved a bit over time, and PDB 2.0 used a slightly different definition from PDB 7.0. Both of these are specific to CodeView and not COFF. Reflect this by moving the structure definitions into the DebugInfo/CodeView headers. Define a generic DebugInfo union type that can be used to pass around a reference to the DebugInfo irrespective of the versioning. NFC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278075 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f7c3c99642
commit
b79146f48d
55
include/llvm/DebugInfo/CodeView/CVDebugRecord.h
Normal file
55
include/llvm/DebugInfo/CodeView/CVDebugRecord.h
Normal file
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user