Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
39644 views
//===-- PDBLocationToDWARFExpression.cpp ----------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "PDBLocationToDWARFExpression.h"910#include "lldb/Core/Section.h"11#include "lldb/Core/dwarf.h"12#include "lldb/Expression/DWARFExpression.h"13#include "lldb/Symbol/Variable.h"14#include "lldb/Utility/DataBufferHeap.h"15#include "lldb/Utility/StreamBuffer.h"1617#include "llvm/DebugInfo/CodeView/CodeView.h"18#include "llvm/DebugInfo/PDB/IPDBSession.h"19#include "llvm/DebugInfo/PDB/PDBSymbolData.h"2021#include "Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.h"22#include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h"2324using namespace lldb;25using namespace lldb_private;26using namespace lldb_private::npdb;27using namespace lldb_private::dwarf;28using namespace llvm::pdb;2930static std::unique_ptr<IPDBFrameData>31GetCorrespondingFrameData(const IPDBSession &session,32const Variable::RangeList &ranges) {33auto enumFrameData = session.getFrameData();34if (!enumFrameData)35return nullptr;3637std::unique_ptr<IPDBFrameData> found;38while (auto fd = enumFrameData->getNext()) {39Range<lldb::addr_t, lldb::addr_t> fdRange(fd->getVirtualAddress(),40fd->getLengthBlock());4142for (size_t i = 0; i < ranges.GetSize(); i++) {43auto range = ranges.GetEntryAtIndex(i);44if (!range)45continue;4647if (!range->DoesIntersect(fdRange))48continue;4950found = std::move(fd);5152break;53}54}5556return found;57}5859static bool EmitVFrameEvaluationDWARFExpression(60llvm::StringRef program, llvm::Triple::ArchType arch_type, Stream &stream) {61// VFrame value always stored in $TO pseudo-register62return TranslateFPOProgramToDWARFExpression(program, "$T0", arch_type,63stream);64}6566DWARFExpression ConvertPDBLocationToDWARFExpression(67ModuleSP module, const PDBSymbolData &symbol,68const Variable::RangeList &ranges, bool &is_constant) {69is_constant = true;7071if (!module)72return DWARFExpression();7374const ArchSpec &architecture = module->GetArchitecture();75llvm::Triple::ArchType arch_type = architecture.GetMachine();76ByteOrder byte_order = architecture.GetByteOrder();77uint32_t address_size = architecture.GetAddressByteSize();78uint32_t byte_size = architecture.GetDataByteSize();79if (byte_order == eByteOrderInvalid || address_size == 0)80return DWARFExpression();8182RegisterKind register_kind = eRegisterKindDWARF;83StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);84switch (symbol.getLocationType()) {85case PDB_LocType::Static:86case PDB_LocType::TLS: {87stream.PutHex8(DW_OP_addr);8889SectionList *section_list = module->GetSectionList();90if (!section_list)91return DWARFExpression();9293uint32_t section_id = symbol.getAddressSection();9495auto section = section_list->FindSectionByID(section_id);96if (!section)97return DWARFExpression();9899uint32_t offset = symbol.getAddressOffset();100stream.PutMaxHex64(section->GetFileAddress() + offset, address_size,101byte_order);102103is_constant = false;104105break;106}107case PDB_LocType::RegRel: {108uint32_t reg_num;109auto reg_id = symbol.getRegisterId();110if (reg_id == llvm::codeview::RegisterId::VFRAME) {111if (auto fd = GetCorrespondingFrameData(symbol.getSession(), ranges)) {112if (EmitVFrameEvaluationDWARFExpression(fd->getProgram(), arch_type,113stream)) {114int32_t offset = symbol.getOffset();115stream.PutHex8(DW_OP_consts);116stream.PutSLEB128(offset);117stream.PutHex8(DW_OP_plus);118119register_kind = eRegisterKindLLDB;120121is_constant = false;122break;123}124}125126register_kind = eRegisterKindGeneric;127reg_num = LLDB_REGNUM_GENERIC_FP;128} else {129register_kind = eRegisterKindLLDB;130reg_num = GetLLDBRegisterNumber(arch_type, reg_id);131if (reg_num == LLDB_INVALID_REGNUM)132return DWARFExpression();133}134135if (reg_num > 31) {136stream.PutHex8(DW_OP_bregx);137stream.PutULEB128(reg_num);138} else139stream.PutHex8(DW_OP_breg0 + reg_num);140141int32_t offset = symbol.getOffset();142stream.PutSLEB128(offset);143144is_constant = false;145146break;147}148case PDB_LocType::Enregistered: {149register_kind = eRegisterKindLLDB;150uint32_t reg_num = GetLLDBRegisterNumber(arch_type, symbol.getRegisterId());151if (reg_num == LLDB_INVALID_REGNUM)152return DWARFExpression();153154if (reg_num > 31) {155stream.PutHex8(DW_OP_regx);156stream.PutULEB128(reg_num);157} else158stream.PutHex8(DW_OP_reg0 + reg_num);159160is_constant = false;161162break;163}164case PDB_LocType::Constant: {165Variant value = symbol.getValue();166stream.PutRawBytes(&value.Value, sizeof(value.Value),167endian::InlHostByteOrder());168break;169}170default:171return DWARFExpression();172}173174DataBufferSP buffer =175std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());176DataExtractor extractor(buffer, byte_order, address_size, byte_size);177DWARFExpression result(extractor);178result.SetRegisterKind(register_kind);179180return result;181}182183184