| // Copyright 2019 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SRC_DEVELOPER_DEBUG_ZXDB_EXPR_VIRTUAL_BASE_TEST_SETUP_H_ | |
| #define SRC_DEVELOPER_DEBUG_ZXDB_EXPR_VIRTUAL_BASE_TEST_SETUP_H_ | |
| #include <memory> | |
| #include <vector> | |
| #include "src/developer/debug/zxdb/symbols/arch.h" | |
| #include "src/developer/debug/zxdb/symbols/collection.h" | |
| #include "src/developer/debug/zxdb/symbols/elf_symbol.h" | |
| #include "src/developer/debug/zxdb/symbols/index_test_support.h" | |
| #include "src/developer/debug/zxdb/symbols/process_symbols_test_setup.h" | |
| #include "src/developer/debug/zxdb/symbols/symbol.h" | |
| namespace zxdb { | |
| class MockModuleSymbols; | |
| class MockSymbolDataProvider; | |
| struct TestIndexedSymbol; | |
| // Sets up the required information for a test involving a base class with a virtual function and | |
| // a class derived from it. The necessary symbols for the vtables all need to be set properly. | |
| // | |
| // It is designed to work with a module loaded at the address provided by ProcessSymbolsTestSetup. | |
| // | |
| // Example: | |
| // | |
| // VirtualBaseTestSetup setup(...); | |
| // ExprValue ptr(setup::kBaseAddress, setup.base_class_ptr); | |
| // | |
| // This will be a pointer to the Base class that is actually implemented by the Derived class. | |
| struct VirtualBaseTestSetup { | |
| VirtualBaseTestSetup(MockSymbolDataProvider* data_provider, | |
| MockModuleSymbols* mock_module_symbols); | |
| // Clang uses "vtbl_ptr_type*" as the type for the vtable pointers at the beginning of a virtual | |
| // class. Clang defines the vtable as being pointers to functions "int()", so a pointer to a table | |
| // is a pointer to that. For simplicity, we define the vtable entry type as uint64_t instead of | |
| // "int()". | |
| fxl::RefPtr<Type> vtbl_entry_type; | |
| fxl::RefPtr<Type> vtbl_ptr_type; | |
| fxl::RefPtr<Type> vtbl_ptr_type_ptr; | |
| // Virtual base class collection type. It has one member "base_i" = kBaseI defined below. | |
| fxl::RefPtr<Collection> base_class; | |
| std::unique_ptr<TestIndexedSymbol> base_class_indexed; | |
| fxl::RefPtr<ModifiedType> base_class_ptr; // BaseClass* | |
| fxl::RefPtr<ModifiedType> base_class_ref; // BaseClass& | |
| // This starts the base class at an offset inside of the derived one, leaving empty bytes at the | |
| // beginning. This simulates having multiple inheritance and tests the offset management. | |
| static constexpr uint32_t kBaseOffset = 4; | |
| // Derived class type. It has one member "derived_i" = kDerivedI defined below. | |
| fxl::RefPtr<Collection> derived_class; | |
| std::unique_ptr<TestIndexedSymbol> derived_class_indexed; | |
| // Address of the derived class' vtable. | |
| static constexpr TargetPointer kVtableRelativeAddress = 0x2000; | |
| static constexpr TargetPointer kVtableAbsoluteAddress = | |
| ProcessSymbolsTestSetup::kDefaultLoadAddress + kVtableRelativeAddress; | |
| // Absolute address of the derived and base class in memory. | |
| static constexpr TargetPointer kDerivedAddress = 0x1000; | |
| static constexpr TargetPointer kBaseAddress = kDerivedAddress + kBaseOffset; | |
| // Symbols for the vtables. Make kVtableAddress can point to one of these to determine the type of | |
| // the class. | |
| fxl::RefPtr<ElfSymbol> base_vtable; | |
| fxl::RefPtr<ElfSymbol> derived_vtable; | |
| // The values of the two data members in the derived_data. | |
| static const char* kBaseIName; // member name = "base_i". | |
| static constexpr uint32_t kBaseI = 42; | |
| static const char* kDerivedIName; // member name = "derived_i". | |
| static constexpr uint32_t kDerivedI = 99; | |
| // Sample data for the derived class. This will have a vtable address of kVtableAddress and | |
| // will be injected into the mock eval context at kDerivedAddress. | |
| std::vector<uint8_t> derived_data; | |
| }; | |
| } // namespace zxdb | |
| #endif // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_VIRTUAL_BASE_TEST_SETUP_H_ |