LLDB mainline
RegisterContextFreeBSDKernelCore_arm64.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
11
12#include "lldb/Symbol/Symbol.h"
13#include "lldb/Target/Process.h"
14#include "lldb/Target/Target.h"
15#include "lldb/Target/Thread.h"
17#include "lldb/Utility/Log.h"
19#include "llvm/Support/Endian.h"
20
21using namespace lldb;
22using namespace lldb_private;
23
25 Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
26 lldb::addr_t pcb_addr)
27 : RegisterContextPOSIX_arm64(thread, std::move(register_info_up)),
28 m_pcb_addr(pcb_addr) {}
29
31
33
35 assert(0);
36 return false;
37}
38
40 assert(0);
41 return false;
42}
43
45 const RegisterInfo *reg_info, RegisterValue &value) {
47 return false;
48
49 // https://cgit.freebsd.org/src/tree/sys/arm64/include/pcb.h
50 struct {
51 llvm::support::ulittle64_t x[12];
52 llvm::support::ulittle64_t sp;
53 } pcb;
54
55 // https://cgit.freebsd.org/src/tree/sys/arm64/include/pcb.h?h=stable%2F13
56 struct {
57 llvm::support::ulittle64_t x[30];
58 llvm::support::ulittle64_t lr;
59 llvm::support::ulittle64_t _reserved;
60 llvm::support::ulittle64_t sp;
61 } pcb13;
62
64 constexpr int FBSD14 = 1400084;
65 int osreldate = FBSD14;
66
67 if (auto osreldate_or_null = GetOsreldate())
68 osreldate = *osreldate_or_null;
69 else
71 "Cannot find osreldate. Defaulting to %d.", FBSD14);
72
73 // TODO: LLVM 24: Remove FreeBSD 13 support
74 if (osreldate >= FBSD14) {
75 constexpr uint32_t PCB_FP = 10;
76 constexpr uint32_t PCB_LR = 11;
77 size_t rd =
78 m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
79 if (rd != sizeof(pcb))
80 return false;
81
82 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
83 switch (reg) {
84 case gpr_x19_arm64:
85 case gpr_x20_arm64:
86 case gpr_x21_arm64:
87 case gpr_x22_arm64:
88 case gpr_x23_arm64:
89 case gpr_x24_arm64:
90 case gpr_x25_arm64:
91 case gpr_x26_arm64:
92 case gpr_x27_arm64:
93 case gpr_x28_arm64:
94 case gpr_fp_arm64:
95 static_assert(gpr_fp_arm64 - gpr_x19_arm64 == PCB_FP,
96 "nonconsecutive arm64 register numbers");
97 value = pcb.x[reg - gpr_x19_arm64];
98 break;
99 case gpr_lr_arm64:
100 case gpr_pc_arm64:
101 // The pc of crashing thread is stored in lr.
102 static_assert(gpr_lr_arm64 - gpr_x19_arm64 == PCB_LR,
103 "nonconsecutive arm64 register numbers");
104 value = pcb.x[reg - gpr_x19_arm64];
105 break;
106 case gpr_sp_arm64:
107 value = pcb.sp;
108 break;
109 default:
110 return false;
111 }
112 } else {
113 size_t rd = m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb13,
114 sizeof(pcb13), error);
115 if (rd != sizeof(pcb13))
116 return false;
117
118 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
119 switch (reg) {
120 case gpr_x0_arm64:
121 case gpr_x1_arm64:
122 case gpr_x2_arm64:
123 case gpr_x3_arm64:
124 case gpr_x4_arm64:
125 case gpr_x5_arm64:
126 case gpr_x6_arm64:
127 case gpr_x7_arm64:
128 case gpr_x8_arm64:
129 case gpr_x9_arm64:
130 case gpr_x10_arm64:
131 case gpr_x11_arm64:
132 case gpr_x12_arm64:
133 case gpr_x13_arm64:
134 case gpr_x14_arm64:
135 case gpr_x15_arm64:
136 case gpr_x16_arm64:
137 case gpr_x17_arm64:
138 case gpr_x18_arm64:
139 case gpr_x19_arm64:
140 case gpr_x20_arm64:
141 case gpr_x21_arm64:
142 case gpr_x22_arm64:
143 case gpr_x23_arm64:
144 case gpr_x24_arm64:
145 case gpr_x25_arm64:
146 case gpr_x26_arm64:
147 case gpr_x27_arm64:
148 case gpr_x28_arm64:
149 case gpr_fp_arm64:
150 static_assert(gpr_fp_arm64 - gpr_x0_arm64 == 29,
151 "nonconsecutive arm64 register numbers");
152 value = pcb13.x[reg - gpr_x0_arm64];
153 break;
154 case gpr_sp_arm64:
155 value = pcb13.sp;
156 break;
157 case gpr_pc_arm64:
158 // The pc of crashing thread is stored in lr.
159 value = pcb13.lr;
160 break;
161 default:
162 return false;
163 }
164 }
165 return true;
166}
167
169 const RegisterInfo *reg_info, const RegisterValue &value) {
170 return false;
171}
172
174 ProcessSP process_sp = m_thread.GetProcess();
175 if (!process_sp)
176 return std::nullopt;
177
178 Target &target = process_sp->GetTarget();
179
180 SymbolContextList sc_list;
182 lldb::eSymbolTypeData, sc_list);
183 if (sc_list.GetSize() == 0)
184 return std::nullopt;
185
186 SymbolContext sc;
187 sc_list.GetContextAtIndex(0, sc);
188 if (!sc.symbol)
189 return std::nullopt;
190
191 lldb::addr_t addr = sc.symbol->GetLoadAddress(&target);
192 if (addr == LLDB_INVALID_ADDRESS)
193 return std::nullopt;
194
196 int osreldate = 0;
197 size_t bytes_read =
198 process_sp->ReadMemory(addr, &osreldate, sizeof(osreldate), error);
199 if (bytes_read == sizeof(osreldate) && error.Success())
200 return osreldate;
201
202 return std::nullopt;
203}
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
Definition Log.h:376
bool WriteRegister(const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value) override
bool ReadRegister(const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value) override
RegisterContextFreeBSDKernelCore_arm64(lldb_private::Thread &thread, std::unique_ptr< RegisterInfoPOSIX_arm64 > register_info_up, lldb::addr_t pcb_addr)
RegisterContextPOSIX_arm64(lldb_private::Thread &thread, std::unique_ptr< RegisterInfoPOSIX_arm64 > register_info)
A uniqued constant string class.
Definition ConstString.h:40
void FindSymbolsWithNameAndType(ConstString name, lldb::SymbolType symbol_type, SymbolContextList &sc_list) const
An error handling class.
Definition Status.h:118
Defines a list of symbol context objects.
bool GetContextAtIndex(size_t idx, SymbolContext &sc) const
Get accessor for a symbol context at index idx.
uint32_t GetSize() const
Get accessor for a symbol context list size.
Defines a symbol context baton that can be handed other debug core functions.
Symbol * symbol
The Symbol for a given query.
lldb::addr_t GetLoadAddress(Target *target) const
Definition Symbol.cpp:504
const ModuleList & GetImages() const
Get accessor for the images for this process.
Definition Target.h:1141
#define LLDB_INVALID_ADDRESS
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition Log.h:332
std::shared_ptr< lldb_private::Process > ProcessSP
uint64_t addr_t
Definition lldb-types.h:80
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
uint32_t kinds[lldb::kNumRegisterKinds]
Holds all of the various register numbers for all register kinds.