forked from OSchip/llvm-project
parent
6dd34dc3dd
commit
a93458b050
|
@ -23,6 +23,7 @@
|
||||||
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
|
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
|
||||||
#include "llvm/DebugInfo/CodeView/RecordName.h"
|
#include "llvm/DebugInfo/CodeView/RecordName.h"
|
||||||
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
|
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
|
||||||
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
|
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
|
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
|
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
|
||||||
|
@ -895,39 +896,6 @@ copyAndAlignSymbol(const CVSymbol &Sym, MutableArrayRef<uint8_t> &AlignedMem) {
|
||||||
return NewData;
|
return NewData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if this symbol opens a scope. This implies that the symbol has
|
|
||||||
/// "parent" and "end" fields, which contain the offset of the S_END or
|
|
||||||
/// S_INLINESITE_END record.
|
|
||||||
static bool symbolOpensScope(SymbolKind Kind) {
|
|
||||||
switch (Kind) {
|
|
||||||
case SymbolKind::S_GPROC32:
|
|
||||||
case SymbolKind::S_LPROC32:
|
|
||||||
case SymbolKind::S_LPROC32_ID:
|
|
||||||
case SymbolKind::S_GPROC32_ID:
|
|
||||||
case SymbolKind::S_BLOCK32:
|
|
||||||
case SymbolKind::S_SEPCODE:
|
|
||||||
case SymbolKind::S_THUNK32:
|
|
||||||
case SymbolKind::S_INLINESITE:
|
|
||||||
case SymbolKind::S_INLINESITE2:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool symbolEndsScope(SymbolKind Kind) {
|
|
||||||
switch (Kind) {
|
|
||||||
case SymbolKind::S_END:
|
|
||||||
case SymbolKind::S_PROC_ID_END:
|
|
||||||
case SymbolKind::S_INLINESITE_END:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ScopeRecord {
|
struct ScopeRecord {
|
||||||
ulittle32_t PtrParent;
|
ulittle32_t PtrParent;
|
||||||
ulittle32_t PtrEnd;
|
ulittle32_t PtrEnd;
|
||||||
|
@ -1516,7 +1484,7 @@ static void addCommonLinkerModuleSymbols(StringRef Path,
|
||||||
std::string ArgStr = quote(Args);
|
std::string ArgStr = quote(Args);
|
||||||
EBS.Fields.push_back("cwd");
|
EBS.Fields.push_back("cwd");
|
||||||
SmallString<64> cwd;
|
SmallString<64> cwd;
|
||||||
if (Config->PDBSourcePath.empty())
|
if (Config->PDBSourcePath.empty())
|
||||||
sys::fs::current_path(cwd);
|
sys::fs::current_path(cwd);
|
||||||
else
|
else
|
||||||
cwd = Config->PDBSourcePath;
|
cwd = Config->PDBSourcePath;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN
|
add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN
|
||||||
CompileUnitIndex.cpp
|
CompileUnitIndex.cpp
|
||||||
|
DWARFLocationExpression.cpp
|
||||||
PdbIndex.cpp
|
PdbIndex.cpp
|
||||||
PdbSymUid.cpp
|
PdbSymUid.cpp
|
||||||
PdbUtil.cpp
|
PdbUtil.cpp
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
//===-- DWARFLocationExpression.cpp -----------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "DWARFLocationExpression.h"
|
||||||
|
|
||||||
|
#include "lldb/Core/Module.h"
|
||||||
|
#include "lldb/Core/Section.h"
|
||||||
|
#include "lldb/Core/StreamBuffer.h"
|
||||||
|
#include "lldb/Expression/DWARFExpression.h"
|
||||||
|
#include "lldb/Utility/ArchSpec.h"
|
||||||
|
#include "lldb/Utility/DataBufferHeap.h"
|
||||||
|
#include "llvm/BinaryFormat/Dwarf.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
|
||||||
|
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
|
|
||||||
|
#include "PdbUtil.h"
|
||||||
|
|
||||||
|
using namespace lldb;
|
||||||
|
using namespace lldb_private;
|
||||||
|
using namespace lldb_private::npdb;
|
||||||
|
using namespace llvm::codeview;
|
||||||
|
using namespace llvm::pdb;
|
||||||
|
|
||||||
|
static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case SimpleTypeKind::Int128:
|
||||||
|
case SimpleTypeKind::Int64:
|
||||||
|
case SimpleTypeKind::Int64Quad:
|
||||||
|
case SimpleTypeKind::Int32:
|
||||||
|
case SimpleTypeKind::Int32Long:
|
||||||
|
case SimpleTypeKind::Int16:
|
||||||
|
case SimpleTypeKind::Int16Short:
|
||||||
|
case SimpleTypeKind::Float128:
|
||||||
|
case SimpleTypeKind::Float80:
|
||||||
|
case SimpleTypeKind::Float64:
|
||||||
|
case SimpleTypeKind::Float32:
|
||||||
|
case SimpleTypeKind::Float16:
|
||||||
|
case SimpleTypeKind::NarrowCharacter:
|
||||||
|
case SimpleTypeKind::SignedCharacter:
|
||||||
|
case SimpleTypeKind::SByte:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::pair<size_t, bool> GetIntegralTypeInfo(TypeIndex ti,
|
||||||
|
TpiStream &tpi) {
|
||||||
|
if (ti.isSimple()) {
|
||||||
|
SimpleTypeKind stk = ti.getSimpleKind();
|
||||||
|
return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)};
|
||||||
|
}
|
||||||
|
|
||||||
|
CVType cvt = tpi.getType(ti);
|
||||||
|
switch (cvt.kind()) {
|
||||||
|
case LF_MODIFIER: {
|
||||||
|
ModifierRecord mfr;
|
||||||
|
llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr));
|
||||||
|
return GetIntegralTypeInfo(mfr.ModifiedType, tpi);
|
||||||
|
}
|
||||||
|
case LF_POINTER: {
|
||||||
|
PointerRecord pr;
|
||||||
|
llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr));
|
||||||
|
return GetIntegralTypeInfo(pr.ReferentType, tpi);
|
||||||
|
}
|
||||||
|
case LF_ENUM: {
|
||||||
|
EnumRecord er;
|
||||||
|
llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
|
||||||
|
return GetIntegralTypeInfo(er.UnderlyingType, tpi);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false && "Type is not integral!");
|
||||||
|
return {0, false};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename StreamWriter>
|
||||||
|
static DWARFExpression MakeLocationExpressionInternal(lldb::ModuleSP module,
|
||||||
|
StreamWriter &&writer) {
|
||||||
|
const ArchSpec &architecture = module->GetArchitecture();
|
||||||
|
ByteOrder byte_order = architecture.GetByteOrder();
|
||||||
|
uint32_t address_size = architecture.GetAddressByteSize();
|
||||||
|
uint32_t byte_size = architecture.GetDataByteSize();
|
||||||
|
if (byte_order == eByteOrderInvalid || address_size == 0)
|
||||||
|
return DWARFExpression(nullptr);
|
||||||
|
|
||||||
|
RegisterKind register_kind = eRegisterKindDWARF;
|
||||||
|
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
|
||||||
|
|
||||||
|
if (!writer(stream, register_kind))
|
||||||
|
return DWARFExpression(nullptr);
|
||||||
|
|
||||||
|
DataBufferSP buffer =
|
||||||
|
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
|
||||||
|
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
|
||||||
|
DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
|
||||||
|
result.SetRegisterKind(register_kind);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression(
|
||||||
|
uint16_t section, uint32_t offset, ModuleSP module) {
|
||||||
|
assert(section > 0);
|
||||||
|
assert(module);
|
||||||
|
|
||||||
|
return MakeLocationExpressionInternal(
|
||||||
|
module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool {
|
||||||
|
stream.PutHex8(llvm::dwarf::DW_OP_addr);
|
||||||
|
|
||||||
|
SectionList *section_list = module->GetSectionList();
|
||||||
|
assert(section_list);
|
||||||
|
|
||||||
|
// Section indices in PDB are 1-based, but in DWARF they are 0-based, so
|
||||||
|
// we need to subtract 1.
|
||||||
|
uint32_t section_idx = section - 1;
|
||||||
|
if (section_idx >= section_list->GetSize())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto section_ptr = section_list->GetSectionAtIndex(section_idx);
|
||||||
|
if (!section_ptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
stream.PutMaxHex64(section_ptr->GetFileAddress() + offset,
|
||||||
|
stream.GetAddressByteSize(), stream.GetByteOrder());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
DWARFExpression lldb_private::npdb::MakeConstantLocationExpression(
|
||||||
|
TypeIndex underlying_ti, TpiStream &tpi, const llvm::APSInt &constant,
|
||||||
|
ModuleSP module) {
|
||||||
|
const ArchSpec &architecture = module->GetArchitecture();
|
||||||
|
uint32_t address_size = architecture.GetAddressByteSize();
|
||||||
|
|
||||||
|
size_t size = 0;
|
||||||
|
bool is_signed = false;
|
||||||
|
std::tie(size, is_signed) = GetIntegralTypeInfo(underlying_ti, tpi);
|
||||||
|
|
||||||
|
union {
|
||||||
|
llvm::support::little64_t I;
|
||||||
|
llvm::support::ulittle64_t U;
|
||||||
|
} Value;
|
||||||
|
|
||||||
|
std::shared_ptr<DataBufferHeap> buffer = std::make_shared<DataBufferHeap>();
|
||||||
|
buffer->SetByteSize(size);
|
||||||
|
|
||||||
|
llvm::ArrayRef<uint8_t> bytes;
|
||||||
|
if (is_signed) {
|
||||||
|
Value.I = constant.getSExtValue();
|
||||||
|
} else {
|
||||||
|
Value.U = constant.getZExtValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes = llvm::makeArrayRef(reinterpret_cast<const uint8_t *>(&Value), 8)
|
||||||
|
.take_front(size);
|
||||||
|
buffer->CopyData(bytes.data(), size);
|
||||||
|
DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
|
||||||
|
DWARFExpression result(nullptr, extractor, nullptr, 0, size);
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
//===-- DWARFLocationExpression.h -------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
|
||||||
|
#define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
|
||||||
|
|
||||||
|
#include "lldb/lldb-forward.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
class APSInt;
|
||||||
|
namespace codeview {
|
||||||
|
class TypeIndex;
|
||||||
|
}
|
||||||
|
namespace pdb {
|
||||||
|
class TpiStream;
|
||||||
|
}
|
||||||
|
} // namespace llvm
|
||||||
|
namespace lldb_private {
|
||||||
|
namespace npdb {
|
||||||
|
DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset,
|
||||||
|
lldb::ModuleSP module);
|
||||||
|
DWARFExpression MakeConstantLocationExpression(
|
||||||
|
llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi,
|
||||||
|
const llvm::APSInt &constant, lldb::ModuleSP module);
|
||||||
|
} // namespace npdb
|
||||||
|
} // namespace lldb_private
|
||||||
|
|
||||||
|
#endif
|
|
@ -425,3 +425,123 @@ llvm::StringRef lldb_private::npdb::DropNameScope(llvm::StringRef name) {
|
||||||
|
|
||||||
return name.substr(offset + 2);
|
return name.substr(offset + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lldb::BasicType
|
||||||
|
lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case SimpleTypeKind::Boolean128:
|
||||||
|
case SimpleTypeKind::Boolean16:
|
||||||
|
case SimpleTypeKind::Boolean32:
|
||||||
|
case SimpleTypeKind::Boolean64:
|
||||||
|
case SimpleTypeKind::Boolean8:
|
||||||
|
return lldb::eBasicTypeBool;
|
||||||
|
case SimpleTypeKind::Byte:
|
||||||
|
case SimpleTypeKind::UnsignedCharacter:
|
||||||
|
return lldb::eBasicTypeUnsignedChar;
|
||||||
|
case SimpleTypeKind::NarrowCharacter:
|
||||||
|
return lldb::eBasicTypeChar;
|
||||||
|
case SimpleTypeKind::SignedCharacter:
|
||||||
|
case SimpleTypeKind::SByte:
|
||||||
|
return lldb::eBasicTypeSignedChar;
|
||||||
|
case SimpleTypeKind::Character16:
|
||||||
|
return lldb::eBasicTypeChar16;
|
||||||
|
case SimpleTypeKind::Character32:
|
||||||
|
return lldb::eBasicTypeChar32;
|
||||||
|
case SimpleTypeKind::Complex80:
|
||||||
|
return lldb::eBasicTypeLongDoubleComplex;
|
||||||
|
case SimpleTypeKind::Complex64:
|
||||||
|
return lldb::eBasicTypeDoubleComplex;
|
||||||
|
case SimpleTypeKind::Complex32:
|
||||||
|
return lldb::eBasicTypeFloatComplex;
|
||||||
|
case SimpleTypeKind::Float128:
|
||||||
|
case SimpleTypeKind::Float80:
|
||||||
|
return lldb::eBasicTypeLongDouble;
|
||||||
|
case SimpleTypeKind::Float64:
|
||||||
|
return lldb::eBasicTypeDouble;
|
||||||
|
case SimpleTypeKind::Float32:
|
||||||
|
return lldb::eBasicTypeFloat;
|
||||||
|
case SimpleTypeKind::Float16:
|
||||||
|
return lldb::eBasicTypeHalf;
|
||||||
|
case SimpleTypeKind::Int128:
|
||||||
|
return lldb::eBasicTypeInt128;
|
||||||
|
case SimpleTypeKind::Int64:
|
||||||
|
case SimpleTypeKind::Int64Quad:
|
||||||
|
return lldb::eBasicTypeLongLong;
|
||||||
|
case SimpleTypeKind::Int32:
|
||||||
|
return lldb::eBasicTypeInt;
|
||||||
|
case SimpleTypeKind::Int16:
|
||||||
|
case SimpleTypeKind::Int16Short:
|
||||||
|
return lldb::eBasicTypeShort;
|
||||||
|
case SimpleTypeKind::UInt128:
|
||||||
|
return lldb::eBasicTypeUnsignedInt128;
|
||||||
|
case SimpleTypeKind::UInt64:
|
||||||
|
case SimpleTypeKind::UInt64Quad:
|
||||||
|
return lldb::eBasicTypeUnsignedLongLong;
|
||||||
|
case SimpleTypeKind::HResult:
|
||||||
|
case SimpleTypeKind::UInt32:
|
||||||
|
return lldb::eBasicTypeUnsignedInt;
|
||||||
|
case SimpleTypeKind::UInt16:
|
||||||
|
case SimpleTypeKind::UInt16Short:
|
||||||
|
return lldb::eBasicTypeUnsignedShort;
|
||||||
|
case SimpleTypeKind::Int32Long:
|
||||||
|
return lldb::eBasicTypeLong;
|
||||||
|
case SimpleTypeKind::UInt32Long:
|
||||||
|
return lldb::eBasicTypeUnsignedLong;
|
||||||
|
case SimpleTypeKind::Void:
|
||||||
|
return lldb::eBasicTypeVoid;
|
||||||
|
case SimpleTypeKind::WideCharacter:
|
||||||
|
return lldb::eBasicTypeWChar;
|
||||||
|
default:
|
||||||
|
return lldb::eBasicTypeInvalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
|
||||||
|
switch (kind) {
|
||||||
|
case SimpleTypeKind::Boolean128:
|
||||||
|
case SimpleTypeKind::Int128:
|
||||||
|
case SimpleTypeKind::UInt128:
|
||||||
|
case SimpleTypeKind::Float128:
|
||||||
|
return 16;
|
||||||
|
case SimpleTypeKind::Complex80:
|
||||||
|
case SimpleTypeKind::Float80:
|
||||||
|
return 10;
|
||||||
|
case SimpleTypeKind::Boolean64:
|
||||||
|
case SimpleTypeKind::Complex64:
|
||||||
|
case SimpleTypeKind::UInt64:
|
||||||
|
case SimpleTypeKind::UInt64Quad:
|
||||||
|
case SimpleTypeKind::Float64:
|
||||||
|
case SimpleTypeKind::Int64:
|
||||||
|
case SimpleTypeKind::Int64Quad:
|
||||||
|
return 8;
|
||||||
|
case SimpleTypeKind::Boolean32:
|
||||||
|
case SimpleTypeKind::Character32:
|
||||||
|
case SimpleTypeKind::Complex32:
|
||||||
|
case SimpleTypeKind::Float32:
|
||||||
|
case SimpleTypeKind::Int32:
|
||||||
|
case SimpleTypeKind::Int32Long:
|
||||||
|
case SimpleTypeKind::UInt32Long:
|
||||||
|
case SimpleTypeKind::HResult:
|
||||||
|
case SimpleTypeKind::UInt32:
|
||||||
|
return 4;
|
||||||
|
case SimpleTypeKind::Boolean16:
|
||||||
|
case SimpleTypeKind::Character16:
|
||||||
|
case SimpleTypeKind::Float16:
|
||||||
|
case SimpleTypeKind::Int16:
|
||||||
|
case SimpleTypeKind::Int16Short:
|
||||||
|
case SimpleTypeKind::UInt16:
|
||||||
|
case SimpleTypeKind::UInt16Short:
|
||||||
|
case SimpleTypeKind::WideCharacter:
|
||||||
|
return 2;
|
||||||
|
case SimpleTypeKind::Boolean8:
|
||||||
|
case SimpleTypeKind::Byte:
|
||||||
|
case SimpleTypeKind::UnsignedCharacter:
|
||||||
|
case SimpleTypeKind::NarrowCharacter:
|
||||||
|
case SimpleTypeKind::SignedCharacter:
|
||||||
|
case SimpleTypeKind::SByte:
|
||||||
|
return 1;
|
||||||
|
case SimpleTypeKind::Void:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include "lldb/lldb-enumerations.h"
|
#include "lldb/lldb-enumerations.h"
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/CodeView/CodeView.h"
|
||||||
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
||||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||||
#include "llvm/DebugInfo/PDB/PDBTypes.h"
|
#include "llvm/DebugInfo/PDB/PDBTypes.h"
|
||||||
|
@ -119,6 +120,10 @@ LookThroughModifierRecord(llvm::codeview::CVType modifier);
|
||||||
|
|
||||||
llvm::StringRef DropNameScope(llvm::StringRef name);
|
llvm::StringRef DropNameScope(llvm::StringRef name);
|
||||||
|
|
||||||
|
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
|
||||||
|
lldb::BasicType
|
||||||
|
GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
|
||||||
|
|
||||||
} // namespace npdb
|
} // namespace npdb
|
||||||
} // namespace lldb_private
|
} // namespace lldb_private
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "llvm/Support/ErrorOr.h"
|
#include "llvm/Support/ErrorOr.h"
|
||||||
#include "llvm/Support/MemoryBuffer.h"
|
#include "llvm/Support/MemoryBuffer.h"
|
||||||
|
|
||||||
|
#include "DWARFLocationExpression.h"
|
||||||
#include "PdbSymUid.h"
|
#include "PdbSymUid.h"
|
||||||
#include "PdbUtil.h"
|
#include "PdbUtil.h"
|
||||||
#include "UdtRecordCompleter.h"
|
#include "UdtRecordCompleter.h"
|
||||||
|
@ -184,177 +185,6 @@ GetMSInheritance(LazyRandomTypeCollection &tpi, const ClassRecord &record) {
|
||||||
return clang::MSInheritanceAttr::Keyword_single_inheritance;
|
return clang::MSInheritanceAttr::Keyword_single_inheritance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static lldb::BasicType GetCompilerTypeForSimpleKind(SimpleTypeKind kind) {
|
|
||||||
switch (kind) {
|
|
||||||
case SimpleTypeKind::Boolean128:
|
|
||||||
case SimpleTypeKind::Boolean16:
|
|
||||||
case SimpleTypeKind::Boolean32:
|
|
||||||
case SimpleTypeKind::Boolean64:
|
|
||||||
case SimpleTypeKind::Boolean8:
|
|
||||||
return lldb::eBasicTypeBool;
|
|
||||||
case SimpleTypeKind::Byte:
|
|
||||||
case SimpleTypeKind::UnsignedCharacter:
|
|
||||||
return lldb::eBasicTypeUnsignedChar;
|
|
||||||
case SimpleTypeKind::NarrowCharacter:
|
|
||||||
return lldb::eBasicTypeChar;
|
|
||||||
case SimpleTypeKind::SignedCharacter:
|
|
||||||
case SimpleTypeKind::SByte:
|
|
||||||
return lldb::eBasicTypeSignedChar;
|
|
||||||
case SimpleTypeKind::Character16:
|
|
||||||
return lldb::eBasicTypeChar16;
|
|
||||||
case SimpleTypeKind::Character32:
|
|
||||||
return lldb::eBasicTypeChar32;
|
|
||||||
case SimpleTypeKind::Complex80:
|
|
||||||
return lldb::eBasicTypeLongDoubleComplex;
|
|
||||||
case SimpleTypeKind::Complex64:
|
|
||||||
return lldb::eBasicTypeDoubleComplex;
|
|
||||||
case SimpleTypeKind::Complex32:
|
|
||||||
return lldb::eBasicTypeFloatComplex;
|
|
||||||
case SimpleTypeKind::Float128:
|
|
||||||
case SimpleTypeKind::Float80:
|
|
||||||
return lldb::eBasicTypeLongDouble;
|
|
||||||
case SimpleTypeKind::Float64:
|
|
||||||
return lldb::eBasicTypeDouble;
|
|
||||||
case SimpleTypeKind::Float32:
|
|
||||||
return lldb::eBasicTypeFloat;
|
|
||||||
case SimpleTypeKind::Float16:
|
|
||||||
return lldb::eBasicTypeHalf;
|
|
||||||
case SimpleTypeKind::Int128:
|
|
||||||
return lldb::eBasicTypeInt128;
|
|
||||||
case SimpleTypeKind::Int64:
|
|
||||||
case SimpleTypeKind::Int64Quad:
|
|
||||||
return lldb::eBasicTypeLongLong;
|
|
||||||
case SimpleTypeKind::Int32:
|
|
||||||
return lldb::eBasicTypeInt;
|
|
||||||
case SimpleTypeKind::Int16:
|
|
||||||
case SimpleTypeKind::Int16Short:
|
|
||||||
return lldb::eBasicTypeShort;
|
|
||||||
case SimpleTypeKind::UInt128:
|
|
||||||
return lldb::eBasicTypeUnsignedInt128;
|
|
||||||
case SimpleTypeKind::UInt64:
|
|
||||||
case SimpleTypeKind::UInt64Quad:
|
|
||||||
return lldb::eBasicTypeUnsignedLongLong;
|
|
||||||
case SimpleTypeKind::HResult:
|
|
||||||
case SimpleTypeKind::UInt32:
|
|
||||||
return lldb::eBasicTypeUnsignedInt;
|
|
||||||
case SimpleTypeKind::UInt16:
|
|
||||||
case SimpleTypeKind::UInt16Short:
|
|
||||||
return lldb::eBasicTypeUnsignedShort;
|
|
||||||
case SimpleTypeKind::Int32Long:
|
|
||||||
return lldb::eBasicTypeLong;
|
|
||||||
case SimpleTypeKind::UInt32Long:
|
|
||||||
return lldb::eBasicTypeUnsignedLong;
|
|
||||||
case SimpleTypeKind::Void:
|
|
||||||
return lldb::eBasicTypeVoid;
|
|
||||||
case SimpleTypeKind::WideCharacter:
|
|
||||||
return lldb::eBasicTypeWChar;
|
|
||||||
default:
|
|
||||||
return lldb::eBasicTypeInvalid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind) {
|
|
||||||
switch (kind) {
|
|
||||||
case SimpleTypeKind::Int128:
|
|
||||||
case SimpleTypeKind::Int64:
|
|
||||||
case SimpleTypeKind::Int64Quad:
|
|
||||||
case SimpleTypeKind::Int32:
|
|
||||||
case SimpleTypeKind::Int32Long:
|
|
||||||
case SimpleTypeKind::Int16:
|
|
||||||
case SimpleTypeKind::Int16Short:
|
|
||||||
case SimpleTypeKind::Float128:
|
|
||||||
case SimpleTypeKind::Float80:
|
|
||||||
case SimpleTypeKind::Float64:
|
|
||||||
case SimpleTypeKind::Float32:
|
|
||||||
case SimpleTypeKind::Float16:
|
|
||||||
case SimpleTypeKind::NarrowCharacter:
|
|
||||||
case SimpleTypeKind::SignedCharacter:
|
|
||||||
case SimpleTypeKind::SByte:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t GetTypeSizeForSimpleKind(SimpleTypeKind kind) {
|
|
||||||
switch (kind) {
|
|
||||||
case SimpleTypeKind::Boolean128:
|
|
||||||
case SimpleTypeKind::Int128:
|
|
||||||
case SimpleTypeKind::UInt128:
|
|
||||||
case SimpleTypeKind::Float128:
|
|
||||||
return 16;
|
|
||||||
case SimpleTypeKind::Complex80:
|
|
||||||
case SimpleTypeKind::Float80:
|
|
||||||
return 10;
|
|
||||||
case SimpleTypeKind::Boolean64:
|
|
||||||
case SimpleTypeKind::Complex64:
|
|
||||||
case SimpleTypeKind::UInt64:
|
|
||||||
case SimpleTypeKind::UInt64Quad:
|
|
||||||
case SimpleTypeKind::Float64:
|
|
||||||
case SimpleTypeKind::Int64:
|
|
||||||
case SimpleTypeKind::Int64Quad:
|
|
||||||
return 8;
|
|
||||||
case SimpleTypeKind::Boolean32:
|
|
||||||
case SimpleTypeKind::Character32:
|
|
||||||
case SimpleTypeKind::Complex32:
|
|
||||||
case SimpleTypeKind::Float32:
|
|
||||||
case SimpleTypeKind::Int32:
|
|
||||||
case SimpleTypeKind::Int32Long:
|
|
||||||
case SimpleTypeKind::UInt32Long:
|
|
||||||
case SimpleTypeKind::HResult:
|
|
||||||
case SimpleTypeKind::UInt32:
|
|
||||||
return 4;
|
|
||||||
case SimpleTypeKind::Boolean16:
|
|
||||||
case SimpleTypeKind::Character16:
|
|
||||||
case SimpleTypeKind::Float16:
|
|
||||||
case SimpleTypeKind::Int16:
|
|
||||||
case SimpleTypeKind::Int16Short:
|
|
||||||
case SimpleTypeKind::UInt16:
|
|
||||||
case SimpleTypeKind::UInt16Short:
|
|
||||||
case SimpleTypeKind::WideCharacter:
|
|
||||||
return 2;
|
|
||||||
case SimpleTypeKind::Boolean8:
|
|
||||||
case SimpleTypeKind::Byte:
|
|
||||||
case SimpleTypeKind::UnsignedCharacter:
|
|
||||||
case SimpleTypeKind::NarrowCharacter:
|
|
||||||
case SimpleTypeKind::SignedCharacter:
|
|
||||||
case SimpleTypeKind::SByte:
|
|
||||||
return 1;
|
|
||||||
case SimpleTypeKind::Void:
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<size_t, bool> GetIntegralTypeInfo(TypeIndex ti, TpiStream &tpi) {
|
|
||||||
if (ti.isSimple()) {
|
|
||||||
SimpleTypeKind stk = ti.getSimpleKind();
|
|
||||||
return {GetTypeSizeForSimpleKind(stk), IsSimpleTypeSignedInteger(stk)};
|
|
||||||
}
|
|
||||||
|
|
||||||
CVType cvt = tpi.getType(ti);
|
|
||||||
switch (cvt.kind()) {
|
|
||||||
case LF_MODIFIER: {
|
|
||||||
ModifierRecord mfr;
|
|
||||||
llvm::cantFail(TypeDeserializer::deserializeAs<ModifierRecord>(cvt, mfr));
|
|
||||||
return GetIntegralTypeInfo(mfr.ModifiedType, tpi);
|
|
||||||
}
|
|
||||||
case LF_POINTER: {
|
|
||||||
PointerRecord pr;
|
|
||||||
llvm::cantFail(TypeDeserializer::deserializeAs<PointerRecord>(cvt, pr));
|
|
||||||
return GetIntegralTypeInfo(pr.ReferentType, tpi);
|
|
||||||
}
|
|
||||||
case LF_ENUM: {
|
|
||||||
EnumRecord er;
|
|
||||||
llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er));
|
|
||||||
return GetIntegralTypeInfo(er.UnderlyingType, tpi);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
assert(false && "Type is not integral!");
|
|
||||||
return {0, false};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
|
static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) {
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case SimpleTypeKind::Boolean128:
|
case SimpleTypeKind::Boolean128:
|
||||||
|
@ -1197,78 +1027,6 @@ TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) {
|
||||||
return CreateAndCacheType(type_id);
|
return CreateAndCacheType(type_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWARFExpression
|
|
||||||
MakeConstantLocationExpression(TypeIndex underlying_ti, TpiStream &tpi,
|
|
||||||
const ConstantSym &constant, ModuleSP module) {
|
|
||||||
const ArchSpec &architecture = module->GetArchitecture();
|
|
||||||
uint32_t address_size = architecture.GetAddressByteSize();
|
|
||||||
|
|
||||||
size_t size = 0;
|
|
||||||
bool is_signed = false;
|
|
||||||
std::tie(size, is_signed) = GetIntegralTypeInfo(underlying_ti, tpi);
|
|
||||||
|
|
||||||
union {
|
|
||||||
llvm::support::little64_t I;
|
|
||||||
llvm::support::ulittle64_t U;
|
|
||||||
} Value;
|
|
||||||
|
|
||||||
std::shared_ptr<DataBufferHeap> buffer = std::make_shared<DataBufferHeap>();
|
|
||||||
buffer->SetByteSize(size);
|
|
||||||
|
|
||||||
llvm::ArrayRef<uint8_t> bytes;
|
|
||||||
if (is_signed) {
|
|
||||||
Value.I = constant.Value.getSExtValue();
|
|
||||||
} else {
|
|
||||||
Value.U = constant.Value.getZExtValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
bytes = llvm::makeArrayRef(reinterpret_cast<const uint8_t *>(&Value), 8)
|
|
||||||
.take_front(size);
|
|
||||||
buffer->CopyData(bytes.data(), size);
|
|
||||||
DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
|
|
||||||
DWARFExpression result(nullptr, extractor, nullptr, 0, size);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DWARFExpression MakeGlobalLocationExpression(uint16_t section,
|
|
||||||
uint32_t offset,
|
|
||||||
ModuleSP module) {
|
|
||||||
assert(section > 0);
|
|
||||||
assert(module);
|
|
||||||
|
|
||||||
const ArchSpec &architecture = module->GetArchitecture();
|
|
||||||
ByteOrder byte_order = architecture.GetByteOrder();
|
|
||||||
uint32_t address_size = architecture.GetAddressByteSize();
|
|
||||||
uint32_t byte_size = architecture.GetDataByteSize();
|
|
||||||
assert(byte_order != eByteOrderInvalid && address_size != 0);
|
|
||||||
|
|
||||||
RegisterKind register_kind = eRegisterKindDWARF;
|
|
||||||
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
|
|
||||||
stream.PutHex8(DW_OP_addr);
|
|
||||||
|
|
||||||
SectionList *section_list = module->GetSectionList();
|
|
||||||
assert(section_list);
|
|
||||||
|
|
||||||
// Section indices in PDB are 1-based, but in DWARF they are 0-based, so we
|
|
||||||
// need to subtract 1.
|
|
||||||
uint32_t section_idx = section - 1;
|
|
||||||
if (section_idx >= section_list->GetSize())
|
|
||||||
return DWARFExpression(nullptr);
|
|
||||||
|
|
||||||
auto section_ptr = section_list->GetSectionAtIndex(section_idx);
|
|
||||||
if (!section_ptr)
|
|
||||||
return DWARFExpression(nullptr);
|
|
||||||
|
|
||||||
stream.PutMaxHex64(section_ptr->GetFileAddress() + offset, address_size,
|
|
||||||
byte_order);
|
|
||||||
DataBufferSP buffer =
|
|
||||||
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
|
|
||||||
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
|
|
||||||
DWARFExpression result(module, extractor, nullptr, 0, buffer->GetByteSize());
|
|
||||||
result.SetRegisterKind(register_kind);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
|
VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
|
||||||
CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
|
CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
|
||||||
if (sym.kind() == S_CONSTANT)
|
if (sym.kind() == S_CONSTANT)
|
||||||
|
@ -1359,8 +1117,8 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
|
||||||
Declaration decl;
|
Declaration decl;
|
||||||
Variable::RangeList ranges;
|
Variable::RangeList ranges;
|
||||||
ModuleSP module = GetObjectFile()->GetModule();
|
ModuleSP module = GetObjectFile()->GetModule();
|
||||||
DWARFExpression location =
|
DWARFExpression location = MakeConstantLocationExpression(
|
||||||
MakeConstantLocationExpression(constant.Type, tpi, constant, module);
|
constant.Type, tpi, constant.Value, module);
|
||||||
|
|
||||||
VariableSP var_sp = std::make_shared<Variable>(
|
VariableSP var_sp = std::make_shared<Variable>(
|
||||||
toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
|
toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(),
|
||||||
|
|
|
@ -0,0 +1,57 @@
|
||||||
|
//===- SymbolRecordHelpers.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_SYMBOLRECORDHELPERS_H
|
||||||
|
#define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORDHELPERS_H
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
namespace codeview {
|
||||||
|
/// Return true if this symbol opens a scope. This implies that the symbol has
|
||||||
|
/// "parent" and "end" fields, which contain the offset of the S_END or
|
||||||
|
/// S_INLINESITE_END record.
|
||||||
|
inline bool symbolOpensScope(SymbolKind Kind) {
|
||||||
|
switch (Kind) {
|
||||||
|
case SymbolKind::S_GPROC32:
|
||||||
|
case SymbolKind::S_LPROC32:
|
||||||
|
case SymbolKind::S_LPROC32_ID:
|
||||||
|
case SymbolKind::S_GPROC32_ID:
|
||||||
|
case SymbolKind::S_BLOCK32:
|
||||||
|
case SymbolKind::S_SEPCODE:
|
||||||
|
case SymbolKind::S_THUNK32:
|
||||||
|
case SymbolKind::S_INLINESITE:
|
||||||
|
case SymbolKind::S_INLINESITE2:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return true if this ssymbol ends a scope.
|
||||||
|
inline bool symbolEndsScope(SymbolKind Kind) {
|
||||||
|
switch (Kind) {
|
||||||
|
case SymbolKind::S_END:
|
||||||
|
case SymbolKind::S_PROC_ID_END:
|
||||||
|
case SymbolKind::S_INLINESITE_END:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given a symbol P for which symbolOpensScope(P) == true, return the
|
||||||
|
/// corresponding end offset.
|
||||||
|
uint32_t getScopeEndOffset(const CVSymbol &symbol);
|
||||||
|
} // namespace codeview
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
|
@ -27,8 +27,9 @@ add_llvm_library(LLVMDebugInfoCodeView
|
||||||
RecordSerialization.cpp
|
RecordSerialization.cpp
|
||||||
SimpleTypeSerializer.cpp
|
SimpleTypeSerializer.cpp
|
||||||
StringsAndChecksums.cpp
|
StringsAndChecksums.cpp
|
||||||
SymbolRecordMapping.cpp
|
|
||||||
SymbolDumper.cpp
|
SymbolDumper.cpp
|
||||||
|
SymbolRecordHelpers.cpp
|
||||||
|
SymbolRecordMapping.cpp
|
||||||
SymbolSerializer.cpp
|
SymbolSerializer.cpp
|
||||||
TypeDumpVisitor.cpp
|
TypeDumpVisitor.cpp
|
||||||
TypeIndex.cpp
|
TypeIndex.cpp
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
//===- SymbolRecordHelpers.cpp ----------------------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
|
||||||
|
|
||||||
|
#include "llvm/ADT/SmallVector.h"
|
||||||
|
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace llvm::codeview;
|
||||||
|
|
||||||
|
template <typename RecordT> RecordT createRecord(const CVSymbol &sym) {
|
||||||
|
RecordT record(static_cast<SymbolRecordKind>(sym.kind()));
|
||||||
|
cantFail(SymbolDeserializer::deserializeAs<RecordT>(sym, record));
|
||||||
|
return record;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
llvm::codeview::getScopeEndOffset(const llvm::codeview::CVSymbol &Sym) {
|
||||||
|
assert(symbolOpensScope(Sym.kind()));
|
||||||
|
switch (Sym.kind()) {
|
||||||
|
case SymbolKind::S_GPROC32:
|
||||||
|
case SymbolKind::S_LPROC32:
|
||||||
|
case SymbolKind::S_GPROC32_ID:
|
||||||
|
case SymbolKind::S_LPROC32_ID:
|
||||||
|
case SymbolKind::S_LPROC32_DPC:
|
||||||
|
case SymbolKind::S_LPROC32_DPC_ID: {
|
||||||
|
ProcSym Proc = createRecord<ProcSym>(Sym);
|
||||||
|
return Proc.End;
|
||||||
|
}
|
||||||
|
case SymbolKind::S_BLOCK32: {
|
||||||
|
BlockSym Block = createRecord<BlockSym>(Sym);
|
||||||
|
return Block.End;
|
||||||
|
}
|
||||||
|
case SymbolKind::S_THUNK32: {
|
||||||
|
Thunk32Sym Thunk = createRecord<Thunk32Sym>(Sym);
|
||||||
|
return Thunk.End;
|
||||||
|
}
|
||||||
|
case SymbolKind::S_INLINESITE: {
|
||||||
|
InlineSiteSym Site = createRecord<InlineSiteSym>(Sym);
|
||||||
|
return Site.End;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false && "Unknown record type");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue