1 /* GNU/Linux/AArch64 specific low level interface, for the in-process
4 Copyright (C) 2015-2024 Free Software Foundation, Inc.
6 This file is part of GDB.
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.
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.
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/>. */
22 #include "tracepoint.h"
27 #include "linux-aarch64-tdesc.h"
29 /* Each register saved by the jump pad is in a 16 byte cell. */
38 #define FT_CR_GPR(n) (FT_CR_X0 + (n))
39 #define FT_CR_FPR(n) (FT_CR_GPR (31) + (n))
41 /* Mapping between registers collected by the jump pad and GDB's register
42 array layout used by regcache.
44 See linux-aarch64-low.c (aarch64_install_fast_tracepoint_jump_pad) for
47 static const int aarch64_ft_collect_regmap
[] = {
120 #define AARCH64_NUM_FT_COLLECT_GREGS \
121 (sizeof (aarch64_ft_collect_regmap) / sizeof(aarch64_ft_collect_regmap[0]))
123 /* Fill in REGCACHE with registers saved by the jump pad in BUF. */
126 supply_fast_tracepoint_registers (struct regcache
*regcache
,
127 const unsigned char *buf
)
131 for (i
= 0; i
< AARCH64_NUM_FT_COLLECT_GREGS
; i
++)
132 supply_register (regcache
, i
,
134 + (aarch64_ft_collect_regmap
[i
] * FT_CR_SIZE
));
138 get_raw_reg (const unsigned char *raw_regs
, int regnum
)
140 if (regnum
>= AARCH64_NUM_FT_COLLECT_GREGS
)
143 return *(ULONGEST
*) (raw_regs
144 + aarch64_ft_collect_regmap
[regnum
] * FT_CR_SIZE
);
147 /* Return target_desc to use for IPA, given the tdesc index passed by
148 gdbserver. Index is ignored, since we have only one tdesc
149 at the moment. SVE, pauth, MTE and TLS not yet supported. */
151 const struct target_desc
*
152 get_ipa_tdesc (int idx
)
154 return aarch64_linux_read_description ({});
157 /* Allocate buffer for the jump pads. The branch instruction has a reach
158 of +/- 128MiB, and the executable is loaded at 0x400000 (4MiB).
159 To maximize the area of executable that can use tracepoints, try
160 allocating at 0x400000 - size initially, decreasing until we hit
164 alloc_jump_pad_buffer (size_t size
)
167 uintptr_t exec_base
= getauxval (AT_PHDR
);
172 exec_base
= 0x400000;
174 pagesize
= sysconf (_SC_PAGE_SIZE
);
176 perror_with_name ("sysconf");
178 addr
= exec_base
- size
;
180 /* size should already be page-aligned, but this can't hurt. */
181 addr
&= ~(pagesize
- 1);
183 /* Search for a free area. If we hit 0, we're out of luck. */
184 for (; addr
; addr
-= pagesize
)
186 /* No MAP_FIXED - we don't want to zap someone's mapping. */
187 res
= mmap ((void *) addr
, size
,
188 PROT_READ
| PROT_WRITE
| PROT_EXEC
,
189 MAP_PRIVATE
| MAP_ANONYMOUS
, -1, 0);
191 /* If we got what we wanted, return. */
192 if ((uintptr_t) res
== addr
)
195 /* If we got a mapping, but at a wrong address, undo it. */
196 if (res
!= MAP_FAILED
)
204 initialize_low_tracepoint (void)
206 /* SVE, pauth, MTE and TLS not yet supported. */
207 aarch64_linux_read_description ({});