]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdbserver/linux-aarch64-ipa.cc
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / gdbserver / linux-aarch64-ipa.cc
CommitLineData
bb903df0
PL
1/* GNU/Linux/AArch64 specific low level interface, for the in-process
2 agent library for GDB.
3
b811d2c2 4 Copyright (C) 2015-2020 Free Software Foundation, Inc.
bb903df0
PL
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21#include "server.h"
a13c4696 22#include <sys/mman.h>
bb903df0 23#include "tracepoint.h"
d0a9981f 24#include <elf.h>
a13c4696
MK
25#ifdef HAVE_GETAUXVAL
26#include <sys/auxv.h>
27#endif
d6d7ce56 28#include "linux-aarch64-tdesc.h"
bb903df0 29
bb903df0
PL
30/* Each register saved by the jump pad is in a 16 byte cell. */
31#define FT_CR_SIZE 16
32
33#define FT_CR_FPCR 0
34#define FT_CR_FPSR 1
35#define FT_CR_CPSR 2
36#define FT_CR_PC 3
37#define FT_CR_SP 4
38#define FT_CR_X0 5
39#define FT_CR_GPR(n) (FT_CR_X0 + (n))
40#define FT_CR_FPR(n) (FT_CR_GPR (31) + (n))
41
42/* Mapping between registers collected by the jump pad and GDB's register
43 array layout used by regcache.
44
45 See linux-aarch64-low.c (aarch64_install_fast_tracepoint_jump_pad) for
46 more details. */
47
48static const int aarch64_ft_collect_regmap[] = {
49 FT_CR_GPR (0),
50 FT_CR_GPR (1),
51 FT_CR_GPR (2),
52 FT_CR_GPR (3),
53 FT_CR_GPR (4),
54 FT_CR_GPR (5),
55 FT_CR_GPR (6),
56 FT_CR_GPR (7),
57 FT_CR_GPR (8),
58 FT_CR_GPR (9),
59 FT_CR_GPR (10),
60 FT_CR_GPR (11),
61 FT_CR_GPR (12),
62 FT_CR_GPR (13),
63 FT_CR_GPR (14),
64 FT_CR_GPR (15),
65 FT_CR_GPR (16),
66 FT_CR_GPR (17),
67 FT_CR_GPR (18),
68 FT_CR_GPR (19),
69 FT_CR_GPR (20),
70 FT_CR_GPR (21),
71 FT_CR_GPR (22),
72 FT_CR_GPR (23),
73 FT_CR_GPR (24),
74 FT_CR_GPR (25),
75 FT_CR_GPR (26),
76 FT_CR_GPR (27),
77 FT_CR_GPR (28),
78 /* FP */
79 FT_CR_GPR (29),
80 /* LR */
81 FT_CR_GPR (30),
82 FT_CR_SP,
83 FT_CR_PC,
84 FT_CR_CPSR,
85 FT_CR_FPR (0),
86 FT_CR_FPR (1),
87 FT_CR_FPR (2),
88 FT_CR_FPR (3),
89 FT_CR_FPR (4),
90 FT_CR_FPR (5),
91 FT_CR_FPR (6),
92 FT_CR_FPR (7),
93 FT_CR_FPR (8),
94 FT_CR_FPR (9),
95 FT_CR_FPR (10),
96 FT_CR_FPR (11),
97 FT_CR_FPR (12),
98 FT_CR_FPR (13),
99 FT_CR_FPR (14),
100 FT_CR_FPR (15),
101 FT_CR_FPR (16),
102 FT_CR_FPR (17),
103 FT_CR_FPR (18),
104 FT_CR_FPR (19),
105 FT_CR_FPR (20),
106 FT_CR_FPR (21),
107 FT_CR_FPR (22),
108 FT_CR_FPR (23),
109 FT_CR_FPR (24),
110 FT_CR_FPR (25),
111 FT_CR_FPR (26),
112 FT_CR_FPR (27),
113 FT_CR_FPR (28),
114 FT_CR_FPR (29),
115 FT_CR_FPR (30),
116 FT_CR_FPR (31),
117 FT_CR_FPSR,
118 FT_CR_FPCR
119};
120
121#define AARCH64_NUM_FT_COLLECT_GREGS \
122 (sizeof (aarch64_ft_collect_regmap) / sizeof(aarch64_ft_collect_regmap[0]))
123
124/* Fill in REGCACHE with registers saved by the jump pad in BUF. */
125
126void
127supply_fast_tracepoint_registers (struct regcache *regcache,
128 const unsigned char *buf)
129{
130 int i;
131
132 for (i = 0; i < AARCH64_NUM_FT_COLLECT_GREGS; i++)
133 supply_register (regcache, i,
134 ((char *) buf)
135 + (aarch64_ft_collect_regmap[i] * FT_CR_SIZE));
136}
137
1cda1512
MK
138ULONGEST
139get_raw_reg (const unsigned char *raw_regs, int regnum)
bb903df0
PL
140{
141 if (regnum >= AARCH64_NUM_FT_COLLECT_GREGS)
142 return 0;
143
144 return *(ULONGEST *) (raw_regs
145 + aarch64_ft_collect_regmap[regnum] * FT_CR_SIZE);
146}
147
ae91f625
MK
148/* Return target_desc to use for IPA, given the tdesc index passed by
149 gdbserver. Index is ignored, since we have only one tdesc
6dc0ebde 150 at the moment. SVE and pauth not yet supported. */
ae91f625
MK
151
152const struct target_desc *
153get_ipa_tdesc (int idx)
154{
6dc0ebde 155 return aarch64_linux_read_description (0, false);
ae91f625
MK
156}
157
a13c4696
MK
158/* Allocate buffer for the jump pads. The branch instruction has a reach
159 of +/- 128MiB, and the executable is loaded at 0x400000 (4MiB).
160 To maximize the area of executable that can use tracepoints, try
161 allocating at 0x400000 - size initially, decreasing until we hit
162 a free area. */
163
164void *
165alloc_jump_pad_buffer (size_t size)
166{
167 uintptr_t addr;
168 uintptr_t exec_base = getauxval (AT_PHDR);
169 int pagesize;
170 void *res;
171
172 if (exec_base == 0)
173 exec_base = 0x400000;
174
175 pagesize = sysconf (_SC_PAGE_SIZE);
176 if (pagesize == -1)
177 perror_with_name ("sysconf");
178
179 addr = exec_base - size;
180
181 /* size should already be page-aligned, but this can't hurt. */
182 addr &= ~(pagesize - 1);
183
184 /* Search for a free area. If we hit 0, we're out of luck. */
185 for (; addr; addr -= pagesize)
186 {
187 /* No MAP_FIXED - we don't want to zap someone's mapping. */
188 res = mmap ((void *) addr, size,
189 PROT_READ | PROT_WRITE | PROT_EXEC,
190 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
191
192 /* If we got what we wanted, return. */
193 if ((uintptr_t) res == addr)
194 return res;
195
196 /* If we got a mapping, but at a wrong address, undo it. */
197 if (res != MAP_FAILED)
198 munmap (res, size);
199 }
200
201 return NULL;
202}
203
bb903df0
PL
204void
205initialize_low_tracepoint (void)
206{
6dc0ebde
AH
207 /* SVE and pauth not yet supported. */
208 aarch64_linux_read_description (0, false);
bb903df0 209}