GDBserver
|
00001 /* GNU/Linux S/390 specific low level interface, for the remote server 00002 for GDB. 00003 Copyright (C) 2001-2013 Free Software Foundation, Inc. 00004 00005 This file is part of GDB. 00006 00007 This program is free software; you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation; either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00019 00020 /* This file is used for both 31-bit and 64-bit S/390 systems. */ 00021 00022 #include "server.h" 00023 #include "linux-low.h" 00024 #include "elf/common.h" 00025 00026 #include <asm/ptrace.h> 00027 #include <sys/ptrace.h> 00028 #include <sys/uio.h> 00029 #include <elf.h> 00030 00031 #ifndef HWCAP_S390_HIGH_GPRS 00032 #define HWCAP_S390_HIGH_GPRS 512 00033 #endif 00034 00035 #ifndef PTRACE_GETREGSET 00036 #define PTRACE_GETREGSET 0x4204 00037 #endif 00038 00039 #ifndef PTRACE_SETREGSET 00040 #define PTRACE_SETREGSET 0x4205 00041 #endif 00042 00043 /* Defined in auto-generated file s390-linux32.c. */ 00044 void init_registers_s390_linux32 (void); 00045 extern const struct target_desc *tdesc_s390_linux32; 00046 00047 /* Defined in auto-generated file s390-linux32v1.c. */ 00048 void init_registers_s390_linux32v1 (void); 00049 extern const struct target_desc *tdesc_s390_linux32v1; 00050 00051 /* Defined in auto-generated file s390-linux32v2.c. */ 00052 void init_registers_s390_linux32v2 (void); 00053 extern const struct target_desc *tdesc_s390_linux32v2; 00054 00055 /* Defined in auto-generated file s390-linux64.c. */ 00056 void init_registers_s390_linux64 (void); 00057 extern const struct target_desc *tdesc_s390_linux64; 00058 00059 /* Defined in auto-generated file s390-linux64v1.c. */ 00060 void init_registers_s390_linux64v1 (void); 00061 extern const struct target_desc *tdesc_s390_linux64v1; 00062 00063 /* Defined in auto-generated file s390-linux64v2.c. */ 00064 void init_registers_s390_linux64v2 (void); 00065 extern const struct target_desc *tdesc_s390_linux64v2; 00066 00067 /* Defined in auto-generated file s390-te-linux64.c. */ 00068 void init_registers_s390_te_linux64 (void); 00069 extern const struct target_desc *tdesc_s390_te_linux64; 00070 00071 /* Defined in auto-generated file s390x-linux64.c. */ 00072 void init_registers_s390x_linux64 (void); 00073 extern const struct target_desc *tdesc_s390x_linux64; 00074 00075 /* Defined in auto-generated file s390x-linux64v1.c. */ 00076 void init_registers_s390x_linux64v1 (void); 00077 extern const struct target_desc *tdesc_s390x_linux64v1; 00078 00079 /* Defined in auto-generated file s390x-linux64v2.c. */ 00080 void init_registers_s390x_linux64v2 (void); 00081 extern const struct target_desc *tdesc_s390x_linux64v2; 00082 00083 /* Defined in auto-generated file s390x-te-linux64.c. */ 00084 void init_registers_s390x_te_linux64 (void); 00085 extern const struct target_desc *tdesc_s390x_te_linux64; 00086 00087 #define s390_num_regs 52 00088 00089 static int s390_regmap[] = { 00090 PT_PSWMASK, PT_PSWADDR, 00091 00092 PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3, 00093 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7, 00094 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11, 00095 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15, 00096 00097 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3, 00098 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7, 00099 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11, 00100 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15, 00101 00102 PT_FPC, 00103 00104 #ifndef __s390x__ 00105 PT_FPR0_HI, PT_FPR1_HI, PT_FPR2_HI, PT_FPR3_HI, 00106 PT_FPR4_HI, PT_FPR5_HI, PT_FPR6_HI, PT_FPR7_HI, 00107 PT_FPR8_HI, PT_FPR9_HI, PT_FPR10_HI, PT_FPR11_HI, 00108 PT_FPR12_HI, PT_FPR13_HI, PT_FPR14_HI, PT_FPR15_HI, 00109 #else 00110 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3, 00111 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7, 00112 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11, 00113 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15, 00114 #endif 00115 00116 PT_ORIGGPR2, 00117 }; 00118 00119 #ifdef __s390x__ 00120 #define s390_num_regs_3264 68 00121 00122 static int s390_regmap_3264[] = { 00123 PT_PSWMASK, PT_PSWADDR, 00124 00125 PT_GPR0, PT_GPR0, PT_GPR1, PT_GPR1, 00126 PT_GPR2, PT_GPR2, PT_GPR3, PT_GPR3, 00127 PT_GPR4, PT_GPR4, PT_GPR5, PT_GPR5, 00128 PT_GPR6, PT_GPR6, PT_GPR7, PT_GPR7, 00129 PT_GPR8, PT_GPR8, PT_GPR9, PT_GPR9, 00130 PT_GPR10, PT_GPR10, PT_GPR11, PT_GPR11, 00131 PT_GPR12, PT_GPR12, PT_GPR13, PT_GPR13, 00132 PT_GPR14, PT_GPR14, PT_GPR15, PT_GPR15, 00133 00134 PT_ACR0, PT_ACR1, PT_ACR2, PT_ACR3, 00135 PT_ACR4, PT_ACR5, PT_ACR6, PT_ACR7, 00136 PT_ACR8, PT_ACR9, PT_ACR10, PT_ACR11, 00137 PT_ACR12, PT_ACR13, PT_ACR14, PT_ACR15, 00138 00139 PT_FPC, 00140 00141 PT_FPR0, PT_FPR1, PT_FPR2, PT_FPR3, 00142 PT_FPR4, PT_FPR5, PT_FPR6, PT_FPR7, 00143 PT_FPR8, PT_FPR9, PT_FPR10, PT_FPR11, 00144 PT_FPR12, PT_FPR13, PT_FPR14, PT_FPR15, 00145 00146 PT_ORIGGPR2, 00147 }; 00148 #endif 00149 00150 00151 static int 00152 s390_cannot_fetch_register (int regno) 00153 { 00154 return 0; 00155 } 00156 00157 static int 00158 s390_cannot_store_register (int regno) 00159 { 00160 return 0; 00161 } 00162 00163 static void 00164 s390_collect_ptrace_register (struct regcache *regcache, int regno, char *buf) 00165 { 00166 int size = register_size (regcache->tdesc, regno); 00167 if (size < sizeof (long)) 00168 { 00169 const struct regs_info *regs_info = (*the_low_target.regs_info) (); 00170 struct usrregs_info *usr = regs_info->usrregs; 00171 int regaddr = usr->regmap[regno]; 00172 00173 memset (buf, 0, sizeof (long)); 00174 00175 if ((regno ^ 1) < usr->num_regs 00176 && usr->regmap[regno ^ 1] == regaddr) 00177 { 00178 collect_register (regcache, regno & ~1, buf); 00179 collect_register (regcache, (regno & ~1) + 1, 00180 buf + sizeof (long) - size); 00181 } 00182 else if (regaddr == PT_PSWMASK) 00183 { 00184 /* Convert 4-byte PSW mask to 8 bytes by clearing bit 12 and copying 00185 the basic addressing mode bit from the PSW address. */ 00186 char *addr = alloca (register_size (regcache->tdesc, regno ^ 1)); 00187 collect_register (regcache, regno, buf); 00188 collect_register (regcache, regno ^ 1, addr); 00189 buf[1] &= ~0x8; 00190 buf[size] |= (addr[0] & 0x80); 00191 } 00192 else if (regaddr == PT_PSWADDR) 00193 { 00194 /* Convert 4-byte PSW address to 8 bytes by clearing the addressing 00195 mode bit (which gets copied to the PSW mask instead). */ 00196 collect_register (regcache, regno, buf + sizeof (long) - size); 00197 buf[sizeof (long) - size] &= ~0x80; 00198 } 00199 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15) 00200 || regaddr == PT_ORIGGPR2) 00201 collect_register (regcache, regno, buf + sizeof (long) - size); 00202 else 00203 collect_register (regcache, regno, buf); 00204 } 00205 else 00206 collect_register (regcache, regno, buf); 00207 } 00208 00209 static void 00210 s390_supply_ptrace_register (struct regcache *regcache, 00211 int regno, const char *buf) 00212 { 00213 int size = register_size (regcache->tdesc, regno); 00214 if (size < sizeof (long)) 00215 { 00216 const struct regs_info *regs_info = (*the_low_target.regs_info) (); 00217 struct usrregs_info *usr = regs_info->usrregs; 00218 int regaddr = usr->regmap[regno]; 00219 00220 if ((regno ^ 1) < usr->num_regs 00221 && usr->regmap[regno ^ 1] == regaddr) 00222 { 00223 supply_register (regcache, regno & ~1, buf); 00224 supply_register (regcache, (regno & ~1) + 1, 00225 buf + sizeof (long) - size); 00226 } 00227 else if (regaddr == PT_PSWMASK) 00228 { 00229 /* Convert 8-byte PSW mask to 4 bytes by setting bit 12 and copying 00230 the basic addressing mode into the PSW address. */ 00231 char *mask = alloca (size); 00232 char *addr = alloca (register_size (regcache->tdesc, regno ^ 1)); 00233 memcpy (mask, buf, size); 00234 mask[1] |= 0x8; 00235 supply_register (regcache, regno, mask); 00236 00237 collect_register (regcache, regno ^ 1, addr); 00238 addr[0] &= ~0x80; 00239 addr[0] |= (buf[size] & 0x80); 00240 supply_register (regcache, regno ^ 1, addr); 00241 } 00242 else if (regaddr == PT_PSWADDR) 00243 { 00244 /* Convert 8-byte PSW address to 4 bytes by truncating, but 00245 keeping the addressing mode bit (which was set from the mask). */ 00246 char *addr = alloca (size); 00247 char amode; 00248 collect_register (regcache, regno, addr); 00249 amode = addr[0] & 0x80; 00250 memcpy (addr, buf + sizeof (long) - size, size); 00251 addr[0] &= ~0x80; 00252 addr[0] |= amode; 00253 supply_register (regcache, regno, addr); 00254 } 00255 else if ((regaddr >= PT_GPR0 && regaddr <= PT_GPR15) 00256 || regaddr == PT_ORIGGPR2) 00257 supply_register (regcache, regno, buf + sizeof (long) - size); 00258 else 00259 supply_register (regcache, regno, buf); 00260 } 00261 else 00262 supply_register (regcache, regno, buf); 00263 } 00264 00265 /* Provide only a fill function for the general register set. ps_lgetregs 00266 will use this for NPTL support. */ 00267 00268 static void 00269 s390_fill_gregset (struct regcache *regcache, void *buf) 00270 { 00271 int i; 00272 const struct regs_info *regs_info = (*the_low_target.regs_info) (); 00273 struct usrregs_info *usr = regs_info->usrregs; 00274 00275 for (i = 0; i < usr->num_regs; i++) 00276 { 00277 if (usr->regmap[i] < PT_PSWMASK 00278 || usr->regmap[i] > PT_ACR15) 00279 continue; 00280 00281 s390_collect_ptrace_register (regcache, i, 00282 (char *) buf + usr->regmap[i]); 00283 } 00284 } 00285 00286 /* Fill and store functions for extended register sets. */ 00287 00288 static void 00289 s390_fill_last_break (struct regcache *regcache, void *buf) 00290 { 00291 /* Last break address is read-only. */ 00292 } 00293 00294 static void 00295 s390_store_last_break (struct regcache *regcache, const void *buf) 00296 { 00297 const char *p; 00298 00299 p = (const char *) buf + 8 - register_size (regcache->tdesc, 0); 00300 supply_register_by_name (regcache, "last_break", p); 00301 } 00302 00303 static void 00304 s390_fill_system_call (struct regcache *regcache, void *buf) 00305 { 00306 collect_register_by_name (regcache, "system_call", buf); 00307 } 00308 00309 static void 00310 s390_store_system_call (struct regcache *regcache, const void *buf) 00311 { 00312 supply_register_by_name (regcache, "system_call", buf); 00313 } 00314 00315 static struct regset_info s390_regsets[] = { 00316 { 0, 0, 0, 0, GENERAL_REGS, s390_fill_gregset, NULL }, 00317 /* Last break address is read-only; do not attempt PTRACE_SETREGSET. */ 00318 { PTRACE_GETREGSET, PTRACE_GETREGSET, NT_S390_LAST_BREAK, 0, 00319 EXTENDED_REGS, s390_fill_last_break, s390_store_last_break }, 00320 { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_S390_SYSTEM_CALL, 0, 00321 EXTENDED_REGS, s390_fill_system_call, s390_store_system_call }, 00322 { 0, 0, 0, -1, -1, NULL, NULL } 00323 }; 00324 00325 00326 static const unsigned char s390_breakpoint[] = { 0, 1 }; 00327 #define s390_breakpoint_len 2 00328 00329 static CORE_ADDR 00330 s390_get_pc (struct regcache *regcache) 00331 { 00332 if (register_size (regcache->tdesc, 0) == 4) 00333 { 00334 unsigned int pswa; 00335 collect_register_by_name (regcache, "pswa", &pswa); 00336 return pswa & 0x7fffffff; 00337 } 00338 else 00339 { 00340 unsigned long pc; 00341 collect_register_by_name (regcache, "pswa", &pc); 00342 return pc; 00343 } 00344 } 00345 00346 static void 00347 s390_set_pc (struct regcache *regcache, CORE_ADDR newpc) 00348 { 00349 if (register_size (regcache->tdesc, 0) == 4) 00350 { 00351 unsigned int pswa; 00352 collect_register_by_name (regcache, "pswa", &pswa); 00353 pswa = (pswa & 0x80000000) | (newpc & 0x7fffffff); 00354 supply_register_by_name (regcache, "pswa", &pswa); 00355 } 00356 else 00357 { 00358 unsigned long pc = newpc; 00359 supply_register_by_name (regcache, "pswa", &pc); 00360 } 00361 } 00362 00363 #ifdef __s390x__ 00364 static unsigned long 00365 s390_get_hwcap (const struct target_desc *tdesc) 00366 { 00367 int wordsize = register_size (tdesc, 0); 00368 unsigned char *data = alloca (2 * wordsize); 00369 int offset = 0; 00370 00371 while ((*the_target->read_auxv) (offset, data, 2 * wordsize) == 2 * wordsize) 00372 { 00373 if (wordsize == 4) 00374 { 00375 unsigned int *data_p = (unsigned int *)data; 00376 if (data_p[0] == AT_HWCAP) 00377 return data_p[1]; 00378 } 00379 else 00380 { 00381 unsigned long *data_p = (unsigned long *)data; 00382 if (data_p[0] == AT_HWCAP) 00383 return data_p[1]; 00384 } 00385 00386 offset += 2 * wordsize; 00387 } 00388 00389 return 0; 00390 } 00391 #endif 00392 00393 static int 00394 s390_check_regset (int pid, int regset, int regsize) 00395 { 00396 gdb_byte *buf = alloca (regsize); 00397 struct iovec iov; 00398 00399 iov.iov_base = buf; 00400 iov.iov_len = regsize; 00401 00402 if (ptrace (PTRACE_GETREGSET, pid, (long) regset, (long) &iov) >= 0 00403 || errno == ENODATA) 00404 return 1; 00405 return 0; 00406 } 00407 00408 #ifdef __s390x__ 00409 /* For a 31-bit inferior, whether the kernel supports using the full 00410 64-bit GPRs. */ 00411 static int have_hwcap_s390_high_gprs = 0; 00412 #endif 00413 00414 static void 00415 s390_arch_setup (void) 00416 { 00417 const struct target_desc *tdesc; 00418 struct regset_info *regset; 00419 00420 /* Check whether the kernel supports extra register sets. */ 00421 int pid = pid_of (get_thread_lwp (current_inferior)); 00422 int have_regset_last_break 00423 = s390_check_regset (pid, NT_S390_LAST_BREAK, 8); 00424 int have_regset_system_call 00425 = s390_check_regset (pid, NT_S390_SYSTEM_CALL, 4); 00426 int have_regset_tdb = s390_check_regset (pid, NT_S390_TDB, 256); 00427 00428 /* Update target_regsets according to available register sets. */ 00429 for (regset = s390_regsets; regset->fill_function != NULL; regset++) 00430 if (regset->get_request == PTRACE_GETREGSET) 00431 switch (regset->nt_type) 00432 { 00433 case NT_S390_LAST_BREAK: 00434 regset->size = have_regset_last_break? 8 : 0; 00435 break; 00436 case NT_S390_SYSTEM_CALL: 00437 regset->size = have_regset_system_call? 4 : 0; 00438 break; 00439 case NT_S390_TDB: 00440 regset->size = have_regset_tdb ? 256 : 0; 00441 default: 00442 break; 00443 } 00444 00445 /* Assume 31-bit inferior process. */ 00446 if (have_regset_system_call) 00447 tdesc = tdesc_s390_linux32v2; 00448 else if (have_regset_last_break) 00449 tdesc = tdesc_s390_linux32v1; 00450 else 00451 tdesc = tdesc_s390_linux32; 00452 00453 /* On a 64-bit host, check the low bit of the (31-bit) PSWM 00454 -- if this is one, we actually have a 64-bit inferior. */ 00455 #ifdef __s390x__ 00456 { 00457 unsigned int pswm; 00458 struct regcache *regcache = new_register_cache (tdesc); 00459 fetch_inferior_registers (regcache, find_regno (tdesc, "pswm")); 00460 collect_register_by_name (regcache, "pswm", &pswm); 00461 free_register_cache (regcache); 00462 00463 if (pswm & 1) 00464 { 00465 if (have_regset_tdb) 00466 tdesc = tdesc_s390x_te_linux64; 00467 if (have_regset_system_call) 00468 tdesc = tdesc_s390x_linux64v2; 00469 else if (have_regset_last_break) 00470 tdesc = tdesc_s390x_linux64v1; 00471 else 00472 tdesc = tdesc_s390x_linux64; 00473 } 00474 00475 /* For a 31-bit inferior, check whether the kernel supports 00476 using the full 64-bit GPRs. */ 00477 else if (s390_get_hwcap (tdesc) & HWCAP_S390_HIGH_GPRS) 00478 { 00479 have_hwcap_s390_high_gprs = 1; 00480 00481 if (have_regset_tdb) 00482 tdesc = tdesc_s390_te_linux64; 00483 else if (have_regset_system_call) 00484 tdesc = tdesc_s390_linux64v2; 00485 else if (have_regset_last_break) 00486 tdesc = tdesc_s390_linux64v1; 00487 else 00488 tdesc = tdesc_s390_linux64; 00489 } 00490 } 00491 #endif 00492 current_process ()->tdesc = tdesc; 00493 } 00494 00495 00496 static int 00497 s390_breakpoint_at (CORE_ADDR pc) 00498 { 00499 unsigned char c[s390_breakpoint_len]; 00500 read_inferior_memory (pc, c, s390_breakpoint_len); 00501 return memcmp (c, s390_breakpoint, s390_breakpoint_len) == 0; 00502 } 00503 00504 static struct usrregs_info s390_usrregs_info = 00505 { 00506 s390_num_regs, 00507 s390_regmap, 00508 }; 00509 00510 static struct regsets_info s390_regsets_info = 00511 { 00512 s390_regsets, /* regsets */ 00513 0, /* num_regsets */ 00514 NULL, /* disabled_regsets */ 00515 }; 00516 00517 static struct regs_info regs_info = 00518 { 00519 NULL, /* regset_bitmap */ 00520 &s390_usrregs_info, 00521 &s390_regsets_info 00522 }; 00523 00524 #ifdef __s390x__ 00525 static struct usrregs_info s390_usrregs_info_3264 = 00526 { 00527 s390_num_regs_3264, 00528 s390_regmap_3264 00529 }; 00530 00531 static struct regsets_info s390_regsets_info_3264 = 00532 { 00533 s390_regsets, /* regsets */ 00534 0, /* num_regsets */ 00535 NULL, /* disabled_regsets */ 00536 }; 00537 00538 static struct regs_info regs_info_3264 = 00539 { 00540 NULL, /* regset_bitmap */ 00541 &s390_usrregs_info_3264, 00542 &s390_regsets_info_3264 00543 }; 00544 #endif 00545 00546 static const struct regs_info * 00547 s390_regs_info (void) 00548 { 00549 #ifdef __s390x__ 00550 if (have_hwcap_s390_high_gprs) 00551 { 00552 const struct target_desc *tdesc = current_process ()->tdesc; 00553 00554 if (register_size (tdesc, 0) == 4) 00555 return ®s_info_3264; 00556 } 00557 #endif 00558 return ®s_info; 00559 } 00560 00561 struct linux_target_ops the_low_target = { 00562 s390_arch_setup, 00563 s390_regs_info, 00564 s390_cannot_fetch_register, 00565 s390_cannot_store_register, 00566 NULL, /* fetch_register */ 00567 s390_get_pc, 00568 s390_set_pc, 00569 s390_breakpoint, 00570 s390_breakpoint_len, 00571 NULL, 00572 s390_breakpoint_len, 00573 s390_breakpoint_at, 00574 NULL, 00575 NULL, 00576 NULL, 00577 NULL, 00578 s390_collect_ptrace_register, 00579 s390_supply_ptrace_register, 00580 }; 00581 00582 void 00583 initialize_low_arch (void) 00584 { 00585 /* Initialize the Linux target descriptions. */ 00586 00587 init_registers_s390_linux32 (); 00588 init_registers_s390_linux32v1 (); 00589 init_registers_s390_linux32v2 (); 00590 init_registers_s390_linux64 (); 00591 init_registers_s390_linux64v1 (); 00592 init_registers_s390_linux64v2 (); 00593 init_registers_s390_te_linux64 (); 00594 init_registers_s390x_linux64 (); 00595 init_registers_s390x_linux64v1 (); 00596 init_registers_s390x_linux64v2 (); 00597 init_registers_s390x_te_linux64 (); 00598 00599 initialize_regsets_info (&s390_regsets_info); 00600 #ifdef __s390x__ 00601 initialize_regsets_info (&s390_regsets_info_3264); 00602 #endif 00603 }