From a93458b050ef7158d848252d294b4ada62f4e479 Mon Sep 17 00:00:00 2001 From: Zachary Turner Date: Thu, 6 Dec 2018 17:49:15 +0000 Subject: [PATCH] [PDB] Move some code around. NFC. llvm-svn: 348505 --- lld/COFF/PDB.cpp | 36 +-- .../Plugins/SymbolFile/NativePDB/CMakeLists.txt | 1 + .../NativePDB/DWARFLocationExpression.cpp | 170 ++++++++++++++ .../SymbolFile/NativePDB/DWARFLocationExpression.h | 34 +++ .../Plugins/SymbolFile/NativePDB/PdbUtil.cpp | 120 ++++++++++ lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h | 5 + .../SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 248 +-------------------- .../llvm/DebugInfo/CodeView/SymbolRecordHelpers.h | 57 +++++ llvm/lib/DebugInfo/CodeView/CMakeLists.txt | 3 +- .../lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp | 53 +++++ 10 files changed, 447 insertions(+), 280 deletions(-) create mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp create mode 100644 lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h create mode 100644 llvm/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h create mode 100644 llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp diff --git a/lld/COFF/PDB.cpp b/lld/COFF/PDB.cpp index faf32a2..ccce0e7 100644 --- a/lld/COFF/PDB.cpp +++ b/lld/COFF/PDB.cpp @@ -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 &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; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt b/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt index e9f792d..72ebfc3 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CMakeLists.txt @@ -1,5 +1,6 @@ add_lldb_library(lldbPluginSymbolFileNativePDB PLUGIN CompileUnitIndex.cpp + DWARFLocationExpression.cpp PdbIndex.cpp PdbSymUid.cpp PdbUtil.cpp diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp new file mode 100644 index 0000000..1bad4c0 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.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 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(cvt, mfr)); + return GetIntegralTypeInfo(mfr.ModifiedType, tpi); + } + case LF_POINTER: { + PointerRecord pr; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, pr)); + return GetIntegralTypeInfo(pr.ReferentType, tpi); + } + case LF_ENUM: { + EnumRecord er; + llvm::cantFail(TypeDeserializer::deserializeAs(cvt, er)); + return GetIntegralTypeInfo(er.UnderlyingType, tpi); + } + default: + assert(false && "Type is not integral!"); + return {0, false}; + } +} + +template +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(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 buffer = std::make_shared(); + buffer->SetByteSize(size); + + llvm::ArrayRef bytes; + if (is_signed) { + Value.I = constant.getSExtValue(); + } else { + Value.U = constant.getZExtValue(); + } + + bytes = llvm::makeArrayRef(reinterpret_cast(&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; +} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h new file mode 100644 index 0000000..d251282 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h @@ -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 diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index e00190e..4c19b61 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -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; + } +} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index 6a5797c..c01e419 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -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 diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 9310e7c..59d1d04 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -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 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(cvt, mfr)); - return GetIntegralTypeInfo(mfr.ModifiedType, tpi); - } - case LF_POINTER: { - PointerRecord pr; - llvm::cantFail(TypeDeserializer::deserializeAs(cvt, pr)); - return GetIntegralTypeInfo(pr.ReferentType, tpi); - } - case LF_ENUM: { - EnumRecord er; - llvm::cantFail(TypeDeserializer::deserializeAs(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 buffer = std::make_shared(); - buffer->SetByteSize(size); - - llvm::ArrayRef bytes; - if (is_signed) { - Value.I = constant.Value.getSExtValue(); - } else { - Value.U = constant.Value.getZExtValue(); - } - - bytes = llvm::makeArrayRef(reinterpret_cast(&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(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( toOpaqueUid(var_id), constant.Name.str().c_str(), global_name.c_str(), diff --git a/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h new file mode 100644 index 0000000..8c01bd4 --- /dev/null +++ b/llvm/include/llvm/DebugInfo/CodeView/SymbolRecordHelpers.h @@ -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 diff --git a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt index e1bdffd..1610ca4 100644 --- a/llvm/lib/DebugInfo/CodeView/CMakeLists.txt +++ b/llvm/lib/DebugInfo/CodeView/CMakeLists.txt @@ -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 diff --git a/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp b/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.cpp new file mode 100644 index 0000000..f44fc8f --- /dev/null +++ b/llvm/lib/DebugInfo/CodeView/SymbolRecordHelpers.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 RecordT createRecord(const CVSymbol &sym) { + RecordT record(static_cast(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs(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(Sym); + return Proc.End; + } + case SymbolKind::S_BLOCK32: { + BlockSym Block = createRecord(Sym); + return Block.End; + } + case SymbolKind::S_THUNK32: { + Thunk32Sym Thunk = createRecord(Sym); + return Thunk.End; + } + case SymbolKind::S_INLINESITE: { + InlineSiteSym Site = createRecord(Sym); + return Site.End; + } + default: + assert(false && "Unknown record type"); + return 0; + } +} \ No newline at end of file -- 2.7.4