1 //===-- NativeProcessTestUtils.cpp ------------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H
10 #define LLDB_UNITTESTS_TESTINGSUPPORT_HOST_NATIVEPROCESSTESTUTILS_H
12 #include "lldb/Host/common/NativeProcessProtocol.h"
13 #include "llvm/Testing/Support/Error.h"
14 #include "gmock/gmock.h"
16 using namespace lldb_private
;
18 using namespace testing
;
20 namespace lldb_private
{
22 class MockDelegate
: public NativeProcessProtocol::NativeDelegate
{
24 MOCK_METHOD1(InitializeDelegate
, void(NativeProcessProtocol
*Process
));
25 MOCK_METHOD2(ProcessStateChanged
,
26 void(NativeProcessProtocol
*Process
, StateType State
));
27 MOCK_METHOD1(DidExec
, void(NativeProcessProtocol
*Process
));
28 MOCK_METHOD2(NewSubprocessImpl
,
29 void(NativeProcessProtocol
*parent_process
,
30 std::unique_ptr
<NativeProcessProtocol
> &child_process
));
31 // This is a hack to avoid MOCK_METHOD2 incompatibility with std::unique_ptr
33 void NewSubprocess(NativeProcessProtocol
*parent_process
,
34 std::unique_ptr
<NativeProcessProtocol
> child_process
) {
35 NewSubprocessImpl(parent_process
, child_process
);
39 // NB: This class doesn't use the override keyword to avoid
40 // -Winconsistent-missing-override warnings from the compiler. The
41 // inconsistency comes from the overriding definitions in the MOCK_*** macros.
42 template <typename T
> class MockProcess
: public T
{
44 MockProcess(NativeProcessProtocol::NativeDelegate
&Delegate
,
45 const ArchSpec
&Arch
, lldb::pid_t Pid
= 1)
46 : T(Pid
, -1, Delegate
), Arch(Arch
) {}
48 MOCK_METHOD1(Resume
, Status(const ResumeActionList
&ResumeActions
));
49 MOCK_METHOD0(Halt
, Status());
50 MOCK_METHOD0(Detach
, Status());
51 MOCK_METHOD1(Signal
, Status(int Signo
));
52 MOCK_METHOD0(Kill
, Status());
53 MOCK_METHOD0(GetSharedLibraryInfoAddress
, addr_t());
54 MOCK_METHOD0(UpdateThreads
, size_t());
55 MOCK_CONST_METHOD0(GetAuxvData
,
56 llvm::ErrorOr
<std::unique_ptr
<llvm::MemoryBuffer
>>());
57 MOCK_METHOD2(GetLoadedModuleFileSpec
,
58 Status(const char *ModulePath
, FileSpec
&Spec
));
59 MOCK_METHOD2(GetFileLoadAddress
,
60 Status(const llvm::StringRef
&FileName
, addr_t
&Addr
));
62 const ArchSpec
&GetArchitecture() const /*override*/ { return Arch
; }
63 Status
SetBreakpoint(lldb::addr_t Addr
, uint32_t Size
,
64 bool Hardware
) /*override*/ {
66 return this->SetHardwareBreakpoint(Addr
, Size
);
68 return this->SetSoftwareBreakpoint(Addr
, Size
);
71 // Redirect base class Read/Write Memory methods to functions whose signatures
72 // are more mock-friendly.
73 Status
ReadMemory(addr_t Addr
, void *Buf
, size_t Size
,
74 size_t &BytesRead
) /*override*/ {
75 auto ExpectedMemory
= this->ReadMemory(Addr
, Size
);
76 if (!ExpectedMemory
) {
78 return Status(ExpectedMemory
.takeError());
80 BytesRead
= ExpectedMemory
->size();
81 assert(BytesRead
<= Size
);
82 std::memcpy(Buf
, ExpectedMemory
->data(), BytesRead
);
86 Status
WriteMemory(addr_t Addr
, const void *Buf
, size_t Size
,
87 size_t &BytesWritten
) /*override*/ {
88 auto ExpectedBytes
= this->WriteMemory(
89 Addr
, llvm::ArrayRef(static_cast<const uint8_t *>(Buf
), Size
));
92 return Status(ExpectedBytes
.takeError());
94 BytesWritten
= *ExpectedBytes
;
98 MOCK_METHOD2(ReadMemory
,
99 llvm::Expected
<std::vector
<uint8_t>>(addr_t Addr
, size_t Size
));
100 MOCK_METHOD2(WriteMemory
,
101 llvm::Expected
<size_t>(addr_t Addr
,
102 llvm::ArrayRef
<uint8_t> Data
));
104 using T::GetSoftwareBreakpointTrapOpcode
;
105 llvm::Expected
<std::vector
<uint8_t>> ReadMemoryWithoutTrap(addr_t Addr
,
107 std::vector
<uint8_t> Data(Size
, 0);
110 T::ReadMemoryWithoutTrap(Addr
, Data
.data(), Data
.size(), BytesRead
);
113 Data
.resize(BytesRead
);
114 return std::move(Data
);
123 FakeMemory(llvm::ArrayRef
<uint8_t> Data
, addr_t start_addr
= 0)
124 : Data(Data
), m_start_addr(start_addr
) {}
126 FakeMemory(const void *Data
, size_t data_size
, addr_t start_addr
= 0)
127 : Data((const uint8_t *)Data
, ((const uint8_t *)Data
) + data_size
),
128 m_start_addr(start_addr
) {}
130 llvm::Expected
<std::vector
<uint8_t>> Read(addr_t Addr
, size_t Size
) {
131 Addr
-= m_start_addr
;
132 if (Addr
>= Data
.size())
133 return llvm::createStringError(llvm::inconvertibleErrorCode(),
134 "Address out of range.");
135 Size
= std::min(Size
, Data
.size() - (size_t)Addr
);
136 auto Begin
= std::next(Data
.begin(), Addr
);
137 return std::vector
<uint8_t>(Begin
, std::next(Begin
, Size
));
140 llvm::Expected
<size_t> Write(addr_t Addr
, llvm::ArrayRef
<uint8_t> Chunk
) {
141 Addr
-= m_start_addr
;
142 if (Addr
>= Data
.size())
143 return llvm::createStringError(llvm::inconvertibleErrorCode(),
144 "Address out of range.");
145 size_t Size
= std::min(Chunk
.size(), Data
.size() - (size_t)Addr
);
146 std::copy_n(Chunk
.begin(), Size
, &Data
[Addr
]);
151 std::vector
<uint8_t> Data
;
154 } // namespace lldb_private