GDB (API)
|
00001 /* Motorola m68k native support for GNU/Linux. 00002 00003 Copyright (C) 1996-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 #include "defs.h" 00021 #include "frame.h" 00022 #include "inferior.h" 00023 #include "language.h" 00024 #include "gdbcore.h" 00025 #include "gdb_string.h" 00026 #include "regcache.h" 00027 #include "target.h" 00028 #include "linux-nat.h" 00029 00030 #include "m68k-tdep.h" 00031 00032 #include <sys/dir.h> 00033 #include <signal.h> 00034 #include <sys/ptrace.h> 00035 #include <sys/user.h> 00036 #include <sys/ioctl.h> 00037 #include <fcntl.h> 00038 #include <sys/procfs.h> 00039 00040 #ifdef HAVE_SYS_REG_H 00041 #include <sys/reg.h> 00042 #endif 00043 00044 #include <sys/file.h> 00045 #include "gdb_stat.h" 00046 00047 #include "floatformat.h" 00048 00049 #include "target.h" 00050 00051 /* Prototypes for supply_gregset etc. */ 00052 #include "gregset.h" 00053 00054 /* Defines ps_err_e, struct ps_prochandle. */ 00055 #include "gdb_proc_service.h" 00056 00057 #ifndef PTRACE_GET_THREAD_AREA 00058 #define PTRACE_GET_THREAD_AREA 25 00059 #endif 00060 00061 /* This table must line up with gdbarch_register_name in "m68k-tdep.c". */ 00062 static const int regmap[] = 00063 { 00064 PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7, 00065 PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP, 00066 PT_SR, PT_PC, 00067 /* PT_FP0, ..., PT_FP7 */ 00068 21, 24, 27, 30, 33, 36, 39, 42, 00069 /* PT_FPCR, PT_FPSR, PT_FPIAR */ 00070 45, 46, 47 00071 }; 00072 00073 /* Which ptrace request retrieves which registers? 00074 These apply to the corresponding SET requests as well. */ 00075 #define NUM_GREGS (18) 00076 #define MAX_NUM_REGS (NUM_GREGS + 11) 00077 00078 static int 00079 getregs_supplies (int regno) 00080 { 00081 return 0 <= regno && regno < NUM_GREGS; 00082 } 00083 00084 static int 00085 getfpregs_supplies (int regno) 00086 { 00087 return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM; 00088 } 00089 00090 /* Does the current host support the GETREGS request? */ 00091 static int have_ptrace_getregs = 00092 #ifdef HAVE_PTRACE_GETREGS 00093 1 00094 #else 00095 0 00096 #endif 00097 ; 00098 00099 00100 00101 /* Fetching registers directly from the U area, one at a time. */ 00102 00103 /* Fetch one register. */ 00104 00105 static void 00106 fetch_register (struct regcache *regcache, int regno) 00107 { 00108 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00109 long regaddr, val; 00110 int i; 00111 gdb_byte buf[MAX_REGISTER_SIZE]; 00112 int tid; 00113 00114 /* Overload thread id onto process id. */ 00115 tid = ptid_get_lwp (inferior_ptid); 00116 if (tid == 0) 00117 tid = ptid_get_pid (inferior_ptid); /* no thread id, just use 00118 process id. */ 00119 00120 regaddr = 4 * regmap[regno]; 00121 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long)) 00122 { 00123 errno = 0; 00124 val = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0); 00125 memcpy (&buf[i], &val, sizeof (long)); 00126 regaddr += sizeof (long); 00127 if (errno != 0) 00128 error (_("Couldn't read register %s (#%d): %s."), 00129 gdbarch_register_name (gdbarch, regno), 00130 regno, safe_strerror (errno)); 00131 } 00132 regcache_raw_supply (regcache, regno, buf); 00133 } 00134 00135 /* Fetch register values from the inferior. 00136 If REGNO is negative, do this for all registers. 00137 Otherwise, REGNO specifies which register (so we can save time). */ 00138 00139 static void 00140 old_fetch_inferior_registers (struct regcache *regcache, int regno) 00141 { 00142 if (regno >= 0) 00143 { 00144 fetch_register (regcache, regno); 00145 } 00146 else 00147 { 00148 for (regno = 0; 00149 regno < gdbarch_num_regs (get_regcache_arch (regcache)); 00150 regno++) 00151 { 00152 fetch_register (regcache, regno); 00153 } 00154 } 00155 } 00156 00157 /* Store one register. */ 00158 00159 static void 00160 store_register (const struct regcache *regcache, int regno) 00161 { 00162 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00163 long regaddr, val; 00164 int i; 00165 int tid; 00166 gdb_byte buf[MAX_REGISTER_SIZE]; 00167 00168 /* Overload thread id onto process id. */ 00169 tid = ptid_get_lwp (inferior_ptid); 00170 if (tid == 0) 00171 tid = ptid_get_pid (inferior_ptid); /* no thread id, just use 00172 process id. */ 00173 00174 regaddr = 4 * regmap[regno]; 00175 00176 /* Put the contents of regno into a local buffer. */ 00177 regcache_raw_collect (regcache, regno, buf); 00178 00179 /* Store the local buffer into the inferior a chunk at the time. */ 00180 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long)) 00181 { 00182 errno = 0; 00183 memcpy (&val, &buf[i], sizeof (long)); 00184 ptrace (PTRACE_POKEUSER, tid, regaddr, val); 00185 regaddr += sizeof (long); 00186 if (errno != 0) 00187 error (_("Couldn't write register %s (#%d): %s."), 00188 gdbarch_register_name (gdbarch, regno), 00189 regno, safe_strerror (errno)); 00190 } 00191 } 00192 00193 /* Store our register values back into the inferior. 00194 If REGNO is negative, do this for all registers. 00195 Otherwise, REGNO specifies which register (so we can save time). */ 00196 00197 static void 00198 old_store_inferior_registers (const struct regcache *regcache, int regno) 00199 { 00200 if (regno >= 0) 00201 { 00202 store_register (regcache, regno); 00203 } 00204 else 00205 { 00206 for (regno = 0; 00207 regno < gdbarch_num_regs (get_regcache_arch (regcache)); 00208 regno++) 00209 { 00210 store_register (regcache, regno); 00211 } 00212 } 00213 } 00214 00215 /* Given a pointer to a general register set in /proc format 00216 (elf_gregset_t *), unpack the register contents and supply 00217 them as gdb's idea of the current register values. */ 00218 00219 void 00220 supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp) 00221 { 00222 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00223 const elf_greg_t *regp = (const elf_greg_t *) gregsetp; 00224 int regi; 00225 00226 for (regi = M68K_D0_REGNUM; 00227 regi <= gdbarch_sp_regnum (gdbarch); 00228 regi++) 00229 regcache_raw_supply (regcache, regi, ®p[regmap[regi]]); 00230 regcache_raw_supply (regcache, gdbarch_ps_regnum (gdbarch), 00231 ®p[PT_SR]); 00232 regcache_raw_supply (regcache, 00233 gdbarch_pc_regnum (gdbarch), ®p[PT_PC]); 00234 } 00235 00236 /* Fill register REGNO (if it is a general-purpose register) in 00237 *GREGSETPS with the value in GDB's register array. If REGNO is -1, 00238 do this for all registers. */ 00239 void 00240 fill_gregset (const struct regcache *regcache, 00241 elf_gregset_t *gregsetp, int regno) 00242 { 00243 elf_greg_t *regp = (elf_greg_t *) gregsetp; 00244 int i; 00245 00246 for (i = 0; i < NUM_GREGS; i++) 00247 if (regno == -1 || regno == i) 00248 regcache_raw_collect (regcache, i, regp + regmap[i]); 00249 } 00250 00251 #ifdef HAVE_PTRACE_GETREGS 00252 00253 /* Fetch all general-purpose registers from process/thread TID and 00254 store their values in GDB's register array. */ 00255 00256 static void 00257 fetch_regs (struct regcache *regcache, int tid) 00258 { 00259 elf_gregset_t regs; 00260 00261 if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0) 00262 { 00263 if (errno == EIO) 00264 { 00265 /* The kernel we're running on doesn't support the GETREGS 00266 request. Reset `have_ptrace_getregs'. */ 00267 have_ptrace_getregs = 0; 00268 return; 00269 } 00270 00271 perror_with_name (_("Couldn't get registers")); 00272 } 00273 00274 supply_gregset (regcache, (const elf_gregset_t *) ®s); 00275 } 00276 00277 /* Store all valid general-purpose registers in GDB's register array 00278 into the process/thread specified by TID. */ 00279 00280 static void 00281 store_regs (const struct regcache *regcache, int tid, int regno) 00282 { 00283 elf_gregset_t regs; 00284 00285 if (ptrace (PTRACE_GETREGS, tid, 0, (int) ®s) < 0) 00286 perror_with_name (_("Couldn't get registers")); 00287 00288 fill_gregset (regcache, ®s, regno); 00289 00290 if (ptrace (PTRACE_SETREGS, tid, 0, (int) ®s) < 0) 00291 perror_with_name (_("Couldn't write registers")); 00292 } 00293 00294 #else 00295 00296 static void fetch_regs (struct regcache *regcache, int tid) 00297 { 00298 } 00299 00300 static void store_regs (const struct regcache *regcache, int tid, int regno) 00301 { 00302 } 00303 00304 #endif 00305 00306 00307 /* Transfering floating-point registers between GDB, inferiors and cores. */ 00308 00309 /* What is the address of fpN within the floating-point register set F? */ 00310 #define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3]) 00311 00312 /* Fill GDB's register array with the floating-point register values in 00313 *FPREGSETP. */ 00314 00315 void 00316 supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp) 00317 { 00318 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00319 int regi; 00320 00321 for (regi = gdbarch_fp0_regnum (gdbarch); 00322 regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++) 00323 regcache_raw_supply (regcache, regi, 00324 FPREG_ADDR (fpregsetp, 00325 regi - gdbarch_fp0_regnum (gdbarch))); 00326 regcache_raw_supply (regcache, M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]); 00327 regcache_raw_supply (regcache, M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]); 00328 regcache_raw_supply (regcache, M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]); 00329 } 00330 00331 /* Fill register REGNO (if it is a floating-point register) in 00332 *FPREGSETP with the value in GDB's register array. If REGNO is -1, 00333 do this for all registers. */ 00334 00335 void 00336 fill_fpregset (const struct regcache *regcache, 00337 elf_fpregset_t *fpregsetp, int regno) 00338 { 00339 struct gdbarch *gdbarch = get_regcache_arch (regcache); 00340 int i; 00341 00342 /* Fill in the floating-point registers. */ 00343 for (i = gdbarch_fp0_regnum (gdbarch); 00344 i < gdbarch_fp0_regnum (gdbarch) + 8; i++) 00345 if (regno == -1 || regno == i) 00346 regcache_raw_collect (regcache, i, 00347 FPREG_ADDR (fpregsetp, 00348 i - gdbarch_fp0_regnum (gdbarch))); 00349 00350 /* Fill in the floating-point control registers. */ 00351 for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++) 00352 if (regno == -1 || regno == i) 00353 regcache_raw_collect (regcache, i, 00354 &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]); 00355 } 00356 00357 #ifdef HAVE_PTRACE_GETREGS 00358 00359 /* Fetch all floating-point registers from process/thread TID and store 00360 thier values in GDB's register array. */ 00361 00362 static void 00363 fetch_fpregs (struct regcache *regcache, int tid) 00364 { 00365 elf_fpregset_t fpregs; 00366 00367 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0) 00368 perror_with_name (_("Couldn't get floating point status")); 00369 00370 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs); 00371 } 00372 00373 /* Store all valid floating-point registers in GDB's register array 00374 into the process/thread specified by TID. */ 00375 00376 static void 00377 store_fpregs (const struct regcache *regcache, int tid, int regno) 00378 { 00379 elf_fpregset_t fpregs; 00380 00381 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0) 00382 perror_with_name (_("Couldn't get floating point status")); 00383 00384 fill_fpregset (regcache, &fpregs, regno); 00385 00386 if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0) 00387 perror_with_name (_("Couldn't write floating point status")); 00388 } 00389 00390 #else 00391 00392 static void fetch_fpregs (struct regcache *regcache, int tid) 00393 { 00394 } 00395 00396 static void store_fpregs (const struct regcache *regcache, int tid, int regno) 00397 { 00398 } 00399 00400 #endif 00401 00402 /* Transferring arbitrary registers between GDB and inferior. */ 00403 00404 /* Fetch register REGNO from the child process. If REGNO is -1, do 00405 this for all registers (including the floating point and SSE 00406 registers). */ 00407 00408 static void 00409 m68k_linux_fetch_inferior_registers (struct target_ops *ops, 00410 struct regcache *regcache, int regno) 00411 { 00412 int tid; 00413 00414 /* Use the old method of peeking around in `struct user' if the 00415 GETREGS request isn't available. */ 00416 if (! have_ptrace_getregs) 00417 { 00418 old_fetch_inferior_registers (regcache, regno); 00419 return; 00420 } 00421 00422 /* GNU/Linux LWP ID's are process ID's. */ 00423 tid = ptid_get_lwp (inferior_ptid); 00424 if (tid == 0) 00425 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ 00426 00427 /* Use the PTRACE_GETFPXREGS request whenever possible, since it 00428 transfers more registers in one system call, and we'll cache the 00429 results. But remember that fetch_fpxregs can fail, and return 00430 zero. */ 00431 if (regno == -1) 00432 { 00433 fetch_regs (regcache, tid); 00434 00435 /* The call above might reset `have_ptrace_getregs'. */ 00436 if (! have_ptrace_getregs) 00437 { 00438 old_fetch_inferior_registers (regcache, -1); 00439 return; 00440 } 00441 00442 fetch_fpregs (regcache, tid); 00443 return; 00444 } 00445 00446 if (getregs_supplies (regno)) 00447 { 00448 fetch_regs (regcache, tid); 00449 return; 00450 } 00451 00452 if (getfpregs_supplies (regno)) 00453 { 00454 fetch_fpregs (regcache, tid); 00455 return; 00456 } 00457 00458 internal_error (__FILE__, __LINE__, 00459 _("Got request for bad register number %d."), regno); 00460 } 00461 00462 /* Store register REGNO back into the child process. If REGNO is -1, 00463 do this for all registers (including the floating point and SSE 00464 registers). */ 00465 static void 00466 m68k_linux_store_inferior_registers (struct target_ops *ops, 00467 struct regcache *regcache, int regno) 00468 { 00469 int tid; 00470 00471 /* Use the old method of poking around in `struct user' if the 00472 SETREGS request isn't available. */ 00473 if (! have_ptrace_getregs) 00474 { 00475 old_store_inferior_registers (regcache, regno); 00476 return; 00477 } 00478 00479 /* GNU/Linux LWP ID's are process ID's. */ 00480 tid = ptid_get_lwp (inferior_ptid); 00481 if (tid == 0) 00482 tid = ptid_get_pid (inferior_ptid); /* Not a threaded program. */ 00483 00484 /* Use the PTRACE_SETFPREGS requests whenever possible, since it 00485 transfers more registers in one system call. But remember that 00486 store_fpregs can fail, and return zero. */ 00487 if (regno == -1) 00488 { 00489 store_regs (regcache, tid, regno); 00490 store_fpregs (regcache, tid, regno); 00491 return; 00492 } 00493 00494 if (getregs_supplies (regno)) 00495 { 00496 store_regs (regcache, tid, regno); 00497 return; 00498 } 00499 00500 if (getfpregs_supplies (regno)) 00501 { 00502 store_fpregs (regcache, tid, regno); 00503 return; 00504 } 00505 00506 internal_error (__FILE__, __LINE__, 00507 _("Got request to store bad register number %d."), regno); 00508 } 00509 00510 /* Interpreting register set info found in core files. */ 00511 00512 /* Provide registers to GDB from a core file. 00513 00514 (We can't use the generic version of this function in 00515 core-regset.c, because we need to use elf_gregset_t instead of 00516 gregset_t.) 00517 00518 CORE_REG_SECT points to an array of bytes, which are the contents 00519 of a `note' from a core file which BFD thinks might contain 00520 register contents. CORE_REG_SIZE is its size. 00521 00522 WHICH says which register set corelow suspects this is: 00523 0 --- the general-purpose register set, in elf_gregset_t format 00524 2 --- the floating-point register set, in elf_fpregset_t format 00525 00526 REG_ADDR isn't used on GNU/Linux. */ 00527 00528 static void 00529 fetch_core_registers (struct regcache *regcache, 00530 char *core_reg_sect, unsigned core_reg_size, 00531 int which, CORE_ADDR reg_addr) 00532 { 00533 elf_gregset_t gregset; 00534 elf_fpregset_t fpregset; 00535 00536 switch (which) 00537 { 00538 case 0: 00539 if (core_reg_size != sizeof (gregset)) 00540 warning (_("Wrong size gregset in core file.")); 00541 else 00542 { 00543 memcpy (&gregset, core_reg_sect, sizeof (gregset)); 00544 supply_gregset (regcache, (const elf_gregset_t *) &gregset); 00545 } 00546 break; 00547 00548 case 2: 00549 if (core_reg_size != sizeof (fpregset)) 00550 warning (_("Wrong size fpregset in core file.")); 00551 else 00552 { 00553 memcpy (&fpregset, core_reg_sect, sizeof (fpregset)); 00554 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregset); 00555 } 00556 break; 00557 00558 default: 00559 /* We've covered all the kinds of registers we know about here, 00560 so this must be something we wouldn't know what to do with 00561 anyway. Just ignore it. */ 00562 break; 00563 } 00564 } 00565 00566 00567 /* Fetch the thread-local storage pointer for libthread_db. */ 00568 00569 ps_err_e 00570 ps_get_thread_area (const struct ps_prochandle *ph, 00571 lwpid_t lwpid, int idx, void **base) 00572 { 00573 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0) 00574 return PS_ERR; 00575 00576 /* IDX is the bias from the thread pointer to the beginning of the 00577 thread descriptor. It has to be subtracted due to implementation 00578 quirks in libthread_db. */ 00579 *base = (char *) *base - idx; 00580 00581 return PS_OK; 00582 } 00583 00584 00585 /* Register that we are able to handle GNU/Linux ELF core file 00586 formats. */ 00587 00588 static struct core_fns linux_elf_core_fns = 00589 { 00590 bfd_target_elf_flavour, /* core_flavour */ 00591 default_check_format, /* check_format */ 00592 default_core_sniffer, /* core_sniffer */ 00593 fetch_core_registers, /* core_read_registers */ 00594 NULL /* next */ 00595 }; 00596 00597 void _initialize_m68k_linux_nat (void); 00598 00599 void 00600 _initialize_m68k_linux_nat (void) 00601 { 00602 struct target_ops *t; 00603 00604 /* Fill in the generic GNU/Linux methods. */ 00605 t = linux_target (); 00606 00607 /* Add our register access methods. */ 00608 t->to_fetch_registers = m68k_linux_fetch_inferior_registers; 00609 t->to_store_registers = m68k_linux_store_inferior_registers; 00610 00611 /* Register the target. */ 00612 linux_nat_add_target (t); 00613 00614 deprecated_add_core_fns (&linux_elf_core_fns); 00615 }