1 //===-- NativeProcessProtocolTest.cpp ---------------------------*- C++ -*-===// 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 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 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 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 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 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 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 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 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 }