Path: blob/main/contrib/llvm-project/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp
39644 views
//===-- PdbFPOProgramToDWARFExpression.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 "PdbFPOProgramToDWARFExpression.h"9#include "CodeViewRegisterMapping.h"1011#include "lldb/Symbol/PostfixExpression.h"12#include "lldb/Utility/LLDBAssert.h"13#include "lldb/Utility/Stream.h"14#include "llvm/ADT/DenseMap.h"1516#include "llvm/ADT/StringExtras.h"17#include "llvm/DebugInfo/CodeView/CodeView.h"18#include "llvm/DebugInfo/CodeView/EnumTables.h"19#include "llvm/Support/ScopedPrinter.h"2021using namespace lldb;22using namespace lldb_private;23using namespace lldb_private::postfix;2425static uint32_t ResolveLLDBRegisterNum(llvm::StringRef reg_name, llvm::Triple::ArchType arch_type) {26// lookup register name to get lldb register number27llvm::codeview::CPUType cpu_type;28switch (arch_type) {29case llvm::Triple::ArchType::aarch64:30cpu_type = llvm::codeview::CPUType::ARM64;31break;3233default:34cpu_type = llvm::codeview::CPUType::X64;35break;36}3738llvm::ArrayRef<llvm::EnumEntry<uint16_t>> register_names =39llvm::codeview::getRegisterNames(cpu_type);40auto it = llvm::find_if(41register_names,42[®_name](const llvm::EnumEntry<uint16_t> ®ister_entry) {43return reg_name.compare_insensitive(register_entry.Name) == 0;44});4546if (it == register_names.end())47return LLDB_INVALID_REGNUM;4849auto reg_id = static_cast<llvm::codeview::RegisterId>(it->Value);50return npdb::GetLLDBRegisterNumber(arch_type, reg_id);51}5253static Node *ResolveFPOProgram(llvm::StringRef program,54llvm::StringRef register_name,55llvm::Triple::ArchType arch_type,56llvm::BumpPtrAllocator &alloc) {57std::vector<std::pair<llvm::StringRef, Node *>> parsed =58postfix::ParseFPOProgram(program, alloc);5960for (auto it = parsed.begin(), end = parsed.end(); it != end; ++it) {61// Emplace valid dependent subtrees to make target assignment independent62// from predecessors. Resolve all other SymbolNodes as registers.63bool success =64ResolveSymbols(it->second, [&](SymbolNode &symbol) -> Node * {65for (const auto &pair : llvm::make_range(parsed.begin(), it)) {66if (pair.first == symbol.GetName())67return pair.second;68}6970uint32_t reg_num =71ResolveLLDBRegisterNum(symbol.GetName().drop_front(1), arch_type);7273if (reg_num == LLDB_INVALID_REGNUM)74return nullptr;7576return MakeNode<RegisterNode>(alloc, reg_num);77});78if (!success)79return nullptr;8081if (it->first == register_name) {82// found target assignment program - no need to parse further83return it->second;84}85}8687return nullptr;88}8990bool lldb_private::npdb::TranslateFPOProgramToDWARFExpression(91llvm::StringRef program, llvm::StringRef register_name,92llvm::Triple::ArchType arch_type, Stream &stream) {93llvm::BumpPtrAllocator node_alloc;94Node *target_program =95ResolveFPOProgram(program, register_name, arch_type, node_alloc);96if (target_program == nullptr) {97return false;98}99100ToDWARF(*target_program, stream);101return true;102}103104105