1326949Sdim//===-- RegisterUtilities.h -------------------------------------*- C++ -*-===//
2326949Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6326949Sdim//
7326949Sdim//===----------------------------------------------------------------------===//
8326949Sdim
9326949Sdim#ifndef LLDB_REGISTERUTILITIES_H
10326949Sdim#define LLDB_REGISTERUTILITIES_H
11326949Sdim
12326949Sdim#include "Plugins/ObjectFile/ELF/ObjectFileELF.h"
13326949Sdim#include "lldb/Utility/DataExtractor.h"
14360784Sdim#include "llvm/BinaryFormat/ELF.h"
15326949Sdim
16326949Sdimnamespace lldb_private {
17326949Sdim/// Core files PT_NOTE segment descriptor types
18326949Sdim
19326949Sdimnamespace NETBSD {
20353358Sdimenum { NT_PROCINFO = 1, NT_AUXV = 2 };
21353358Sdim
22353358Sdim/* Size in bytes */
23353358Sdimenum { NT_PROCINFO_SIZE = 160 };
24353358Sdim
25353358Sdim/* Size in bytes */
26353358Sdimenum {
27353358Sdim  NT_PROCINFO_CPI_VERSION_SIZE = 4,
28353358Sdim  NT_PROCINFO_CPI_CPISIZE_SIZE = 4,
29353358Sdim  NT_PROCINFO_CPI_SIGNO_SIZE = 4,
30353358Sdim  NT_PROCINFO_CPI_SIGCODE_SIZE = 4,
31353358Sdim  NT_PROCINFO_CPI_SIGPEND_SIZE = 16,
32353358Sdim  NT_PROCINFO_CPI_SIGMASK_SIZE = 16,
33353358Sdim  NT_PROCINFO_CPI_SIGIGNORE_SIZE = 16,
34353358Sdim  NT_PROCINFO_CPI_SIGCATCH_SIZE = 16,
35353358Sdim  NT_PROCINFO_CPI_PID_SIZE = 4,
36353358Sdim  NT_PROCINFO_CPI_PPID_SIZE = 4,
37353358Sdim  NT_PROCINFO_CPI_PGRP_SIZE = 4,
38353358Sdim  NT_PROCINFO_CPI_SID_SIZE = 4,
39353358Sdim  NT_PROCINFO_CPI_RUID_SIZE = 4,
40353358Sdim  NT_PROCINFO_CPI_EUID_SIZE = 4,
41353358Sdim  NT_PROCINFO_CPI_SVUID_SIZE = 4,
42353358Sdim  NT_PROCINFO_CPI_RGID_SIZE = 4,
43353358Sdim  NT_PROCINFO_CPI_EGID_SIZE = 4,
44353358Sdim  NT_PROCINFO_CPI_SVGID_SIZE = 4,
45353358Sdim  NT_PROCINFO_CPI_NLWPS_SIZE = 4,
46353358Sdim  NT_PROCINFO_CPI_NAME_SIZE = 32,
47353358Sdim  NT_PROCINFO_CPI_SIGLWP_SIZE = 4,
48353358Sdim};
49353358Sdim
50353358Sdimnamespace AARCH64 {
51353358Sdimenum { NT_REGS = 32, NT_FPREGS = 34 };
52326949Sdim}
53326949Sdim
54353358Sdimnamespace AMD64 {
55353358Sdimenum { NT_REGS = 33, NT_FPREGS = 35 };
56353358Sdim}
57353358Sdim
58353358Sdim} // namespace NETBSD
59353358Sdim
60326949Sdimnamespace OPENBSD {
61326949Sdimenum {
62326949Sdim  NT_PROCINFO = 10,
63326949Sdim  NT_AUXV = 11,
64326949Sdim  NT_REGS = 20,
65326949Sdim  NT_FPREGS = 21,
66326949Sdim};
67326949Sdim}
68326949Sdim
69326949Sdimstruct CoreNote {
70326949Sdim  ELFNote info;
71326949Sdim  DataExtractor data;
72326949Sdim};
73326949Sdim
74326949Sdim// A structure describing how to find a register set in a core file from a given
75326949Sdim// OS.
76326949Sdimstruct RegsetDesc {
77326949Sdim  // OS to which this entry applies to. Must not be UnknownOS.
78326949Sdim  llvm::Triple::OSType OS;
79326949Sdim
80326949Sdim  // Architecture to which this entry applies to. Can be UnknownArch, in which
81326949Sdim  // case it applies to all architectures of a given OS.
82326949Sdim  llvm::Triple::ArchType Arch;
83326949Sdim
84326949Sdim  // The note type under which the register set can be found.
85326949Sdim  uint32_t Note;
86326949Sdim};
87326949Sdim
88326949Sdim// Returns the register set in Notes which corresponds to the specified Triple
89326949Sdim// according to the list of register set descriptions in RegsetDescs. The list
90326949Sdim// is scanned linearly, so you can use a more specific entry (e.g. linux-i386)
91326949Sdim// to override a more general entry (e.g. general linux), as long as you place
92326949Sdim// it earlier in the list. If a register set is not found, it returns an empty
93326949Sdim// DataExtractor.
94326949SdimDataExtractor getRegset(llvm::ArrayRef<CoreNote> Notes,
95326949Sdim                        const llvm::Triple &Triple,
96326949Sdim                        llvm::ArrayRef<RegsetDesc> RegsetDescs);
97326949Sdim
98326949Sdimconstexpr RegsetDesc FPR_Desc[] = {
99360784Sdim    {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
100326949Sdim    // In a i386 core file NT_FPREGSET is present, but it's not the result
101326949Sdim    // of the FXSAVE instruction like in 64 bit files.
102326949Sdim    // The result from FXSAVE is in NT_PRXFPREG for i386 core files
103360784Sdim    {llvm::Triple::Linux, llvm::Triple::x86, llvm::ELF::NT_PRXFPREG},
104360784Sdim    {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_FPREGSET},
105353358Sdim    {llvm::Triple::NetBSD, llvm::Triple::aarch64, NETBSD::AARCH64::NT_FPREGS},
106353358Sdim    {llvm::Triple::NetBSD, llvm::Triple::x86_64, NETBSD::AMD64::NT_FPREGS},
107326949Sdim    {llvm::Triple::OpenBSD, llvm::Triple::UnknownArch, OPENBSD::NT_FPREGS},
108326949Sdim};
109326949Sdim
110326949Sdimconstexpr RegsetDesc PPC_VMX_Desc[] = {
111360784Sdim    {llvm::Triple::FreeBSD, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
112360784Sdim    {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VMX},
113326949Sdim};
114326949Sdim
115326949Sdimconstexpr RegsetDesc PPC_VSX_Desc[] = {
116360784Sdim    {llvm::Triple::Linux, llvm::Triple::UnknownArch, llvm::ELF::NT_PPC_VSX},
117326949Sdim};
118326949Sdim
119326949Sdim} // namespace lldb_private
120326949Sdim
121326949Sdim#endif // #ifndef LLDB_REGISTERUTILITIES_H
122