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
21#if defined(__FreeBSD__) && defined(__aarch64__)
22#include <machine/pcb.h>
23#include <sys/param.h>
24#endif
25
26using namespace lldb;
27using namespace lldb_private;
28
30 Thread &thread, std::unique_ptr<RegisterInfoPOSIX_arm64> register_info_up,
31 lldb::addr_t pcb_addr)
32 : RegisterContextPOSIX_arm64(thread, std::move(register_info_up)),
33 m_pcb_addr(pcb_addr) {}
34
36
38
40 assert(0);
41 return false;
42}
43
45 assert(0);
46 return false;
47}
48
50 const RegisterInfo *reg_info, RegisterValue &value) {
52 return false;
53
54 // https://cgit.freebsd.org/src/tree/sys/arm64/include/pcb.h
55 struct {
56 llvm::support::ulittle64_t x[12];
57 llvm::support::ulittle64_t sp;
58 } pcb;
59
60#if defined(__FreeBSD__) && defined(__aarch64__) && __FreeBSD_version >= 1400084
61 static_assert(offsetof(struct pcb, pcb_x) == offsetof(decltype(pcb), x));
62 static_assert(offsetof(struct pcb, pcb_sp) == offsetof(decltype(pcb), sp));
63#endif
64
65 // https://cgit.freebsd.org/src/tree/sys/arm64/include/pcb.h?h=stable%2F13
66 struct {
67 llvm::support::ulittle64_t x[30];
68 llvm::support::ulittle64_t lr;
69 llvm::support::ulittle64_t _reserved;
70 llvm::support::ulittle64_t sp;
71 } pcb13;
72
73#if defined(__FreeBSD__) && defined(__aarch64__) && __FreeBSD_version < 1400084
74 static_assert(offsetof(struct pcb, pcb_x) == offsetof(decltype(pcb13), x));
75 static_assert(offsetof(struct pcb, pcb_lr) == offsetof(decltype(pcb13), lr));
76 static_assert(offsetof(struct pcb, pcb_sp) == offsetof(decltype(pcb13), sp));
77#endif
78
80 constexpr int FBSD14 = 1400084;
81 int osreldate = FBSD14;
82
83 if (auto osreldate_or_null = GetOsreldate())
84 osreldate = *osreldate_or_null;
85 else
87 "Cannot find osreldate. Defaulting to %d.", FBSD14);
88
89 // TODO: LLVM 24: Remove FreeBSD 13 support
90 if (osreldate >= FBSD14) {
91 constexpr uint32_t pcb_fp = 10;
92 constexpr uint32_t pcb_lr = 11;
93 size_t rd =
94 m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb, sizeof(pcb), error);
95 if (rd != sizeof(pcb))
96 return false;
97
98 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
99 switch (reg) {
100 case gpr_x19_arm64:
101 case gpr_x20_arm64:
102 case gpr_x21_arm64:
103 case gpr_x22_arm64:
104 case gpr_x23_arm64:
105 case gpr_x24_arm64:
106 case gpr_x25_arm64:
107 case gpr_x26_arm64:
108 case gpr_x27_arm64:
109 case gpr_x28_arm64:
110 case gpr_fp_arm64:
111 static_assert(gpr_fp_arm64 - gpr_x19_arm64 == pcb_fp,
112 "nonconsecutive arm64 register numbers");
113 value = pcb.x[reg - gpr_x19_arm64];
114 break;
115 case gpr_sp_arm64:
116 value = pcb.sp;
117 break;
118 case gpr_pc_arm64:
119 // The pc of crashing thread is stored in lr.
120 static_assert(gpr_lr_arm64 - gpr_x19_arm64 == pcb_lr,
121 "nonconsecutive arm64 register numbers");
122 value = pcb.x[gpr_lr_arm64 - gpr_x19_arm64];
123 break;
124 default:
125 return false;
126 }
127 } else {
128 size_t rd = m_thread.GetProcess()->ReadMemory(m_pcb_addr, &pcb13,
129 sizeof(pcb13), error);
130 if (rd != sizeof(pcb13))
131 return false;
132
133 uint32_t reg = reg_info->kinds[lldb::eRegisterKindLLDB];
134 switch (reg) {
135 case gpr_x0_arm64:
136 case gpr_x1_arm64:
137 case gpr_x2_arm64:
138 case gpr_x3_arm64:
139 case gpr_x4_arm64:
140 case gpr_x5_arm64:
141 case gpr_x6_arm64:
142 case gpr_x7_arm64:
143 case gpr_x8_arm64:
144 case gpr_x9_arm64:
145 case gpr_x10_arm64:
146 case gpr_x11_arm64:
147 case gpr_x12_arm64:
148 case gpr_x13_arm64:
149 case gpr_x14_arm64:
150 case gpr_x15_arm64:
151 case gpr_x16_arm64:
152 case gpr_x17_arm64:
153 case gpr_x18_arm64:
154 case gpr_x19_arm64:
155 case gpr_x20_arm64:
156 case gpr_x21_arm64:
157 case gpr_x22_arm64:
158 case gpr_x23_arm64:
159 case gpr_x24_arm64:
160 case gpr_x25_arm64:
161 case gpr_x26_arm64:
162 case gpr_x27_arm64:
163 case gpr_x28_arm64:
164 case gpr_fp_arm64:
165 static_assert(gpr_fp_arm64 - gpr_x0_arm64 == 29,
166 "nonconsecutive arm64 register numbers");
167 value = pcb13.x[reg - gpr_x0_arm64];
168 break;
169 case gpr_sp_arm64:
170 value = pcb13.sp;
171 break;
172 case gpr_pc_arm64:
173 // The pc of crashing thread is stored in lr.
174 value = pcb13.lr;
175 break;
176 default:
177 return false;
178 }
179 }
180 return true;
181}
182
184 const RegisterInfo *reg_info, const RegisterValue &value) {
185 return false;
186}
187
189 ProcessSP process_sp = m_thread.GetProcess();
190 if (!process_sp)
191 return std::nullopt;
192
193 Target &target = process_sp->GetTarget();
194
195 SymbolContextList sc_list;
197 lldb::eSymbolTypeData, sc_list);
198 if (sc_list.GetSize() == 0)
199 return std::nullopt;
200
201 SymbolContext sc;
202 sc_list.GetContextAtIndex(0, sc);
203 if (!sc.symbol)
204 return std::nullopt;
205
206 lldb::addr_t addr = sc.symbol->GetLoadAddress(&target);
207 if (addr == LLDB_INVALID_ADDRESS)
208 return std::nullopt;
209
211 int osreldate = 0;
212 size_t bytes_read =
213 process_sp->ReadMemory(addr, &osreldate, sizeof(osreldate), error);
214 if (bytes_read == sizeof(osreldate) && error.Success())
215 return osreldate;
216
217 return std::nullopt;
218}
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:1140
#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.