xref: /llvm-project/lldb/unittests/Host/NativeProcessProtocolTest.cpp (revision 808142876c10b52e7ee57cdc6dcf0acc5c97c1b7)
1 //===-- NativeProcessProtocolTest.cpp -------------------------------------===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "TestingSupport/Host/NativeProcessTestUtils.h"
10 
11 #include "lldb/Host/common/NativeProcessProtocol.h"
12 #include "llvm/Support/Process.h"
13 #include "llvm/Testing/Support/Error.h"
14 #include "gmock/gmock.h"
15 
16 using namespace lldb_private;
17 using namespace lldb;
18 using namespace testing;
19 
TEST(NativeProcessProtocolTest,SetBreakpoint)20 TEST(NativeProcessProtocolTest, SetBreakpoint) {
21   NiceMock<MockDelegate> DummyDelegate;
22   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
23                                              ArchSpec("x86_64-pc-linux"));
24   auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));
25   InSequence S;
26   EXPECT_CALL(Process, ReadMemory(0x47, 1))
27       .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));
28   EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));
29   EXPECT_CALL(Process, ReadMemory(0x47, 1)).WillOnce(Return(ByMove(Trap)));
30   EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
31                     llvm::Succeeded());
32 }
33 
TEST(NativeProcessProtocolTest,SetBreakpointFailRead)34 TEST(NativeProcessProtocolTest, SetBreakpointFailRead) {
35   NiceMock<MockDelegate> DummyDelegate;
36   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
37                                              ArchSpec("x86_64-pc-linux"));
38   EXPECT_CALL(Process, ReadMemory(0x47, 1))
39       .WillOnce(Return(ByMove(
40           llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));
41   EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
42                     llvm::Failed());
43 }
44 
TEST(NativeProcessProtocolTest,SetBreakpointFailWrite)45 TEST(NativeProcessProtocolTest, SetBreakpointFailWrite) {
46   NiceMock<MockDelegate> DummyDelegate;
47   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
48                                              ArchSpec("x86_64-pc-linux"));
49   auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));
50   InSequence S;
51   EXPECT_CALL(Process, ReadMemory(0x47, 1))
52       .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));
53   EXPECT_CALL(Process, WriteMemory(0x47, Trap))
54       .WillOnce(Return(ByMove(
55           llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));
56   EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
57                     llvm::Failed());
58 }
59 
TEST(NativeProcessProtocolTest,SetBreakpointFailVerify)60 TEST(NativeProcessProtocolTest, SetBreakpointFailVerify) {
61   NiceMock<MockDelegate> DummyDelegate;
62   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
63                                              ArchSpec("x86_64-pc-linux"));
64   auto Trap = cantFail(Process.GetSoftwareBreakpointTrapOpcode(1));
65   InSequence S;
66   EXPECT_CALL(Process, ReadMemory(0x47, 1))
67       .WillOnce(Return(ByMove(std::vector<uint8_t>{0xbb})));
68   EXPECT_CALL(Process, WriteMemory(0x47, Trap)).WillOnce(Return(ByMove(1)));
69   EXPECT_CALL(Process, ReadMemory(0x47, 1))
70       .WillOnce(Return(ByMove(
71           llvm::createStringError(llvm::inconvertibleErrorCode(), "Foo"))));
72   EXPECT_THAT_ERROR(Process.SetBreakpoint(0x47, 0, false).ToError(),
73                     llvm::Failed());
74 }
75 
TEST(NativeProcessProtocolTest,ReadMemoryWithoutTrap)76 TEST(NativeProcessProtocolTest, ReadMemoryWithoutTrap) {
77   NiceMock<MockDelegate> DummyDelegate;
78   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
79                                              ArchSpec("aarch64-pc-linux"));
80   FakeMemory M{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
81   EXPECT_CALL(Process, ReadMemory(_, _))
82       .WillRepeatedly(Invoke(&M, &FakeMemory::Read));
83   EXPECT_CALL(Process, WriteMemory(_, _))
84       .WillRepeatedly(Invoke(&M, &FakeMemory::Write));
85 
86   EXPECT_THAT_ERROR(Process.SetBreakpoint(0x4, 0, false).ToError(),
87                     llvm::Succeeded());
88   EXPECT_THAT_EXPECTED(
89       Process.ReadMemoryWithoutTrap(0, 10),
90       llvm::HasValue(std::vector<uint8_t>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));
91   EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(0, 6),
92                        llvm::HasValue(std::vector<uint8_t>{0, 1, 2, 3, 4, 5}));
93   EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 4),
94                        llvm::HasValue(std::vector<uint8_t>{6, 7, 8, 9}));
95   EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(6, 2),
96                        llvm::HasValue(std::vector<uint8_t>{6, 7}));
97   EXPECT_THAT_EXPECTED(Process.ReadMemoryWithoutTrap(4, 2),
98                        llvm::HasValue(std::vector<uint8_t>{4, 5}));
99 }
100 
TEST(NativeProcessProtocolTest,ReadCStringFromMemory)101 TEST(NativeProcessProtocolTest, ReadCStringFromMemory) {
102   NiceMock<MockDelegate> DummyDelegate;
103   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
104                                              ArchSpec("aarch64-pc-linux"));
105   FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'});
106   EXPECT_CALL(Process, ReadMemory(_, _))
107       .WillRepeatedly(Invoke(&M, &FakeMemory::Read));
108 
109   char string[1024];
110   size_t bytes_read;
111   EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory(
112                            0x0, &string[0], sizeof(string), bytes_read),
113                        llvm::HasValue(llvm::StringRef("hello")));
114   EXPECT_EQ(bytes_read, 6UL);
115 }
116 
TEST(NativeProcessProtocolTest,ReadCStringFromMemory_MaxSize)117 TEST(NativeProcessProtocolTest, ReadCStringFromMemory_MaxSize) {
118   NiceMock<MockDelegate> DummyDelegate;
119   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
120                                              ArchSpec("aarch64-pc-linux"));
121   FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'});
122   EXPECT_CALL(Process, ReadMemory(_, _))
123       .WillRepeatedly(Invoke(&M, &FakeMemory::Read));
124 
125   char string[4];
126   size_t bytes_read;
127   EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory(
128                            0x0, &string[0], sizeof(string), bytes_read),
129                        llvm::HasValue(llvm::StringRef("hel")));
130   EXPECT_EQ(bytes_read, 3UL);
131 }
132 
TEST(NativeProcessProtocolTest,ReadCStringFromMemory_CrossPageBoundary)133 TEST(NativeProcessProtocolTest, ReadCStringFromMemory_CrossPageBoundary) {
134   NiceMock<MockDelegate> DummyDelegate;
135   MockProcess<NativeProcessProtocol> Process(DummyDelegate,
136                                              ArchSpec("aarch64-pc-linux"));
137   unsigned string_start = llvm::sys::Process::getPageSizeEstimate() - 3;
138   FakeMemory M({'h', 'e', 'l', 'l', 'o', 0, 'w', 'o'}, string_start);
139   EXPECT_CALL(Process, ReadMemory(_, _))
140       .WillRepeatedly(Invoke(&M, &FakeMemory::Read));
141 
142   char string[1024];
143   size_t bytes_read;
144   EXPECT_THAT_EXPECTED(Process.ReadCStringFromMemory(string_start, &string[0],
145                                                      sizeof(string),
146                                                      bytes_read),
147                        llvm::HasValue(llvm::StringRef("hello")));
148   EXPECT_EQ(bytes_read, 6UL);
149 }