Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/Host/common/NativeProcessProtocol.cpp
39606 views
1
//===-- NativeProcessProtocol.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 "lldb/Host/common/NativeProcessProtocol.h"
10
#include "lldb/Host/Host.h"
11
#include "lldb/Host/common/NativeBreakpointList.h"
12
#include "lldb/Host/common/NativeRegisterContext.h"
13
#include "lldb/Host/common/NativeThreadProtocol.h"
14
#include "lldb/Utility/LLDBAssert.h"
15
#include "lldb/Utility/LLDBLog.h"
16
#include "lldb/Utility/Log.h"
17
#include "lldb/Utility/State.h"
18
#include "lldb/lldb-enumerations.h"
19
20
#include "llvm/Support/Process.h"
21
#include <optional>
22
23
using namespace lldb;
24
using namespace lldb_private;
25
26
// NativeProcessProtocol Members
27
28
NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
29
NativeDelegate &delegate)
30
: m_pid(pid), m_delegate(delegate), m_terminal_fd(terminal_fd) {
31
delegate.InitializeDelegate(this);
32
}
33
34
lldb_private::Status NativeProcessProtocol::Interrupt() {
35
Status error;
36
#if !defined(SIGSTOP)
37
error.SetErrorString("local host does not support signaling");
38
return error;
39
#else
40
return Signal(SIGSTOP);
41
#endif
42
}
43
44
Status NativeProcessProtocol::IgnoreSignals(llvm::ArrayRef<int> signals) {
45
m_signals_to_ignore.clear();
46
m_signals_to_ignore.insert(signals.begin(), signals.end());
47
return Status();
48
}
49
50
lldb_private::Status
51
NativeProcessProtocol::GetMemoryRegionInfo(lldb::addr_t load_addr,
52
MemoryRegionInfo &range_info) {
53
// Default: not implemented.
54
return Status("not implemented");
55
}
56
57
lldb_private::Status
58
NativeProcessProtocol::ReadMemoryTags(int32_t type, lldb::addr_t addr,
59
size_t len, std::vector<uint8_t> &tags) {
60
return Status("not implemented");
61
}
62
63
lldb_private::Status
64
NativeProcessProtocol::WriteMemoryTags(int32_t type, lldb::addr_t addr,
65
size_t len,
66
const std::vector<uint8_t> &tags) {
67
return Status("not implemented");
68
}
69
70
std::optional<WaitStatus> NativeProcessProtocol::GetExitStatus() {
71
if (m_state == lldb::eStateExited)
72
return m_exit_status;
73
74
return std::nullopt;
75
}
76
77
bool NativeProcessProtocol::SetExitStatus(WaitStatus status,
78
bool bNotifyStateChange) {
79
Log *log = GetLog(LLDBLog::Process);
80
LLDB_LOG(log, "status = {0}, notify = {1}", status, bNotifyStateChange);
81
82
// Exit status already set
83
if (m_state == lldb::eStateExited) {
84
if (m_exit_status)
85
LLDB_LOG(log, "exit status already set to {0}", *m_exit_status);
86
else
87
LLDB_LOG(log, "state is exited, but status not set");
88
return false;
89
}
90
91
m_state = lldb::eStateExited;
92
m_exit_status = status;
93
94
if (bNotifyStateChange)
95
SynchronouslyNotifyProcessStateChanged(lldb::eStateExited);
96
97
return true;
98
}
99
100
NativeThreadProtocol *NativeProcessProtocol::GetThreadAtIndex(uint32_t idx) {
101
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
102
if (idx < m_threads.size())
103
return m_threads[idx].get();
104
return nullptr;
105
}
106
107
NativeThreadProtocol *
108
NativeProcessProtocol::GetThreadByIDUnlocked(lldb::tid_t tid) {
109
for (const auto &thread : m_threads) {
110
if (thread->GetID() == tid)
111
return thread.get();
112
}
113
return nullptr;
114
}
115
116
NativeThreadProtocol *NativeProcessProtocol::GetThreadByID(lldb::tid_t tid) {
117
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
118
return GetThreadByIDUnlocked(tid);
119
}
120
121
bool NativeProcessProtocol::IsAlive() const {
122
return m_state != eStateDetached && m_state != eStateExited &&
123
m_state != eStateInvalid && m_state != eStateUnloaded;
124
}
125
126
const NativeWatchpointList::WatchpointMap &
127
NativeProcessProtocol::GetWatchpointMap() const {
128
return m_watchpoint_list.GetWatchpointMap();
129
}
130
131
std::optional<std::pair<uint32_t, uint32_t>>
132
NativeProcessProtocol::GetHardwareDebugSupportInfo() const {
133
Log *log = GetLog(LLDBLog::Process);
134
135
// get any thread
136
NativeThreadProtocol *thread(
137
const_cast<NativeProcessProtocol *>(this)->GetThreadAtIndex(0));
138
if (!thread) {
139
LLDB_LOG(log, "failed to find a thread to grab a NativeRegisterContext!");
140
return std::nullopt;
141
}
142
143
NativeRegisterContext &reg_ctx = thread->GetRegisterContext();
144
return std::make_pair(reg_ctx.NumSupportedHardwareBreakpoints(),
145
reg_ctx.NumSupportedHardwareWatchpoints());
146
}
147
148
Status NativeProcessProtocol::SetWatchpoint(lldb::addr_t addr, size_t size,
149
uint32_t watch_flags,
150
bool hardware) {
151
// This default implementation assumes setting the watchpoint for the process
152
// will require setting the watchpoint for each of the threads. Furthermore,
153
// it will track watchpoints set for the process and will add them to each
154
// thread that is attached to via the (FIXME implement) OnThreadAttached ()
155
// method.
156
157
Log *log = GetLog(LLDBLog::Process);
158
159
// Update the thread list
160
UpdateThreads();
161
162
// Keep track of the threads we successfully set the watchpoint for. If one
163
// of the thread watchpoint setting operations fails, back off and remove the
164
// watchpoint for all the threads that were successfully set so we get back
165
// to a consistent state.
166
std::vector<NativeThreadProtocol *> watchpoint_established_threads;
167
168
// Tell each thread to set a watchpoint. In the event that hardware
169
// watchpoints are requested but the SetWatchpoint fails, try to set a
170
// software watchpoint as a fallback. It's conceivable that if there are
171
// more threads than hardware watchpoints available, some of the threads will
172
// fail to set hardware watchpoints while software ones may be available.
173
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
174
for (const auto &thread : m_threads) {
175
assert(thread && "thread list should not have a NULL thread!");
176
177
Status thread_error =
178
thread->SetWatchpoint(addr, size, watch_flags, hardware);
179
if (thread_error.Fail() && hardware) {
180
// Try software watchpoints since we failed on hardware watchpoint
181
// setting and we may have just run out of hardware watchpoints.
182
thread_error = thread->SetWatchpoint(addr, size, watch_flags, false);
183
if (thread_error.Success())
184
LLDB_LOG(log,
185
"hardware watchpoint requested but software watchpoint set");
186
}
187
188
if (thread_error.Success()) {
189
// Remember that we set this watchpoint successfully in case we need to
190
// clear it later.
191
watchpoint_established_threads.push_back(thread.get());
192
} else {
193
// Unset the watchpoint for each thread we successfully set so that we
194
// get back to a consistent state of "not set" for the watchpoint.
195
for (auto unwatch_thread_sp : watchpoint_established_threads) {
196
Status remove_error = unwatch_thread_sp->RemoveWatchpoint(addr);
197
if (remove_error.Fail())
198
LLDB_LOG(log, "RemoveWatchpoint failed for pid={0}, tid={1}: {2}",
199
GetID(), unwatch_thread_sp->GetID(), remove_error);
200
}
201
202
return thread_error;
203
}
204
}
205
return m_watchpoint_list.Add(addr, size, watch_flags, hardware);
206
}
207
208
Status NativeProcessProtocol::RemoveWatchpoint(lldb::addr_t addr) {
209
// Update the thread list
210
UpdateThreads();
211
212
Status overall_error;
213
214
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
215
for (const auto &thread : m_threads) {
216
assert(thread && "thread list should not have a NULL thread!");
217
218
const Status thread_error = thread->RemoveWatchpoint(addr);
219
if (thread_error.Fail()) {
220
// Keep track of the first thread error if any threads fail. We want to
221
// try to remove the watchpoint from every thread, though, even if one or
222
// more have errors.
223
if (!overall_error.Fail())
224
overall_error = thread_error;
225
}
226
}
227
const Status error = m_watchpoint_list.Remove(addr);
228
return overall_error.Fail() ? overall_error : error;
229
}
230
231
const HardwareBreakpointMap &
232
NativeProcessProtocol::GetHardwareBreakpointMap() const {
233
return m_hw_breakpoints_map;
234
}
235
236
Status NativeProcessProtocol::SetHardwareBreakpoint(lldb::addr_t addr,
237
size_t size) {
238
// This default implementation assumes setting a hardware breakpoint for this
239
// process will require setting same hardware breakpoint for each of its
240
// existing threads. New thread will do the same once created.
241
Log *log = GetLog(LLDBLog::Process);
242
243
// Update the thread list
244
UpdateThreads();
245
246
// Exit here if target does not have required hardware breakpoint capability.
247
auto hw_debug_cap = GetHardwareDebugSupportInfo();
248
249
if (hw_debug_cap == std::nullopt || hw_debug_cap->first == 0 ||
250
hw_debug_cap->first <= m_hw_breakpoints_map.size())
251
return Status("Target does not have required no of hardware breakpoints");
252
253
// Vector below stores all thread pointer for which we have we successfully
254
// set this hardware breakpoint. If any of the current process threads fails
255
// to set this hardware breakpoint then roll back and remove this breakpoint
256
// for all the threads that had already set it successfully.
257
std::vector<NativeThreadProtocol *> breakpoint_established_threads;
258
259
// Request to set a hardware breakpoint for each of current process threads.
260
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
261
for (const auto &thread : m_threads) {
262
assert(thread && "thread list should not have a NULL thread!");
263
264
Status thread_error = thread->SetHardwareBreakpoint(addr, size);
265
if (thread_error.Success()) {
266
// Remember that we set this breakpoint successfully in case we need to
267
// clear it later.
268
breakpoint_established_threads.push_back(thread.get());
269
} else {
270
// Unset the breakpoint for each thread we successfully set so that we
271
// get back to a consistent state of "not set" for this hardware
272
// breakpoint.
273
for (auto rollback_thread_sp : breakpoint_established_threads) {
274
Status remove_error =
275
rollback_thread_sp->RemoveHardwareBreakpoint(addr);
276
if (remove_error.Fail())
277
LLDB_LOG(log,
278
"RemoveHardwareBreakpoint failed for pid={0}, tid={1}: {2}",
279
GetID(), rollback_thread_sp->GetID(), remove_error);
280
}
281
282
return thread_error;
283
}
284
}
285
286
// Register new hardware breakpoint into hardware breakpoints map of current
287
// process.
288
m_hw_breakpoints_map[addr] = {addr, size};
289
290
return Status();
291
}
292
293
Status NativeProcessProtocol::RemoveHardwareBreakpoint(lldb::addr_t addr) {
294
// Update the thread list
295
UpdateThreads();
296
297
Status error;
298
299
std::lock_guard<std::recursive_mutex> guard(m_threads_mutex);
300
for (const auto &thread : m_threads) {
301
assert(thread && "thread list should not have a NULL thread!");
302
error = thread->RemoveHardwareBreakpoint(addr);
303
}
304
305
// Also remove from hardware breakpoint map of current process.
306
m_hw_breakpoints_map.erase(addr);
307
308
return error;
309
}
310
311
void NativeProcessProtocol::SynchronouslyNotifyProcessStateChanged(
312
lldb::StateType state) {
313
Log *log = GetLog(LLDBLog::Process);
314
315
m_delegate.ProcessStateChanged(this, state);
316
317
switch (state) {
318
case eStateStopped:
319
case eStateExited:
320
case eStateCrashed:
321
NotifyTracersProcessDidStop();
322
break;
323
default:
324
break;
325
}
326
327
LLDB_LOG(log, "sent state notification [{0}] from process {1}", state,
328
GetID());
329
}
330
331
void NativeProcessProtocol::NotifyDidExec() {
332
Log *log = GetLog(LLDBLog::Process);
333
LLDB_LOG(log, "process {0} exec()ed", GetID());
334
335
m_software_breakpoints.clear();
336
337
m_delegate.DidExec(this);
338
}
339
340
Status NativeProcessProtocol::SetSoftwareBreakpoint(lldb::addr_t addr,
341
uint32_t size_hint) {
342
Log *log = GetLog(LLDBLog::Breakpoints);
343
LLDB_LOG(log, "addr = {0:x}, size_hint = {1}", addr, size_hint);
344
345
auto it = m_software_breakpoints.find(addr);
346
if (it != m_software_breakpoints.end()) {
347
++it->second.ref_count;
348
return Status();
349
}
350
auto expected_bkpt = EnableSoftwareBreakpoint(addr, size_hint);
351
if (!expected_bkpt)
352
return Status(expected_bkpt.takeError());
353
354
m_software_breakpoints.emplace(addr, std::move(*expected_bkpt));
355
return Status();
356
}
357
358
Status NativeProcessProtocol::RemoveSoftwareBreakpoint(lldb::addr_t addr) {
359
Log *log = GetLog(LLDBLog::Breakpoints);
360
LLDB_LOG(log, "addr = {0:x}", addr);
361
auto it = m_software_breakpoints.find(addr);
362
if (it == m_software_breakpoints.end())
363
return Status("Breakpoint not found.");
364
assert(it->second.ref_count > 0);
365
if (--it->second.ref_count > 0)
366
return Status();
367
368
// This is the last reference. Let's remove the breakpoint.
369
Status error;
370
371
// Clear a software breakpoint instruction
372
llvm::SmallVector<uint8_t, 4> curr_break_op(
373
it->second.breakpoint_opcodes.size(), 0);
374
375
// Read the breakpoint opcode
376
size_t bytes_read = 0;
377
error =
378
ReadMemory(addr, curr_break_op.data(), curr_break_op.size(), bytes_read);
379
if (error.Fail() || bytes_read < curr_break_op.size()) {
380
return Status("addr=0x%" PRIx64
381
": tried to read %zu bytes but only read %zu",
382
addr, curr_break_op.size(), bytes_read);
383
}
384
const auto &saved = it->second.saved_opcodes;
385
// Make sure the breakpoint opcode exists at this address
386
if (llvm::ArrayRef(curr_break_op) != it->second.breakpoint_opcodes) {
387
if (curr_break_op != it->second.saved_opcodes)
388
return Status("Original breakpoint trap is no longer in memory.");
389
LLDB_LOG(log,
390
"Saved opcodes ({0:@[x]}) have already been restored at {1:x}.",
391
llvm::make_range(saved.begin(), saved.end()), addr);
392
} else {
393
// We found a valid breakpoint opcode at this address, now restore the
394
// saved opcode.
395
size_t bytes_written = 0;
396
error = WriteMemory(addr, saved.data(), saved.size(), bytes_written);
397
if (error.Fail() || bytes_written < saved.size()) {
398
return Status("addr=0x%" PRIx64
399
": tried to write %zu bytes but only wrote %zu",
400
addr, saved.size(), bytes_written);
401
}
402
403
// Verify that our original opcode made it back to the inferior
404
llvm::SmallVector<uint8_t, 4> verify_opcode(saved.size(), 0);
405
size_t verify_bytes_read = 0;
406
error = ReadMemory(addr, verify_opcode.data(), verify_opcode.size(),
407
verify_bytes_read);
408
if (error.Fail() || verify_bytes_read < verify_opcode.size()) {
409
return Status("addr=0x%" PRIx64
410
": tried to read %zu verification bytes but only read %zu",
411
addr, verify_opcode.size(), verify_bytes_read);
412
}
413
if (verify_opcode != saved)
414
LLDB_LOG(log, "Restoring bytes at {0:x}: {1:@[x]}", addr,
415
llvm::make_range(saved.begin(), saved.end()));
416
}
417
418
m_software_breakpoints.erase(it);
419
return Status();
420
}
421
422
llvm::Expected<NativeProcessProtocol::SoftwareBreakpoint>
423
NativeProcessProtocol::EnableSoftwareBreakpoint(lldb::addr_t addr,
424
uint32_t size_hint) {
425
Log *log = GetLog(LLDBLog::Breakpoints);
426
427
auto expected_trap = GetSoftwareBreakpointTrapOpcode(size_hint);
428
if (!expected_trap)
429
return expected_trap.takeError();
430
431
llvm::SmallVector<uint8_t, 4> saved_opcode_bytes(expected_trap->size(), 0);
432
// Save the original opcodes by reading them so we can restore later.
433
size_t bytes_read = 0;
434
Status error = ReadMemory(addr, saved_opcode_bytes.data(),
435
saved_opcode_bytes.size(), bytes_read);
436
if (error.Fail())
437
return error.ToError();
438
439
// Ensure we read as many bytes as we expected.
440
if (bytes_read != saved_opcode_bytes.size()) {
441
return llvm::createStringError(
442
llvm::inconvertibleErrorCode(),
443
"Failed to read memory while attempting to set breakpoint: attempted "
444
"to read {0} bytes but only read {1}.",
445
saved_opcode_bytes.size(), bytes_read);
446
}
447
448
LLDB_LOG(
449
log, "Overwriting bytes at {0:x}: {1:@[x]}", addr,
450
llvm::make_range(saved_opcode_bytes.begin(), saved_opcode_bytes.end()));
451
452
// Write a software breakpoint in place of the original opcode.
453
size_t bytes_written = 0;
454
error = WriteMemory(addr, expected_trap->data(), expected_trap->size(),
455
bytes_written);
456
if (error.Fail())
457
return error.ToError();
458
459
// Ensure we wrote as many bytes as we expected.
460
if (bytes_written != expected_trap->size()) {
461
return llvm::createStringError(
462
llvm::inconvertibleErrorCode(),
463
"Failed write memory while attempting to set "
464
"breakpoint: attempted to write {0} bytes but only wrote {1}",
465
expected_trap->size(), bytes_written);
466
}
467
468
llvm::SmallVector<uint8_t, 4> verify_bp_opcode_bytes(expected_trap->size(),
469
0);
470
size_t verify_bytes_read = 0;
471
error = ReadMemory(addr, verify_bp_opcode_bytes.data(),
472
verify_bp_opcode_bytes.size(), verify_bytes_read);
473
if (error.Fail())
474
return error.ToError();
475
476
// Ensure we read as many verification bytes as we expected.
477
if (verify_bytes_read != verify_bp_opcode_bytes.size()) {
478
return llvm::createStringError(
479
llvm::inconvertibleErrorCode(),
480
"Failed to read memory while "
481
"attempting to verify breakpoint: attempted to read {0} bytes "
482
"but only read {1}",
483
verify_bp_opcode_bytes.size(), verify_bytes_read);
484
}
485
486
if (llvm::ArrayRef(verify_bp_opcode_bytes.data(), verify_bytes_read) !=
487
*expected_trap) {
488
return llvm::createStringError(
489
llvm::inconvertibleErrorCode(),
490
"Verification of software breakpoint "
491
"writing failed - trap opcodes not successfully read back "
492
"after writing when setting breakpoint at {0:x}",
493
addr);
494
}
495
496
LLDB_LOG(log, "addr = {0:x}: SUCCESS", addr);
497
return SoftwareBreakpoint{1, saved_opcode_bytes, *expected_trap};
498
}
499
500
llvm::Expected<llvm::ArrayRef<uint8_t>>
501
NativeProcessProtocol::GetSoftwareBreakpointTrapOpcode(size_t size_hint) {
502
static const uint8_t g_aarch64_opcode[] = {0x00, 0x00, 0x20, 0xd4};
503
static const uint8_t g_i386_opcode[] = {0xCC};
504
static const uint8_t g_mips64_opcode[] = {0x00, 0x00, 0x00, 0x0d};
505
static const uint8_t g_mips64el_opcode[] = {0x0d, 0x00, 0x00, 0x00};
506
static const uint8_t g_msp430_opcode[] = {0x43, 0x43};
507
static const uint8_t g_s390x_opcode[] = {0x00, 0x01};
508
static const uint8_t g_ppc_opcode[] = {0x7f, 0xe0, 0x00, 0x08}; // trap
509
static const uint8_t g_ppcle_opcode[] = {0x08, 0x00, 0xe0, 0x7f}; // trap
510
static const uint8_t g_riscv_opcode[] = {0x73, 0x00, 0x10, 0x00}; // ebreak
511
static const uint8_t g_riscv_opcode_c[] = {0x02, 0x90}; // c.ebreak
512
static const uint8_t g_loongarch_opcode[] = {0x05, 0x00, 0x2a,
513
0x00}; // break 0x5
514
515
switch (GetArchitecture().GetMachine()) {
516
case llvm::Triple::aarch64:
517
case llvm::Triple::aarch64_32:
518
return llvm::ArrayRef(g_aarch64_opcode);
519
520
case llvm::Triple::x86:
521
case llvm::Triple::x86_64:
522
return llvm::ArrayRef(g_i386_opcode);
523
524
case llvm::Triple::mips:
525
case llvm::Triple::mips64:
526
return llvm::ArrayRef(g_mips64_opcode);
527
528
case llvm::Triple::mipsel:
529
case llvm::Triple::mips64el:
530
return llvm::ArrayRef(g_mips64el_opcode);
531
532
case llvm::Triple::msp430:
533
return llvm::ArrayRef(g_msp430_opcode);
534
535
case llvm::Triple::systemz:
536
return llvm::ArrayRef(g_s390x_opcode);
537
538
case llvm::Triple::ppc:
539
case llvm::Triple::ppc64:
540
return llvm::ArrayRef(g_ppc_opcode);
541
542
case llvm::Triple::ppc64le:
543
return llvm::ArrayRef(g_ppcle_opcode);
544
545
case llvm::Triple::riscv32:
546
case llvm::Triple::riscv64: {
547
return size_hint == 2 ? llvm::ArrayRef(g_riscv_opcode_c)
548
: llvm::ArrayRef(g_riscv_opcode);
549
}
550
551
case llvm::Triple::loongarch32:
552
case llvm::Triple::loongarch64:
553
return llvm::ArrayRef(g_loongarch_opcode);
554
555
default:
556
return llvm::createStringError(llvm::inconvertibleErrorCode(),
557
"CPU type not supported!");
558
}
559
}
560
561
size_t NativeProcessProtocol::GetSoftwareBreakpointPCOffset() {
562
switch (GetArchitecture().GetMachine()) {
563
case llvm::Triple::x86:
564
case llvm::Triple::x86_64:
565
case llvm::Triple::systemz:
566
// These architectures report increment the PC after breakpoint is hit.
567
return cantFail(GetSoftwareBreakpointTrapOpcode(0)).size();
568
569
case llvm::Triple::arm:
570
case llvm::Triple::aarch64:
571
case llvm::Triple::aarch64_32:
572
case llvm::Triple::mips64:
573
case llvm::Triple::mips64el:
574
case llvm::Triple::mips:
575
case llvm::Triple::mipsel:
576
case llvm::Triple::ppc:
577
case llvm::Triple::ppc64:
578
case llvm::Triple::ppc64le:
579
case llvm::Triple::riscv32:
580
case llvm::Triple::riscv64:
581
case llvm::Triple::loongarch32:
582
case llvm::Triple::loongarch64:
583
// On these architectures the PC doesn't get updated for breakpoint hits.
584
return 0;
585
586
default:
587
llvm_unreachable("CPU type not supported!");
588
}
589
}
590
591
void NativeProcessProtocol::FixupBreakpointPCAsNeeded(
592
NativeThreadProtocol &thread) {
593
Log *log = GetLog(LLDBLog::Breakpoints);
594
595
Status error;
596
597
// Find out the size of a breakpoint (might depend on where we are in the
598
// code).
599
NativeRegisterContext &context = thread.GetRegisterContext();
600
601
uint32_t breakpoint_size = GetSoftwareBreakpointPCOffset();
602
LLDB_LOG(log, "breakpoint size: {0}", breakpoint_size);
603
if (breakpoint_size == 0)
604
return;
605
606
// First try probing for a breakpoint at a software breakpoint location: PC -
607
// breakpoint size.
608
const lldb::addr_t initial_pc_addr = context.GetPCfromBreakpointLocation();
609
lldb::addr_t breakpoint_addr = initial_pc_addr;
610
// Do not allow breakpoint probe to wrap around.
611
if (breakpoint_addr >= breakpoint_size)
612
breakpoint_addr -= breakpoint_size;
613
614
if (m_software_breakpoints.count(breakpoint_addr) == 0) {
615
// We didn't find one at a software probe location. Nothing to do.
616
LLDB_LOG(log,
617
"pid {0} no lldb software breakpoint found at current pc with "
618
"adjustment: {1}",
619
GetID(), breakpoint_addr);
620
return;
621
}
622
623
//
624
// We have a software breakpoint and need to adjust the PC.
625
//
626
627
// Change the program counter.
628
LLDB_LOG(log, "pid {0} tid {1}: changing PC from {2:x} to {3:x}", GetID(),
629
thread.GetID(), initial_pc_addr, breakpoint_addr);
630
631
error = context.SetPC(breakpoint_addr);
632
if (error.Fail()) {
633
// This can happen in case the process was killed between the time we read
634
// the PC and when we are updating it. There's nothing better to do than to
635
// swallow the error.
636
LLDB_LOG(log, "pid {0} tid {1}: failed to set PC: {2}", GetID(),
637
thread.GetID(), error);
638
}
639
}
640
641
Status NativeProcessProtocol::RemoveBreakpoint(lldb::addr_t addr,
642
bool hardware) {
643
if (hardware)
644
return RemoveHardwareBreakpoint(addr);
645
else
646
return RemoveSoftwareBreakpoint(addr);
647
}
648
649
Status NativeProcessProtocol::ReadMemoryWithoutTrap(lldb::addr_t addr,
650
void *buf, size_t size,
651
size_t &bytes_read) {
652
Status error = ReadMemory(addr, buf, size, bytes_read);
653
if (error.Fail())
654
return error;
655
656
llvm::MutableArrayRef data(static_cast<uint8_t *>(buf), bytes_read);
657
for (const auto &pair : m_software_breakpoints) {
658
lldb::addr_t bp_addr = pair.first;
659
auto saved_opcodes = llvm::ArrayRef(pair.second.saved_opcodes);
660
661
if (bp_addr + saved_opcodes.size() < addr || addr + bytes_read <= bp_addr)
662
continue; // Breakpoint not in range, ignore
663
664
if (bp_addr < addr) {
665
saved_opcodes = saved_opcodes.drop_front(addr - bp_addr);
666
bp_addr = addr;
667
}
668
auto bp_data = data.drop_front(bp_addr - addr);
669
std::copy_n(saved_opcodes.begin(),
670
std::min(saved_opcodes.size(), bp_data.size()),
671
bp_data.begin());
672
}
673
return Status();
674
}
675
676
llvm::Expected<llvm::StringRef>
677
NativeProcessProtocol::ReadCStringFromMemory(lldb::addr_t addr, char *buffer,
678
size_t max_size,
679
size_t &total_bytes_read) {
680
static const size_t cache_line_size =
681
llvm::sys::Process::getPageSizeEstimate();
682
size_t bytes_read = 0;
683
size_t bytes_left = max_size;
684
addr_t curr_addr = addr;
685
size_t string_size;
686
char *curr_buffer = buffer;
687
total_bytes_read = 0;
688
Status status;
689
690
while (bytes_left > 0 && status.Success()) {
691
addr_t cache_line_bytes_left =
692
cache_line_size - (curr_addr % cache_line_size);
693
addr_t bytes_to_read = std::min<addr_t>(bytes_left, cache_line_bytes_left);
694
status = ReadMemory(curr_addr, static_cast<void *>(curr_buffer),
695
bytes_to_read, bytes_read);
696
697
if (bytes_read == 0)
698
break;
699
700
void *str_end = std::memchr(curr_buffer, '\0', bytes_read);
701
if (str_end != nullptr) {
702
total_bytes_read =
703
static_cast<size_t>((static_cast<char *>(str_end) - buffer + 1));
704
status.Clear();
705
break;
706
}
707
708
total_bytes_read += bytes_read;
709
curr_buffer += bytes_read;
710
curr_addr += bytes_read;
711
bytes_left -= bytes_read;
712
}
713
714
string_size = total_bytes_read - 1;
715
716
// Make sure we return a null terminated string.
717
if (bytes_left == 0 && max_size > 0 && buffer[max_size - 1] != '\0') {
718
buffer[max_size - 1] = '\0';
719
total_bytes_read--;
720
}
721
722
if (!status.Success())
723
return status.ToError();
724
725
return llvm::StringRef(buffer, string_size);
726
}
727
728
lldb::StateType NativeProcessProtocol::GetState() const {
729
std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
730
return m_state;
731
}
732
733
void NativeProcessProtocol::SetState(lldb::StateType state,
734
bool notify_delegates) {
735
std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
736
737
if (state == m_state)
738
return;
739
740
m_state = state;
741
742
if (StateIsStoppedState(state, false)) {
743
++m_stop_id;
744
745
// Give process a chance to do any stop id bump processing, such as
746
// clearing cached data that is invalidated each time the process runs.
747
// Note if/when we support some threads running, we'll end up needing to
748
// manage this per thread and per process.
749
DoStopIDBumped(m_stop_id);
750
}
751
752
// Optionally notify delegates of the state change.
753
if (notify_delegates)
754
SynchronouslyNotifyProcessStateChanged(state);
755
}
756
757
uint32_t NativeProcessProtocol::GetStopID() const {
758
std::lock_guard<std::recursive_mutex> guard(m_state_mutex);
759
return m_stop_id;
760
}
761
762
void NativeProcessProtocol::DoStopIDBumped(uint32_t /* newBumpId */) {
763
// Default implementation does nothing.
764
}
765
766
NativeProcessProtocol::Manager::~Manager() = default;
767
768