GDB (API)
|
00001 /* S390 native-dependent code for GDB, the GNU debugger. 00002 Copyright (C) 2001-2013 Free Software Foundation, Inc. 00003 00004 Contributed by D.J. Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 00005 for IBM Deutschland Entwicklung GmbH, IBM Corporation. 00006 00007 This file is part of GDB. 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 #include "defs.h" 00023 #include "regcache.h" 00024 #include "inferior.h" 00025 #include "target.h" 00026 #include "linux-nat.h" 00027 #include "auxv.h" 00028 #include "gregset.h" 00029 00030 #include "s390-tdep.h" 00031 #include "elf/common.h" 00032 00033 #include <asm/ptrace.h> 00034 #include <sys/ptrace.h> 00035 #include <asm/types.h> 00036 #include <sys/procfs.h> 00037 #include <sys/ucontext.h> 00038 #include <elf.h> 00039 00040 #ifndef PTRACE_GETREGSET 00041 #define PTRACE_GETREGSET 0x4204 00042 #endif 00043 00044 #ifndef PTRACE_SETREGSET 00045 #define PTRACE_SETREGSET 0x4205 00046 #endif 00047 00048 static int have_regset_last_break = 0; 00049 static int have_regset_system_call = 0; 00050 static int have_regset_tdb = 0; 00051 00052 /* Map registers to gregset/ptrace offsets. 00053 These arrays are defined in s390-tdep.c. */ 00054 00055 #ifdef __s390x__ 00056 #define regmap_gregset s390x_regmap_gregset 00057 #else 00058 #define regmap_gregset s390_regmap_gregset 00059 #endif 00060 00061 #define regmap_fpregset s390_regmap_fpregset 00062 00063 /* Fill the regset described by MAP into REGCACHE, using the values 00064 from REGP. The MAP array represents each register as a pair 00065 (offset, regno) of short integers and is terminated with -1. */ 00066 00067 static void 00068 s390_native_supply (struct regcache *regcache, const short *map, 00069 const gdb_byte *regp) 00070 { 00071 for (; map[0] >= 0; map += 2) 00072 regcache_raw_supply (regcache, map[1], regp ? regp + map[0] : NULL); 00073 } 00074 00075 /* Collect the register REGNO out of the regset described by MAP from 00076 REGCACHE into REGP. If REGNO == -1, do this for all registers in 00077 this regset. */ 00078 00079 static void 00080 s390_native_collect (const struct regcache *regcache, const short *map, 00081 int regno, gdb_byte *regp) 00082 { 00083 for (; map[0] >= 0; map += 2) 00084 if (regno == -1 || regno == map[1]) 00085 regcache_raw_collect (regcache, map[1], regp + map[0]); 00086 } 00087 00088 /* Fill GDB's register array with the general-purpose register values 00089 in *REGP. 00090 00091 When debugging a 32-bit executable running under a 64-bit kernel, 00092 we have to fix up the 64-bit registers we get from the kernel to 00093 make them look like 32-bit registers. */ 00094 00095 void 00096 supply_gregset (struct regcache *regcache, const gregset_t *regp) 00097 { 00098 #ifdef __s390x__ 00099 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00100 if (gdbarch_ptr_bit (gdbarch) == 32) 00101 { 00102 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00103 ULONGEST pswm = 0, pswa = 0; 00104 gdb_byte buf[4]; 00105 const short *map; 00106 00107 for (map = regmap_gregset; map[0] >= 0; map += 2) 00108 { 00109 const gdb_byte *p = (const gdb_byte *) regp + map[0]; 00110 int regno = map[1]; 00111 00112 if (regno == S390_PSWM_REGNUM) 00113 pswm = extract_unsigned_integer (p, 8, byte_order); 00114 else if (regno == S390_PSWA_REGNUM) 00115 pswa = extract_unsigned_integer (p, 8, byte_order); 00116 else 00117 { 00118 if ((regno >= S390_R0_REGNUM && regno <= S390_R15_REGNUM) 00119 || regno == S390_ORIG_R2_REGNUM) 00120 p += 4; 00121 regcache_raw_supply (regcache, regno, p); 00122 } 00123 } 00124 00125 store_unsigned_integer (buf, 4, byte_order, (pswm >> 32) | 0x80000); 00126 regcache_raw_supply (regcache, S390_PSWM_REGNUM, buf); 00127 store_unsigned_integer (buf, 4, byte_order, 00128 (pswa & 0x7fffffff) | (pswm & 0x80000000)); 00129 regcache_raw_supply (regcache, S390_PSWA_REGNUM, buf); 00130 return; 00131 } 00132 #endif 00133 00134 s390_native_supply (regcache, regmap_gregset, (const gdb_byte *) regp); 00135 } 00136 00137 /* Fill register REGNO (if it is a general-purpose register) in 00138 *REGP with the value in GDB's register array. If REGNO is -1, 00139 do this for all registers. */ 00140 00141 void 00142 fill_gregset (const struct regcache *regcache, gregset_t *regp, int regno) 00143 { 00144 #ifdef __s390x__ 00145 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00146 if (gdbarch_ptr_bit (gdbarch) == 32) 00147 { 00148 gdb_byte *psw_p[2]; 00149 const short *map; 00150 00151 for (map = regmap_gregset; map[0] >= 0; map += 2) 00152 { 00153 gdb_byte *p = (gdb_byte *) regp + map[0]; 00154 int reg = map[1]; 00155 00156 if (reg >= S390_PSWM_REGNUM && reg <= S390_PSWA_REGNUM) 00157 psw_p[reg - S390_PSWM_REGNUM] = p; 00158 00159 else if (regno == -1 || regno == reg) 00160 { 00161 if ((reg >= S390_R0_REGNUM && reg <= S390_R15_REGNUM) 00162 || reg == S390_ORIG_R2_REGNUM) 00163 { 00164 memset (p, 0, 4); 00165 p += 4; 00166 } 00167 regcache_raw_collect (regcache, reg, p + 4); 00168 } 00169 } 00170 00171 if (regno == -1 00172 || regno == S390_PSWM_REGNUM || regno == S390_PSWA_REGNUM) 00173 { 00174 enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); 00175 ULONGEST pswa, pswm; 00176 gdb_byte buf[4]; 00177 00178 regcache_raw_collect (regcache, S390_PSWM_REGNUM, buf); 00179 pswm = extract_unsigned_integer (buf, 4, byte_order); 00180 regcache_raw_collect (regcache, S390_PSWA_REGNUM, buf); 00181 pswa = extract_unsigned_integer (buf, 4, byte_order); 00182 00183 if (regno == -1 || regno == S390_PSWM_REGNUM) 00184 store_unsigned_integer (psw_p[0], 8, byte_order, 00185 ((pswm & 0xfff7ffff) << 32) | 00186 (pswa & 0x80000000)); 00187 if (regno == -1 || regno == S390_PSWA_REGNUM) 00188 store_unsigned_integer (psw_p[1], 8, byte_order, 00189 pswa & 0x7fffffff); 00190 } 00191 return; 00192 } 00193 #endif 00194 00195 s390_native_collect (regcache, regmap_gregset, regno, (gdb_byte *) regp); 00196 } 00197 00198 /* Fill GDB's register array with the floating-point register values 00199 in *REGP. */ 00200 void 00201 supply_fpregset (struct regcache *regcache, const fpregset_t *regp) 00202 { 00203 s390_native_supply (regcache, regmap_fpregset, (const gdb_byte *) regp); 00204 } 00205 00206 /* Fill register REGNO (if it is a general-purpose register) in 00207 *REGP with the value in GDB's register array. If REGNO is -1, 00208 do this for all registers. */ 00209 void 00210 fill_fpregset (const struct regcache *regcache, fpregset_t *regp, int regno) 00211 { 00212 s390_native_collect (regcache, regmap_fpregset, regno, (gdb_byte *) regp); 00213 } 00214 00215 /* Find the TID for the current inferior thread to use with ptrace. */ 00216 static int 00217 s390_inferior_tid (void) 00218 { 00219 /* GNU/Linux LWP ID's are process ID's. */ 00220 int tid = ptid_get_lwp (inferior_ptid); 00221 if (tid == 0) 00222 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ 00223 00224 return tid; 00225 } 00226 00227 /* Fetch all general-purpose registers from process/thread TID and 00228 store their values in GDB's register cache. */ 00229 static void 00230 fetch_regs (struct regcache *regcache, int tid) 00231 { 00232 gregset_t regs; 00233 ptrace_area parea; 00234 00235 parea.len = sizeof (regs); 00236 parea.process_addr = (addr_t) ®s; 00237 parea.kernel_addr = offsetof (struct user_regs_struct, psw); 00238 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) 00239 perror_with_name (_("Couldn't get registers")); 00240 00241 supply_gregset (regcache, (const gregset_t *) ®s); 00242 } 00243 00244 /* Store all valid general-purpose registers in GDB's register cache 00245 into the process/thread specified by TID. */ 00246 static void 00247 store_regs (const struct regcache *regcache, int tid, int regnum) 00248 { 00249 gregset_t regs; 00250 ptrace_area parea; 00251 00252 parea.len = sizeof (regs); 00253 parea.process_addr = (addr_t) ®s; 00254 parea.kernel_addr = offsetof (struct user_regs_struct, psw); 00255 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) 00256 perror_with_name (_("Couldn't get registers")); 00257 00258 fill_gregset (regcache, ®s, regnum); 00259 00260 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0) 00261 perror_with_name (_("Couldn't write registers")); 00262 } 00263 00264 /* Fetch all floating-point registers from process/thread TID and store 00265 their values in GDB's register cache. */ 00266 static void 00267 fetch_fpregs (struct regcache *regcache, int tid) 00268 { 00269 fpregset_t fpregs; 00270 ptrace_area parea; 00271 00272 parea.len = sizeof (fpregs); 00273 parea.process_addr = (addr_t) &fpregs; 00274 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs); 00275 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) 00276 perror_with_name (_("Couldn't get floating point status")); 00277 00278 supply_fpregset (regcache, (const fpregset_t *) &fpregs); 00279 } 00280 00281 /* Store all valid floating-point registers in GDB's register cache 00282 into the process/thread specified by TID. */ 00283 static void 00284 store_fpregs (const struct regcache *regcache, int tid, int regnum) 00285 { 00286 fpregset_t fpregs; 00287 ptrace_area parea; 00288 00289 parea.len = sizeof (fpregs); 00290 parea.process_addr = (addr_t) &fpregs; 00291 parea.kernel_addr = offsetof (struct user_regs_struct, fp_regs); 00292 if (ptrace (PTRACE_PEEKUSR_AREA, tid, (long) &parea) < 0) 00293 perror_with_name (_("Couldn't get floating point status")); 00294 00295 fill_fpregset (regcache, &fpregs, regnum); 00296 00297 if (ptrace (PTRACE_POKEUSR_AREA, tid, (long) &parea) < 0) 00298 perror_with_name (_("Couldn't write floating point status")); 00299 } 00300 00301 /* Fetch all registers in the kernel's register set whose number is REGSET, 00302 whose size is REGSIZE, and whose layout is described by REGMAP, from 00303 process/thread TID and store their values in GDB's register cache. */ 00304 static void 00305 fetch_regset (struct regcache *regcache, int tid, 00306 int regset, int regsize, const short *regmap) 00307 { 00308 gdb_byte *buf = alloca (regsize); 00309 struct iovec iov; 00310 00311 iov.iov_base = buf; 00312 iov.iov_len = regsize; 00313 00314 if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0) 00315 { 00316 if (errno == ENODATA) 00317 s390_native_supply (regcache, regmap, NULL); 00318 else 00319 perror_with_name (_("Couldn't get register set")); 00320 } 00321 else 00322 s390_native_supply (regcache, regmap, buf); 00323 } 00324 00325 /* Store all registers in the kernel's register set whose number is REGSET, 00326 whose size is REGSIZE, and whose layout is described by REGMAP, from 00327 GDB's register cache back to process/thread TID. */ 00328 static void 00329 store_regset (struct regcache *regcache, int tid, 00330 int regset, int regsize, const short *regmap) 00331 { 00332 gdb_byte *buf = alloca (regsize); 00333 struct iovec iov; 00334 00335 iov.iov_base = buf; 00336 iov.iov_len = regsize; 00337 00338 if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) < 0) 00339 perror_with_name (_("Couldn't get register set")); 00340 00341 s390_native_collect (regcache, regmap, -1, buf); 00342 00343 if (ptrace (PTRACE_SETREGSET, tid, (long) regset, (long) &iov) < 0) 00344 perror_with_name (_("Couldn't set register set")); 00345 } 00346 00347 /* Check whether the kernel provides a register set with number REGSET 00348 of size REGSIZE for process/thread TID. */ 00349 static int 00350 check_regset (int tid, int regset, int regsize) 00351 { 00352 gdb_byte *buf = alloca (regsize); 00353 struct iovec iov; 00354 00355 iov.iov_base = buf; 00356 iov.iov_len = regsize; 00357 00358 if (ptrace (PTRACE_GETREGSET, tid, (long) regset, (long) &iov) >= 0 00359 || errno == ENODATA) 00360 return 1; 00361 return 0; 00362 } 00363 00364 /* Fetch register REGNUM from the child process. If REGNUM is -1, do 00365 this for all registers. */ 00366 static void 00367 s390_linux_fetch_inferior_registers (struct target_ops *ops, 00368 struct regcache *regcache, int regnum) 00369 { 00370 int tid = s390_inferior_tid (); 00371 00372 if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum)) 00373 fetch_regs (regcache, tid); 00374 00375 if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum)) 00376 fetch_fpregs (regcache, tid); 00377 00378 if (have_regset_last_break) 00379 if (regnum == -1 || regnum == S390_LAST_BREAK_REGNUM) 00380 fetch_regset (regcache, tid, NT_S390_LAST_BREAK, 8, 00381 (gdbarch_ptr_bit (get_regcache_arch (regcache)) == 32 00382 ? s390_regmap_last_break : s390x_regmap_last_break)); 00383 00384 if (have_regset_system_call) 00385 if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM) 00386 fetch_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4, 00387 s390_regmap_system_call); 00388 00389 if (have_regset_tdb) 00390 if (regnum == -1 || S390_IS_TDBREGSET_REGNUM (regnum)) 00391 fetch_regset (regcache, tid, NT_S390_TDB, s390_sizeof_tdbregset, 00392 s390_regmap_tdb); 00393 } 00394 00395 /* Store register REGNUM back into the child process. If REGNUM is 00396 -1, do this for all registers. */ 00397 static void 00398 s390_linux_store_inferior_registers (struct target_ops *ops, 00399 struct regcache *regcache, int regnum) 00400 { 00401 int tid = s390_inferior_tid (); 00402 00403 if (regnum == -1 || S390_IS_GREGSET_REGNUM (regnum)) 00404 store_regs (regcache, tid, regnum); 00405 00406 if (regnum == -1 || S390_IS_FPREGSET_REGNUM (regnum)) 00407 store_fpregs (regcache, tid, regnum); 00408 00409 /* S390_LAST_BREAK_REGNUM is read-only. */ 00410 00411 if (have_regset_system_call) 00412 if (regnum == -1 || regnum == S390_SYSTEM_CALL_REGNUM) 00413 store_regset (regcache, tid, NT_S390_SYSTEM_CALL, 4, 00414 s390_regmap_system_call); 00415 } 00416 00417 00418 /* Hardware-assisted watchpoint handling. */ 00419 00420 /* We maintain a list of all currently active watchpoints in order 00421 to properly handle watchpoint removal. 00422 00423 The only thing we actually need is the total address space area 00424 spanned by the watchpoints. */ 00425 00426 struct watch_area 00427 { 00428 struct watch_area *next; 00429 CORE_ADDR lo_addr; 00430 CORE_ADDR hi_addr; 00431 }; 00432 00433 static struct watch_area *watch_base = NULL; 00434 00435 static int 00436 s390_stopped_by_watchpoint (void) 00437 { 00438 per_lowcore_bits per_lowcore; 00439 ptrace_area parea; 00440 int result; 00441 00442 /* Speed up common case. */ 00443 if (!watch_base) 00444 return 0; 00445 00446 parea.len = sizeof (per_lowcore); 00447 parea.process_addr = (addr_t) & per_lowcore; 00448 parea.kernel_addr = offsetof (struct user_regs_struct, per_info.lowcore); 00449 if (ptrace (PTRACE_PEEKUSR_AREA, s390_inferior_tid (), &parea) < 0) 00450 perror_with_name (_("Couldn't retrieve watchpoint status")); 00451 00452 result = (per_lowcore.perc_storage_alteration == 1 00453 && per_lowcore.perc_store_real_address == 0); 00454 00455 if (result) 00456 { 00457 /* Do not report this watchpoint again. */ 00458 memset (&per_lowcore, 0, sizeof (per_lowcore)); 00459 if (ptrace (PTRACE_POKEUSR_AREA, s390_inferior_tid (), &parea) < 0) 00460 perror_with_name (_("Couldn't clear watchpoint status")); 00461 } 00462 00463 return result; 00464 } 00465 00466 static void 00467 s390_fix_watch_points (struct lwp_info *lp) 00468 { 00469 int tid; 00470 00471 per_struct per_info; 00472 ptrace_area parea; 00473 00474 CORE_ADDR watch_lo_addr = (CORE_ADDR)-1, watch_hi_addr = 0; 00475 struct watch_area *area; 00476 00477 tid = ptid_get_lwp (lp->ptid); 00478 if (tid == 0) 00479 tid = ptid_get_pid (lp->ptid); 00480 00481 for (area = watch_base; area; area = area->next) 00482 { 00483 watch_lo_addr = min (watch_lo_addr, area->lo_addr); 00484 watch_hi_addr = max (watch_hi_addr, area->hi_addr); 00485 } 00486 00487 parea.len = sizeof (per_info); 00488 parea.process_addr = (addr_t) & per_info; 00489 parea.kernel_addr = offsetof (struct user_regs_struct, per_info); 00490 if (ptrace (PTRACE_PEEKUSR_AREA, tid, &parea) < 0) 00491 perror_with_name (_("Couldn't retrieve watchpoint status")); 00492 00493 if (watch_base) 00494 { 00495 per_info.control_regs.bits.em_storage_alteration = 1; 00496 per_info.control_regs.bits.storage_alt_space_ctl = 1; 00497 } 00498 else 00499 { 00500 per_info.control_regs.bits.em_storage_alteration = 0; 00501 per_info.control_regs.bits.storage_alt_space_ctl = 0; 00502 } 00503 per_info.starting_addr = watch_lo_addr; 00504 per_info.ending_addr = watch_hi_addr; 00505 00506 if (ptrace (PTRACE_POKEUSR_AREA, tid, &parea) < 0) 00507 perror_with_name (_("Couldn't modify watchpoint status")); 00508 } 00509 00510 static int 00511 s390_insert_watchpoint (CORE_ADDR addr, int len, int type, 00512 struct expression *cond) 00513 { 00514 struct lwp_info *lp; 00515 struct watch_area *area = xmalloc (sizeof (struct watch_area)); 00516 00517 if (!area) 00518 return -1; 00519 00520 area->lo_addr = addr; 00521 area->hi_addr = addr + len - 1; 00522 00523 area->next = watch_base; 00524 watch_base = area; 00525 00526 ALL_LWPS (lp) 00527 s390_fix_watch_points (lp); 00528 return 0; 00529 } 00530 00531 static int 00532 s390_remove_watchpoint (CORE_ADDR addr, int len, int type, 00533 struct expression *cond) 00534 { 00535 struct lwp_info *lp; 00536 struct watch_area *area, **parea; 00537 00538 for (parea = &watch_base; *parea; parea = &(*parea)->next) 00539 if ((*parea)->lo_addr == addr 00540 && (*parea)->hi_addr == addr + len - 1) 00541 break; 00542 00543 if (!*parea) 00544 { 00545 fprintf_unfiltered (gdb_stderr, 00546 "Attempt to remove nonexistent watchpoint.\n"); 00547 return -1; 00548 } 00549 00550 area = *parea; 00551 *parea = area->next; 00552 xfree (area); 00553 00554 ALL_LWPS (lp) 00555 s390_fix_watch_points (lp); 00556 return 0; 00557 } 00558 00559 static int 00560 s390_can_use_hw_breakpoint (int type, int cnt, int othertype) 00561 { 00562 return type == bp_hardware_watchpoint; 00563 } 00564 00565 static int 00566 s390_region_ok_for_hw_watchpoint (CORE_ADDR addr, int cnt) 00567 { 00568 return 1; 00569 } 00570 00571 static int 00572 s390_target_wordsize (void) 00573 { 00574 int wordsize = 4; 00575 00576 /* Check for 64-bit inferior process. This is the case when the host is 00577 64-bit, and in addition bit 32 of the PSW mask is set. */ 00578 #ifdef __s390x__ 00579 long pswm; 00580 00581 errno = 0; 00582 pswm = (long) ptrace (PTRACE_PEEKUSER, s390_inferior_tid (), PT_PSWMASK, 0); 00583 if (errno == 0 && (pswm & 0x100000000ul) != 0) 00584 wordsize = 8; 00585 #endif 00586 00587 return wordsize; 00588 } 00589 00590 static int 00591 s390_auxv_parse (struct target_ops *ops, gdb_byte **readptr, 00592 gdb_byte *endptr, CORE_ADDR *typep, CORE_ADDR *valp) 00593 { 00594 int sizeof_auxv_field = s390_target_wordsize (); 00595 enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ()); 00596 gdb_byte *ptr = *readptr; 00597 00598 if (endptr == ptr) 00599 return 0; 00600 00601 if (endptr - ptr < sizeof_auxv_field * 2) 00602 return -1; 00603 00604 *typep = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); 00605 ptr += sizeof_auxv_field; 00606 *valp = extract_unsigned_integer (ptr, sizeof_auxv_field, byte_order); 00607 ptr += sizeof_auxv_field; 00608 00609 *readptr = ptr; 00610 return 1; 00611 } 00612 00613 #ifdef __s390x__ 00614 static unsigned long 00615 s390_get_hwcap (void) 00616 { 00617 CORE_ADDR field; 00618 00619 if (target_auxv_search (¤t_target, AT_HWCAP, &field)) 00620 return (unsigned long) field; 00621 00622 return 0; 00623 } 00624 #endif 00625 00626 static const struct target_desc * 00627 s390_read_description (struct target_ops *ops) 00628 { 00629 int tid = s390_inferior_tid (); 00630 00631 have_regset_last_break 00632 = check_regset (tid, NT_S390_LAST_BREAK, 8); 00633 have_regset_system_call 00634 = check_regset (tid, NT_S390_SYSTEM_CALL, 4); 00635 have_regset_tdb 00636 = check_regset (tid, NT_S390_TDB, s390_sizeof_tdbregset); 00637 00638 #ifdef __s390x__ 00639 /* If GDB itself is compiled as 64-bit, we are running on a machine in 00640 z/Architecture mode. If the target is running in 64-bit addressing 00641 mode, report s390x architecture. If the target is running in 31-bit 00642 addressing mode, but the kernel supports using 64-bit registers in 00643 that mode, report s390 architecture with 64-bit GPRs. */ 00644 00645 if (s390_target_wordsize () == 8) 00646 return (have_regset_tdb ? tdesc_s390x_te_linux64 : 00647 have_regset_system_call? tdesc_s390x_linux64v2 : 00648 have_regset_last_break? tdesc_s390x_linux64v1 : 00649 tdesc_s390x_linux64); 00650 00651 if (s390_get_hwcap () & HWCAP_S390_HIGH_GPRS) 00652 return (have_regset_tdb ? tdesc_s390_te_linux64 : 00653 have_regset_system_call? tdesc_s390_linux64v2 : 00654 have_regset_last_break? tdesc_s390_linux64v1 : 00655 tdesc_s390_linux64); 00656 #endif 00657 00658 /* If GDB itself is compiled as 31-bit, or if we're running a 31-bit inferior 00659 on a 64-bit kernel that does not support using 64-bit registers in 31-bit 00660 mode, report s390 architecture with 32-bit GPRs. */ 00661 return (have_regset_system_call? tdesc_s390_linux32v2 : 00662 have_regset_last_break? tdesc_s390_linux32v1 : 00663 tdesc_s390_linux32); 00664 } 00665 00666 void _initialize_s390_nat (void); 00667 00668 void 00669 _initialize_s390_nat (void) 00670 { 00671 struct target_ops *t; 00672 00673 /* Fill in the generic GNU/Linux methods. */ 00674 t = linux_target (); 00675 00676 /* Add our register access methods. */ 00677 t->to_fetch_registers = s390_linux_fetch_inferior_registers; 00678 t->to_store_registers = s390_linux_store_inferior_registers; 00679 00680 /* Add our watchpoint methods. */ 00681 t->to_can_use_hw_breakpoint = s390_can_use_hw_breakpoint; 00682 t->to_region_ok_for_hw_watchpoint = s390_region_ok_for_hw_watchpoint; 00683 t->to_have_continuable_watchpoint = 1; 00684 t->to_stopped_by_watchpoint = s390_stopped_by_watchpoint; 00685 t->to_insert_watchpoint = s390_insert_watchpoint; 00686 t->to_remove_watchpoint = s390_remove_watchpoint; 00687 00688 /* Detect target architecture. */ 00689 t->to_read_description = s390_read_description; 00690 t->to_auxv_parse = s390_auxv_parse; 00691 00692 /* Register the target. */ 00693 linux_nat_add_target (t); 00694 linux_nat_set_new_thread (t, s390_fix_watch_points); 00695 }