1 /* GNU/Linux S/390 specific low level interface, for the in-process 2 agent library for GDB. 3 4 Copyright (C) 2016-2024 Free Software Foundation, Inc. 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 <sys/mman.h> 22 #include "tracepoint.h" 23 #include "linux-s390-tdesc.h" 24 #include <elf.h> 25 #ifdef HAVE_GETAUXVAL 26 #include <sys/auxv.h> 27 #endif 28 29 #define FT_FPR(x) (0x000 + (x) * 0x10) 30 #define FT_VR(x) (0x000 + (x) * 0x10) 31 #define FT_VR_L(x) (0x008 + (x) * 0x10) 32 #define FT_GPR(x) (0x200 + (x) * 8) 33 #define FT_GPR_U(x) (0x200 + (x) * 8) 34 #define FT_GPR_L(x) (0x204 + (x) * 8) 35 #define FT_GPR(x) (0x200 + (x) * 8) 36 #define FT_ACR(x) (0x280 + (x) * 4) 37 #define FT_PSWM 0x2c0 38 #define FT_PSWM_U 0x2c0 39 #define FT_PSWA 0x2c8 40 #define FT_PSWA_L 0x2cc 41 #define FT_FPC 0x2d0 42 43 /* Mappings between registers collected by the jump pad and GDB's register 44 array layout used by regcache. 45 46 See linux-s390-low.c (s390_install_fast_tracepoint_jump_pad) for more 47 details. */ 48 49 #ifndef __s390x__ 50 51 /* Used for s390-linux32, s390-linux32v1, s390-linux32v2. */ 52 53 static const int s390_linux32_ft_collect_regmap[] = { 54 /* 32-bit PSWA and PSWM. */ 55 FT_PSWM_U, FT_PSWA_L, 56 /* 32-bit GPRs (mapped to lower halves of 64-bit slots). */ 57 FT_GPR_L (0), FT_GPR_L (1), FT_GPR_L (2), FT_GPR_L (3), 58 FT_GPR_L (4), FT_GPR_L (5), FT_GPR_L (6), FT_GPR_L (7), 59 FT_GPR_L (8), FT_GPR_L (9), FT_GPR_L (10), FT_GPR_L (11), 60 FT_GPR_L (12), FT_GPR_L (13), FT_GPR_L (14), FT_GPR_L (15), 61 /* ACRs */ 62 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3), 63 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7), 64 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11), 65 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15), 66 /* FPRs (mapped to upper halves of 128-bit VR slots). */ 67 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3), 68 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7), 69 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11), 70 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15), 71 /* orig_r2, last_break, system_call */ 72 -1, -1, -1, 73 }; 74 75 /* Used for s390-linux64, s390-linux64v1, s390-linux64v2, s390-vx-linux64. */ 76 77 static const int s390_linux64_ft_collect_regmap[] = { 78 /* 32-bit PSWA and PSWM. */ 79 FT_PSWM_U, FT_PSWA_L, 80 /* 32-bit halves of 64-bit GPRs. */ 81 FT_GPR_U (0), FT_GPR_L (0), 82 FT_GPR_U (1), FT_GPR_L (1), 83 FT_GPR_U (2), FT_GPR_L (2), 84 FT_GPR_U (3), FT_GPR_L (3), 85 FT_GPR_U (4), FT_GPR_L (4), 86 FT_GPR_U (5), FT_GPR_L (5), 87 FT_GPR_U (6), FT_GPR_L (6), 88 FT_GPR_U (7), FT_GPR_L (7), 89 FT_GPR_U (8), FT_GPR_L (8), 90 FT_GPR_U (9), FT_GPR_L (9), 91 FT_GPR_U (10), FT_GPR_L (10), 92 FT_GPR_U (11), FT_GPR_L (11), 93 FT_GPR_U (12), FT_GPR_L (12), 94 FT_GPR_U (13), FT_GPR_L (13), 95 FT_GPR_U (14), FT_GPR_L (14), 96 FT_GPR_U (15), FT_GPR_L (15), 97 /* ACRs */ 98 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3), 99 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7), 100 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11), 101 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15), 102 /* FPRs (mapped to upper halves of 128-bit VR slots). */ 103 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3), 104 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7), 105 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11), 106 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15), 107 /* orig_r2, last_break, system_call */ 108 -1, -1, -1, 109 /* Lower halves of 128-bit VRs. */ 110 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3), 111 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7), 112 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11), 113 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15), 114 /* And the next 16 VRs. */ 115 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19), 116 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23), 117 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27), 118 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31), 119 }; 120 121 /* Used for s390-te-linux64, s390-tevx-linux64, and s390-gs-linux64. */ 122 123 static const int s390_te_linux64_ft_collect_regmap[] = { 124 /* 32-bit PSWA and PSWM. */ 125 FT_PSWM_U, FT_PSWA_L, 126 /* 32-bit halves of 64-bit GPRs. */ 127 FT_GPR_U (0), FT_GPR_L (0), 128 FT_GPR_U (1), FT_GPR_L (1), 129 FT_GPR_U (2), FT_GPR_L (2), 130 FT_GPR_U (3), FT_GPR_L (3), 131 FT_GPR_U (4), FT_GPR_L (4), 132 FT_GPR_U (5), FT_GPR_L (5), 133 FT_GPR_U (6), FT_GPR_L (6), 134 FT_GPR_U (7), FT_GPR_L (7), 135 FT_GPR_U (8), FT_GPR_L (8), 136 FT_GPR_U (9), FT_GPR_L (9), 137 FT_GPR_U (10), FT_GPR_L (10), 138 FT_GPR_U (11), FT_GPR_L (11), 139 FT_GPR_U (12), FT_GPR_L (12), 140 FT_GPR_U (13), FT_GPR_L (13), 141 FT_GPR_U (14), FT_GPR_L (14), 142 FT_GPR_U (15), FT_GPR_L (15), 143 /* ACRs */ 144 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3), 145 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7), 146 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11), 147 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15), 148 /* FPRs (mapped to upper halves of 128-bit VR slots). */ 149 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3), 150 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7), 151 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11), 152 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15), 153 /* orig_r2, last_break, system_call */ 154 -1, -1, -1, 155 /* TDB */ 156 -1, -1, -1, -1, 157 -1, -1, -1, -1, 158 -1, -1, -1, -1, 159 -1, -1, -1, -1, 160 -1, -1, -1, -1, 161 /* Lower halves of 128-bit VRs. */ 162 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3), 163 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7), 164 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11), 165 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15), 166 /* And the next 16 VRs. */ 167 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19), 168 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23), 169 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27), 170 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31), 171 }; 172 173 #else /* __s390x__ */ 174 175 /* Used for s390x-linux64, s390x-linux64v1, s390x-linux64v2, s390x-vx-linux64. */ 176 177 static const int s390x_ft_collect_regmap[] = { 178 /* 64-bit PSWA and PSWM. */ 179 FT_PSWM, FT_PSWA, 180 /* 64-bit GPRs. */ 181 FT_GPR (0), FT_GPR (1), FT_GPR (2), FT_GPR (3), 182 FT_GPR (4), FT_GPR (5), FT_GPR (6), FT_GPR (7), 183 FT_GPR (8), FT_GPR (9), FT_GPR (10), FT_GPR (11), 184 FT_GPR (12), FT_GPR (13), FT_GPR (14), FT_GPR (15), 185 /* ACRs */ 186 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3), 187 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7), 188 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11), 189 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15), 190 /* FPRs (mapped to upper halves of 128-bit VR slots). */ 191 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3), 192 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7), 193 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11), 194 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15), 195 /* orig_r2, last_break, system_call */ 196 -1, -1, -1, 197 /* Lower halves of 128-bit VRs. */ 198 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3), 199 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7), 200 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11), 201 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15), 202 /* And the next 16 VRs. */ 203 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19), 204 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23), 205 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27), 206 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31), 207 }; 208 209 /* Used for s390x-te-linux64, s390x-tevx-linux64, and 210 s390x-gs-linux64. */ 211 212 static const int s390x_te_ft_collect_regmap[] = { 213 /* 64-bit PSWA and PSWM. */ 214 FT_PSWM, FT_PSWA, 215 /* 64-bit GPRs. */ 216 FT_GPR (0), FT_GPR (1), FT_GPR (2), FT_GPR (3), 217 FT_GPR (4), FT_GPR (5), FT_GPR (6), FT_GPR (7), 218 FT_GPR (8), FT_GPR (9), FT_GPR (10), FT_GPR (11), 219 FT_GPR (12), FT_GPR (13), FT_GPR (14), FT_GPR (15), 220 /* ACRs */ 221 FT_ACR (0), FT_ACR (1), FT_ACR (2), FT_ACR (3), 222 FT_ACR (4), FT_ACR (5), FT_ACR (6), FT_ACR (7), 223 FT_ACR (8), FT_ACR (9), FT_ACR (10), FT_ACR (11), 224 FT_ACR (12), FT_ACR (13), FT_ACR (14), FT_ACR (15), 225 /* FPRs (mapped to upper halves of 128-bit VR slots). */ 226 FT_FPR (0), FT_FPR (1), FT_FPR (2), FT_FPR (3), 227 FT_FPR (4), FT_FPR (5), FT_FPR (6), FT_FPR (7), 228 FT_FPR (8), FT_FPR (9), FT_FPR (10), FT_FPR (11), 229 FT_FPR (12), FT_FPR (13), FT_FPR (14), FT_FPR (15), 230 /* orig_r2, last_break, system_call */ 231 -1, -1, -1, 232 /* TDB */ 233 -1, -1, -1, -1, 234 -1, -1, -1, -1, 235 -1, -1, -1, -1, 236 -1, -1, -1, -1, 237 -1, -1, -1, -1, 238 /* Lower halves of 128-bit VRs. */ 239 FT_VR_L (0), FT_VR_L (1), FT_VR_L (2), FT_VR_L (3), 240 FT_VR_L (4), FT_VR_L (5), FT_VR_L (6), FT_VR_L (7), 241 FT_VR_L (8), FT_VR_L (9), FT_VR_L (10), FT_VR_L (11), 242 FT_VR_L (12), FT_VR_L (13), FT_VR_L (14), FT_VR_L (15), 243 /* And the next 16 VRs. */ 244 FT_VR (16), FT_VR (17), FT_VR (18), FT_VR (19), 245 FT_VR (20), FT_VR (21), FT_VR (22), FT_VR (23), 246 FT_VR (24), FT_VR (25), FT_VR (26), FT_VR (27), 247 FT_VR (28), FT_VR (29), FT_VR (30), FT_VR (31), 248 }; 249 250 #endif 251 252 /* Initialized by get_ipa_tdesc according to the tdesc in use. */ 253 254 static const int *s390_regmap; 255 static int s390_regnum; 256 257 /* Fill in REGCACHE with registers saved by the jump pad in BUF. */ 258 259 void 260 supply_fast_tracepoint_registers (struct regcache *regcache, 261 const unsigned char *buf) 262 { 263 int i; 264 for (i = 0; i < s390_regnum; i++) 265 if (s390_regmap[i] != -1) 266 supply_register (regcache, i, ((char *) buf) + s390_regmap[i]); 267 } 268 269 ULONGEST 270 get_raw_reg (const unsigned char *raw_regs, int regnum) 271 { 272 int offset; 273 if (regnum >= s390_regnum) 274 return 0; 275 offset = s390_regmap[regnum]; 276 if (offset == -1) 277 return 0; 278 279 /* The regnums are variable, better to figure out size by FT offset. */ 280 281 /* 64-bit ones. */ 282 if (offset < FT_VR(16) 283 #ifdef __s390x__ 284 || (offset >= FT_GPR(0) && offset < FT_ACR(0)) 285 || offset == FT_PSWM 286 || offset == FT_PSWA 287 #endif 288 ) 289 return *(uint64_t *) (raw_regs + offset); 290 291 if (offset >= FT_ACR(0 && offset < FT_PSWM) 292 || offset == FT_FPC 293 #ifndef __s390x__ 294 || (offset >= FT_GPR(0) && offset < FT_ACR(0)) 295 || offset == FT_PSWM_U 296 || offset == FT_PSWA_L 297 #endif 298 ) 299 return *(uint32_t *) (raw_regs + offset); 300 301 /* This leaves 128-bit VX. No way to return them. */ 302 return 0; 303 } 304 305 /* Return target_desc to use for IPA, given the tdesc index passed by 306 gdbserver. For s390, it also sets s390_regmap and s390_regnum. */ 307 308 const struct target_desc * 309 get_ipa_tdesc (int idx) 310 { 311 #define SET_REGMAP(regmap, skip_last) \ 312 do { \ 313 s390_regmap = regmap; \ 314 s390_regnum = (sizeof regmap / sizeof regmap[0]) - skip_last; \ 315 } while(0) 316 switch (idx) 317 { 318 #ifdef __s390x__ 319 case S390_TDESC_64: 320 /* Subtract number of VX regs. */ 321 SET_REGMAP(s390x_ft_collect_regmap, 32); 322 return tdesc_s390x_linux64; 323 case S390_TDESC_64V1: 324 SET_REGMAP(s390x_ft_collect_regmap, 32); 325 return tdesc_s390x_linux64v1; 326 case S390_TDESC_64V2: 327 SET_REGMAP(s390x_ft_collect_regmap, 32); 328 return tdesc_s390x_linux64v2; 329 case S390_TDESC_TE: 330 SET_REGMAP(s390x_te_ft_collect_regmap, 32); 331 return tdesc_s390x_te_linux64; 332 case S390_TDESC_VX: 333 SET_REGMAP(s390x_ft_collect_regmap, 0); 334 return tdesc_s390x_vx_linux64; 335 case S390_TDESC_TEVX: 336 SET_REGMAP(s390x_te_ft_collect_regmap, 0); 337 return tdesc_s390x_tevx_linux64; 338 case S390_TDESC_GS: 339 SET_REGMAP(s390x_te_ft_collect_regmap, 0); 340 return tdesc_s390x_gs_linux64; 341 #else 342 case S390_TDESC_32: 343 SET_REGMAP(s390_linux32_ft_collect_regmap, 0); 344 return tdesc_s390_linux32; 345 case S390_TDESC_32V1: 346 SET_REGMAP(s390_linux32_ft_collect_regmap, 0); 347 return tdesc_s390_linux32v1; 348 case S390_TDESC_32V2: 349 SET_REGMAP(s390_linux32_ft_collect_regmap, 0); 350 return tdesc_s390_linux32v2; 351 case S390_TDESC_64: 352 SET_REGMAP(s390_linux64_ft_collect_regmap, 32); 353 return tdesc_s390_linux64; 354 case S390_TDESC_64V1: 355 SET_REGMAP(s390_linux64_ft_collect_regmap, 32); 356 return tdesc_s390_linux64v1; 357 case S390_TDESC_64V2: 358 SET_REGMAP(s390_linux64_ft_collect_regmap, 32); 359 return tdesc_s390_linux64v2; 360 case S390_TDESC_TE: 361 SET_REGMAP(s390_te_linux64_ft_collect_regmap, 32); 362 return tdesc_s390_te_linux64; 363 case S390_TDESC_VX: 364 SET_REGMAP(s390_linux64_ft_collect_regmap, 0); 365 return tdesc_s390_vx_linux64; 366 case S390_TDESC_TEVX: 367 SET_REGMAP(s390_te_linux64_ft_collect_regmap, 0); 368 return tdesc_s390_tevx_linux64; 369 case S390_TDESC_GS: 370 SET_REGMAP(s390_te_linux64_ft_collect_regmap, 0); 371 return tdesc_s390_gs_linux64; 372 #endif 373 default: 374 internal_error ("unknown ipa tdesc index: %d", idx); 375 #ifdef __s390x__ 376 return tdesc_s390x_linux64; 377 #else 378 return tdesc_s390_linux32; 379 #endif 380 } 381 } 382 383 /* Allocate buffer for the jump pads. On 31-bit, JG reaches everywhere, 384 so just allocate normally. On 64-bit, we have +/-4GiB of reach, and 385 the executable is usually mapped at 0x80000000 - aim for somewhere 386 below it. */ 387 388 void * 389 alloc_jump_pad_buffer (size_t size) 390 { 391 #ifdef __s390x__ 392 uintptr_t addr; 393 uintptr_t exec_base = getauxval (AT_PHDR); 394 int pagesize; 395 void *res; 396 397 if (exec_base == 0) 398 exec_base = 0x80000000; 399 400 pagesize = sysconf (_SC_PAGE_SIZE); 401 if (pagesize == -1) 402 perror_with_name ("sysconf"); 403 404 addr = exec_base - size; 405 406 /* size should already be page-aligned, but this can't hurt. */ 407 addr &= ~(pagesize - 1); 408 409 /* Search for a free area. If we hit 0, we're out of luck. */ 410 for (; addr; addr -= pagesize) 411 { 412 /* No MAP_FIXED - we don't want to zap someone's mapping. */ 413 res = mmap ((void *) addr, size, 414 PROT_READ | PROT_WRITE | PROT_EXEC, 415 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 416 417 /* If we got what we wanted, return. */ 418 if ((uintptr_t) res == addr) 419 return res; 420 421 /* If we got a mapping, but at a wrong address, undo it. */ 422 if (res != MAP_FAILED) 423 munmap (res, size); 424 } 425 426 return NULL; 427 #else 428 void *res = mmap (NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, 429 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 430 431 if (res == MAP_FAILED) 432 return NULL; 433 434 return res; 435 #endif 436 } 437 438 void 439 initialize_low_tracepoint (void) 440 { 441 #ifdef __s390x__ 442 init_registers_s390x_linux64 (); 443 init_registers_s390x_linux64v1 (); 444 init_registers_s390x_linux64v2 (); 445 init_registers_s390x_te_linux64 (); 446 init_registers_s390x_vx_linux64 (); 447 init_registers_s390x_tevx_linux64 (); 448 init_registers_s390x_gs_linux64 (); 449 #else 450 init_registers_s390_linux32 (); 451 init_registers_s390_linux32v1 (); 452 init_registers_s390_linux32v2 (); 453 init_registers_s390_linux64 (); 454 init_registers_s390_linux64v1 (); 455 init_registers_s390_linux64v2 (); 456 init_registers_s390_te_linux64 (); 457 init_registers_s390_vx_linux64 (); 458 init_registers_s390_tevx_linux64 (); 459 init_registers_s390_gs_linux64 (); 460 #endif 461 } 462