forked from OSchip/llvm-project
parent
6dd34dc3dd
commit
a93458b050
|
@ -23,6 +23,7 @@
|
|||
#include "llvm/DebugInfo/CodeView/MergingTypeTableBuilder.h"
|
||||
#include "llvm/DebugInfo/CodeView/RecordName.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolDeserializer.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolRecordHelpers.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
|
||||
|
@ -895,39 +896,6 @@ copyAndAlignSymbol(const CVSymbol &Sym, MutableArrayRef<uint8_t> &AlignedMem) {
|
|||
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 {
|
||||
ulittle32_t PtrParent;
|
||||
ulittle32_t PtrEnd;
|
||||
|
@ -1516,7 +1484,7 @@ static void addCommonLinkerModuleSymbols(StringRef Path,
|
|||
std::string ArgStr = quote(Args);
|
||||
EBS.Fields.push_back("cwd");
|
||||
SmallString<64> cwd;
|
||||
if (Config->PDBSourcePath.empty())
|
||||
if (Config->PDBSourcePath.empty())
|
||||
sys::fs::current_path(cwd);
|
||||
else
|
||||
cwd = Config->PDBSourcePath;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN
|
||||
CompileUnitIndex.cpp
|
||||
DWARFLocationExpression.cpp
|
||||
PdbIndex.cpp
|
||||
PdbSymUid.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);
|
||||
}
|
||||
|
||||
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 "llvm/DebugInfo/CodeView/CodeView.h"
|
||||
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
|
||||
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
|
||||
#include "llvm/DebugInfo/PDB/PDBTypes.h"
|
||||
|
@ -119,6 +120,10 @@ LookThroughModifierRecord(llvm::codeview::CVType modifier);
|
|||
|
||||
llvm::StringRef DropNameScope(llvm::StringRef name);
|
||||
|
||||
size_t GetTypeSizeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
|
||||
lldb::BasicType
|
||||
GetCompilerTypeForSimpleKind(llvm::codeview::SimpleTypeKind kind);
|
||||
|
||||
} // namespace npdb
|
||||
} // namespace lldb_private
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
|
||||
#include "DWARFLocationExpression.h"
|
||||
#include "PdbSymUid.h"
|
||||
#include "PdbUtil.h"
|
||||
#include "UdtRecordCompleter.h"
|
||||
|
@ -184,177 +185,6 @@ GetMSInheritance(LazyRandomTypeCollection &tpi, const ClassRecord &record) {
|
|||
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) {
|
||||
switch (kind) {
|
||||
case SimpleTypeKind::Boolean128:
|
||||
|
@ -1197,78 +1027,6 @@ TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId 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) {
|
||||
CVSymbol sym = m_index->symrecords().readRecord(var_id.offset);
|
||||
if (sym.kind() == S_CONSTANT)
|
||||
|
@ -1359,8 +1117,8 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id,
|
|||
Declaration decl;
|
||||
Variable::RangeList ranges;
|
||||
ModuleSP module = GetObjectFile()->GetModule();
|
||||
DWARFExpression location =
|
||||
MakeConstantLocationExpression(constant.Type, tpi, constant, module);
|
||||
DWARFExpression location = MakeConstantLocationExpression(
|
||||
constant.Type, tpi, constant.Value, module);
|
||||
|
||||
VariableSP var_sp = std::make_shared<Variable>(
|
||||
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
|
||||
SimpleTypeSerializer.cpp
|
||||
StringsAndChecksums.cpp
|
||||
SymbolRecordMapping.cpp
|
||||
SymbolDumper.cpp
|
||||
SymbolRecordHelpers.cpp
|
||||
SymbolRecordMapping.cpp
|
||||
SymbolSerializer.cpp
|
||||
TypeDumpVisitor.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