LLDB mainline
RegisterUtilities.h
Go to the documentation of this file.
1//===-- RegisterUtilities.h -------------------------------------*- 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#ifndef LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H
10#define LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H
11
14#include "llvm/BinaryFormat/ELF.h"
15
16namespace lldb_private {
17/// Core files PT_NOTE segment descriptor types
18
63
64namespace OPENBSD {
65enum {
67 NT_AUXV = 11,
68 NT_REGS = 20,
70};
71}
72
73namespace RISCV32 {
74enum {
75 // 'NT_CSREGMAP' is a new ELF core-file note type defined for RISC-V that
76 // encodes a sparse set of Control and Status Registers (CSRs) and their
77 // values, instead of dumping all 4,096 possible CSRs. This note records only
78 // the CSRs that are relevant (e.g. implemented or non-default) as a series of
79 // key–value pairs in a RISC-V core dump image. This keeps core files compact
80 // by omitting the many unimplemented or unused CSRs out of the 12-bit CSR
81 // address space (which allows up to 4,096 CSR indices).
82 //
83 // The format of the 'NT_CSREGMAP' note is as follows:
84 //
85 // ELF Note Header
86 //
87 // As with all core notes, the entry begins with the standard ELF note
88 // header fields –
89 //
90 // namesz
91 //
92 // Length of the note name (including NUL terminator). For
93 // 'NT_CSREGMAP'the note name is the usual core dump note name (e.g.
94 // "CORE" for OS-generated core files).
95 //
96 // descsz
97 //
98 // Length of the note descriptor (payload) in bytes.
99 //
100 // note type
101 //
102 // An integer tag identifying the note’s type. For 'NT_CSREGMAP', the
103 // note type field is set to NT_CSREGMAP (a new enum value distinct
104 // from other note types).
105 //
106 // Note Payload
107 //
108 // The descriptor payload (desc) contains a sequence of CSR entries encoded
109 // in binary format. All multi-byte values use the target’s endianness
110 // (typically little-endian for RISC-V). The layout of the payload is as
111 // follows:
112 //
113 // CSR entries
114 //
115 // A list of N key-value pairs structured as follows:
116 //
117 // Key (CSR Identifier)
118 //
119 // A 32-bit unsigned integer identifying which CSR the entry
120 // represents. This corresponds to the CSR’s address/index in the
121 // RISC-V CSR address space (0–4,095). Ideally, each CSR would
122 // appear at most once; if by error the note has duplicate keys,
123 // then the consumer may use the first or the last occurrence but
124 // in a well-formed core dump image, duplicates won’t occur. The
125 // current implementation uses the first occurrence and skips
126 // subsequent occurrences.
127 //
128 // Value (CSR Content)
129 //
130 // An XLEN-sized value that was held in the CSR identified by 'Key'
131 // at the time that the core dump image was generated. This will be
132 // a 32-bit value for a 32-bit RISC-V core dump image and a 64-bit
133 // value for a 64-bit RISC-V core dump image.
134 //
135 // For instance, if the machine status register, 'mstatus' (CSR 0x300)
136 // had the value '0x00001800' at the time that the core dump image was
137 // generated, then the entry would have key '0x300' and value
138 // '0x00001800'.
139 //
140 // The entries appear consecutively in the note data. There is no fixed
141 // ordering requirement for the entries, but they may be sorted by CSR
142 // number for consistency (this is up to the producer of the core dump
143 // image).
144 //
145 // For a 32-bit RISC-V core dump image, each entry is 4 bytes (key) + 4
146 // bytes (value) = 8 bytes. For a 64-bit core dump image, each entry is
147 // 4 bytes (key) + 8 bytes (value) = 12 bytes. The 'descsz' field in
148 // the note header tells the consumer how big the payload is, so a
149 // consumer can calculate the number of entries, N, as N = descsz / 8
150 // for a 32-bit RISC-V core dump image, or N = descz / 12 for a 64-bit
151 // RISC-V core dump image.
152 //
153 // [Illustration] Suppose we only want to save three CSRs (say, CSRs
154 // 'mstatus' (0x300), 'mtvec' (0x305), and 'mscratch' (0x344)) in a
155 // 32-bit RISC-V core dump image. Then, here's what the raw layout of
156 // the 'NT_CSREGMAP' note’s descriptor payload might look like:
157 //
158 // |----------------|-------------|
159 // | Offset (bytes) | Value |
160 // |----------------|-------------|
161 // | 0–3 | 0x00000300 |
162 // |----------------|-------------|
163 // | 4–7 | 0x00001800 |
164 // |----------------|-------------|
165 // | 8–11 | 0x00000305 |
166 // |----------------|-------------|
167 // | 12–15 | 0x00000004 |
168 // |----------------|-------------|
169 // | 16–19 | 0x00000344 |
170 // |----------------|-------------|
171 // | 20–23 | 0x00000000 |
172 // |----------------|-------------|
173 //
174 // In this illustration, 'descsz' would be 3 * 8 bytes = 24 bytes.
175 //
176 // When a consumer reads a core dump image with an 'NT_CSREGMAP' note, it will
177 // parse the note to populate the target’s register set with the recorded CSR
178 // values. Only the listed CSRs will be updated; any CSR not present in the
179 // note will be assumed to be unavailable.
181};
182}
183
188
189// A structure describing how to find a register set in a core file from a given
190// OS.
192 // OS to which this entry applies to. Must not be UnknownOS.
193 llvm::Triple::OSType OS;
194
195 // Architecture to which this entry applies to. Can be UnknownArch, in which
196 // case it applies to all architectures of a given OS.
197 llvm::Triple::ArchType Arch;
198
199 // The note type under which the register set can be found.
200 uint32_t Note;
201};
202
203// Returns the register set in Notes which corresponds to the specified Triple
204// according to the list of register set descriptions in RegsetDescs. The list
205// is scanned linearly, so you can use a more specific entry (e.g. linux-i386)
206// to override a more general entry (e.g. general linux), as long as you place
207// it earlier in the list. If a register set is not found, it returns an empty
208// DataExtractor.
209DataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes,
210 const llvm::Triple &Triple,
211 llvm::ArrayRef<RegsetDesc> RegsetDescs);
212
213constexpr RegsetDesc FPR_Desc[] = {
214 // FreeBSD/i386 core NT_FPREGSET is x87 FSAVE result but the XSAVE dump
215 // starts with FXSAVE struct, so use that instead if available.
216 {llvm::Triple::FreeBSD, llvm::Triple::x86, llvm::ELF::NT_X86_XSTATE},
217 {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
218 // In a i386 core file NT_FPREGSET is present, but it's not the result
219 // of the FXSAVE instruction like in 64 bit files.
220 // The result from FXSAVE is in NT_PRXFPREG for i386 core files
221 {llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG},
222 {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
223 {llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS},
224 {llvm::Triple::NetBSD, llvm::Triple::x86, NETBSD::I386::NT_FPREGS},
225 {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS},
226 {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
227 // Bare-metal 32-bit RISC-V debug target.
228 {llvm::Triple::UnknownOS, llvm::Triple::riscv32, llvm::ELF::NT_FPREGSET},
229};
230
232 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SVE},
233};
234
236 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_SSVE},
237};
238
240 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_ZA},
241};
242
244 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_ZT},
245};
246
248 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_PAC_MASK},
249};
250
252 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_TLS},
253};
254
256 {llvm::Triple::Linux, llvm::Triple::aarch64,
257 llvm::ELF::NT_ARM_TAGGED_ADDR_CTRL},
258};
259
261 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_FPMR},
262};
263
265 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_GCS},
266};
267
269 {llvm::Triple::Linux, llvm::Triple::aarch64, llvm::ELF::NT_ARM_POE},
270};
271
273 {llvm::Triple::FreeBSD, llvm::Triple::arm, llvm::ELF::NT_ARM_VFP},
274 {llvm::Triple::Linux, llvm::Triple::arm, llvm::ELF::NT_ARM_VFP},
275};
276
278 {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
279 {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
280};
281
283 {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VSX},
284};
285
287 {llvm::Triple::UnknownOS, llvm::Triple::riscv32, RISCV32::NT_CSREGMAP},
288};
289
290} // namespace lldb_private
291
292#endif // LLDB_SOURCE_PLUGINS_PROCESS_ELF_CORE_REGISTERUTILITIES_H
An data extractor class.
Core files PT_NOTE segment descriptor types.
A class that represents a running process on the host machine.
constexpr RegsetDesc RISCV32_CSREGMAP_Desc[]
constexpr RegsetDesc ARM_VFP_Desc[]
DataExtractor getRegset(llvm::ArrayRef< CoreNote > Notes, const llvm::Triple &Triple, llvm::ArrayRef< RegsetDesc > RegsetDescs)
constexpr RegsetDesc AARCH64_TLS_Desc[]
constexpr RegsetDesc AARCH64_FPMR_Desc[]
constexpr RegsetDesc AARCH64_ZT_Desc[]
constexpr RegsetDesc AARCH64_SSVE_Desc[]
constexpr RegsetDesc FPR_Desc[]
constexpr RegsetDesc AARCH64_GCS_Desc[]
constexpr RegsetDesc AARCH64_POE_Desc[]
constexpr RegsetDesc AARCH64_MTE_Desc[]
constexpr RegsetDesc PPC_VSX_Desc[]
constexpr RegsetDesc AARCH64_SVE_Desc[]
constexpr RegsetDesc AARCH64_PAC_Desc[]
constexpr RegsetDesc PPC_VMX_Desc[]
constexpr RegsetDesc AARCH64_ZA_Desc[]
llvm::Triple::OSType OS
llvm::Triple::ArchType Arch