stored relative to VFRAME Summary: This patch makes LLDB able to retrieve proper values for function arguments and local variables stored in PDB relative to VFRAME register. Patch contains retrieval of corresponding FPO table entries from PDB and a generic translator from FPO programs to DWARF expressions to get correct VFRAME value. Patch also improves variables-locations.test and makes this test passable on x86. Patch By: leonid.mashinsky Reviewers: zturner, asmith, stella.stamenova, aleksandr.urakov Reviewed By: zturner Subscribers: arphaman, labath, mgorny, aprantl, JDevlieghere, lldb-commits Tags: #lldb Differential Revision: https://reviews.llvm.org/D55122 llvm-svn: 352845
167 lines
5.9 KiB
C++
167 lines
5.9 KiB
C++
//===-- PDBFPOProgramToDWARFExpressionTests.cpp -----------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "gtest/gtest.h"
|
|
|
|
#include "Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.h"
|
|
|
|
#include "lldb/Core/StreamBuffer.h"
|
|
#include "lldb/Expression/DWARFExpression.h"
|
|
#include "lldb/Utility/ArchSpec.h"
|
|
#include "lldb/Utility/DataBufferHeap.h"
|
|
#include "lldb/Utility/DataExtractor.h"
|
|
#include "lldb/Utility/StreamString.h"
|
|
|
|
using namespace lldb;
|
|
using namespace lldb_private;
|
|
using namespace lldb_private::npdb;
|
|
|
|
/// Valid programs tests
|
|
|
|
static void
|
|
CheckValidProgramTranslation(llvm::StringRef fpo_program,
|
|
llvm::StringRef target_register_name,
|
|
llvm::StringRef expected_dwarf_expression) {
|
|
// initial setup
|
|
ArchSpec arch_spec("i686-pc-windows");
|
|
llvm::Triple::ArchType arch_type = arch_spec.GetMachine();
|
|
ByteOrder byte_order = arch_spec.GetByteOrder();
|
|
uint32_t address_size = arch_spec.GetAddressByteSize();
|
|
uint32_t byte_size = arch_spec.GetDataByteSize();
|
|
|
|
// program translation
|
|
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
|
|
ASSERT_TRUE(TranslateFPOProgramToDWARFExpression(
|
|
fpo_program, target_register_name, arch_type, stream));
|
|
|
|
// print dwarf expression to comparable textual representation
|
|
DataBufferSP buffer =
|
|
std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
|
|
DataExtractor extractor(buffer, byte_order, address_size, byte_size);
|
|
|
|
StreamString result_dwarf_expression;
|
|
ASSERT_TRUE(DWARFExpression::PrintDWARFExpression(
|
|
result_dwarf_expression, extractor, address_size, 4, false));
|
|
|
|
// actual check
|
|
ASSERT_STREQ(expected_dwarf_expression.data(),
|
|
result_dwarf_expression.GetString().data());
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentConst) {
|
|
CheckValidProgramTranslation("$T0 0 = ", "$T0", "DW_OP_constu 0x0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentRegisterRef) {
|
|
CheckValidProgramTranslation("$T0 $ebp = ", "$T0", "DW_OP_breg6 +0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionPlus) {
|
|
CheckValidProgramTranslation("$T0 $ebp 4 + = ", "$T0",
|
|
"DW_OP_breg6 +0, DW_OP_constu 0x4, DW_OP_plus ");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionDeref) {
|
|
CheckValidProgramTranslation("$T0 $ebp ^ = ", "$T0",
|
|
"DW_OP_breg6 +0, DW_OP_deref ");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionMinus) {
|
|
CheckValidProgramTranslation(
|
|
"$T0 $ebp 4 - = ", "$T0",
|
|
"DW_OP_breg6 +0, DW_OP_constu 0x4, DW_OP_minus ");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, SingleAssignmentExpressionAlign) {
|
|
CheckValidProgramTranslation("$T0 $ebp 128 @ = ", "$T0",
|
|
"DW_OP_breg6 +0, DW_OP_constu 0x80, DW_OP_lit1 "
|
|
", DW_OP_minus , DW_OP_not , DW_OP_and ");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, MultipleIndependentAssignments) {
|
|
CheckValidProgramTranslation("$T1 1 = $T0 0 =", "$T0", "DW_OP_constu 0x0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, MultipleDependentAssignments) {
|
|
CheckValidProgramTranslation(
|
|
"$T1 $ebp 4 + = $T0 $T1 8 - 128 @ = ", "$T0",
|
|
"DW_OP_breg6 +0, DW_OP_constu 0x4, DW_OP_plus , DW_OP_constu 0x8, "
|
|
"DW_OP_minus , DW_OP_constu 0x80, DW_OP_lit1 , DW_OP_minus , DW_OP_not , "
|
|
"DW_OP_and ");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, DependencyChain) {
|
|
CheckValidProgramTranslation("$T1 0 = $T0 $T1 = $ebp $T0 =", "$ebp",
|
|
"DW_OP_constu 0x0");
|
|
}
|
|
|
|
/// Invalid programs tests
|
|
static void
|
|
CheckInvalidProgramTranslation(llvm::StringRef fpo_program,
|
|
llvm::StringRef target_register_name) {
|
|
// initial setup
|
|
ArchSpec arch_spec("i686-pc-windows");
|
|
llvm::Triple::ArchType arch_type = arch_spec.GetMachine();
|
|
ByteOrder byte_order = arch_spec.GetByteOrder();
|
|
uint32_t address_size = arch_spec.GetAddressByteSize();
|
|
|
|
// program translation
|
|
StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
|
|
EXPECT_FALSE(TranslateFPOProgramToDWARFExpression(
|
|
fpo_program, target_register_name, arch_type, stream));
|
|
EXPECT_EQ(0, stream.GetSize());
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentSingle) {
|
|
CheckInvalidProgramTranslation("$T0 0", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, InvalidAssignmentMultiple) {
|
|
CheckInvalidProgramTranslation("$T1 0 = $T0 0", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, UnknownOp) {
|
|
CheckInvalidProgramTranslation("$T0 $ebp 0 & = ", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpBinary) {
|
|
CheckInvalidProgramTranslation("$T0 0 + = ", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, InvalidOpUnary) {
|
|
CheckInvalidProgramTranslation("$T0 ^ = ", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, MissingTargetRegister) {
|
|
CheckInvalidProgramTranslation("$T1 0 = ", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, UnresolvedRegisterReference) {
|
|
CheckInvalidProgramTranslation("$T0 $abc = ", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests,
|
|
UnresolvedRegisterAssignmentReference) {
|
|
CheckInvalidProgramTranslation("$T2 0 = $T0 $T1 = ", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests,
|
|
UnresolvedCyclicRegisterAssignmentReference) {
|
|
CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = ", "$T0");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests,
|
|
UnresolvedDependentCyclicRegisterAssignmentReference) {
|
|
CheckInvalidProgramTranslation("$T1 $T0 = $T0 $T1 = $T2 $T1 =", "$T2");
|
|
}
|
|
|
|
TEST(PDBFPOProgramToDWARFExpressionTests, UnsupportedRASearch) {
|
|
CheckInvalidProgramTranslation("$T0 .raSearch = ", "$T0");
|
|
}
|