| OLD | NEW |
| 1 /* PPC GNU/Linux native support. | 1 /* PPC GNU/Linux native support. |
| 2 | 2 |
| 3 Copyright (C) 1988-1989, 1991-1992, 1994, 1996, 2000-2012 Free | 3 Copyright (C) 1988-1989, 1991-1992, 1994, 1996, 2000-2012 Free |
| 4 Software Foundation, Inc. | 4 Software Foundation, Inc. |
| 5 | 5 |
| 6 This file is part of GDB. | 6 This file is part of GDB. |
| 7 | 7 |
| 8 This program is free software; you can redistribute it and/or modify | 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 | 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 | 10 the Free Software Foundation; either version 3 of the License, or |
| (...skipping 575 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 return; | 586 return; |
| 587 } | 587 } |
| 588 | 588 |
| 589 /* Read the raw register using sizeof(long) sized chunks. On a | 589 /* Read the raw register using sizeof(long) sized chunks. On a |
| 590 32-bit platform, 64-bit floating-point registers will require two | 590 32-bit platform, 64-bit floating-point registers will require two |
| 591 transfers. */ | 591 transfers. */ |
| 592 for (bytes_transferred = 0; | 592 for (bytes_transferred = 0; |
| 593 bytes_transferred < register_size (gdbarch, regno); | 593 bytes_transferred < register_size (gdbarch, regno); |
| 594 bytes_transferred += sizeof (long)) | 594 bytes_transferred += sizeof (long)) |
| 595 { | 595 { |
| 596 long l; |
| 597 |
| 596 errno = 0; | 598 errno = 0; |
| 597 *(long *) &buf[bytes_transferred] | 599 l = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0); |
| 598 = ptrace (PTRACE_PEEKUSER, tid, (PTRACE_TYPE_ARG3) regaddr, 0); | |
| 599 regaddr += sizeof (long); | 600 regaddr += sizeof (long); |
| 600 if (errno != 0) | 601 if (errno != 0) |
| 601 { | 602 { |
| 602 char message[128]; | 603 char message[128]; |
| 603 sprintf (message, "reading register %s (#%d)", | 604 sprintf (message, "reading register %s (#%d)", |
| 604 gdbarch_register_name (gdbarch, regno), regno); | 605 gdbarch_register_name (gdbarch, regno), regno); |
| 605 perror_with_name (message); | 606 perror_with_name (message); |
| 606 } | 607 } |
| 608 memcpy (&buf[bytes_transferred], &l, sizeof (l)); |
| 607 } | 609 } |
| 608 | 610 |
| 609 /* Now supply the register. Keep in mind that the regcache's idea | 611 /* Now supply the register. Keep in mind that the regcache's idea |
| 610 of the register's size may not be a multiple of sizeof | 612 of the register's size may not be a multiple of sizeof |
| 611 (long). */ | 613 (long). */ |
| 612 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) | 614 if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_LITTLE) |
| 613 { | 615 { |
| 614 /* Little-endian values are always found at the left end of the | 616 /* Little-endian values are always found at the left end of the |
| 615 bytes transferred. */ | 617 bytes transferred. */ |
| 616 regcache_raw_supply (regcache, regno, buf); | 618 regcache_raw_supply (regcache, regno, buf); |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1066 } | 1068 } |
| 1067 else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) | 1069 else if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG) |
| 1068 { | 1070 { |
| 1069 /* Big-endian values sit at the right end of the buffer. */ | 1071 /* Big-endian values sit at the right end of the buffer. */ |
| 1070 size_t padding = (bytes_to_transfer - register_size (gdbarch, regno)); | 1072 size_t padding = (bytes_to_transfer - register_size (gdbarch, regno)); |
| 1071 regcache_raw_collect (regcache, regno, buf + padding); | 1073 regcache_raw_collect (regcache, regno, buf + padding); |
| 1072 } | 1074 } |
| 1073 | 1075 |
| 1074 for (i = 0; i < bytes_to_transfer; i += sizeof (long)) | 1076 for (i = 0; i < bytes_to_transfer; i += sizeof (long)) |
| 1075 { | 1077 { |
| 1078 long l; |
| 1079 |
| 1080 memcpy (&l, &buf[i], sizeof (l)); |
| 1076 errno = 0; | 1081 errno = 0; |
| 1077 ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, | 1082 ptrace (PTRACE_POKEUSER, tid, (PTRACE_TYPE_ARG3) regaddr, l); |
| 1078 » *(long *) &buf[i]); | |
| 1079 regaddr += sizeof (long); | 1083 regaddr += sizeof (long); |
| 1080 | 1084 |
| 1081 if (errno == EIO | 1085 if (errno == EIO |
| 1082 && (regno == tdep->ppc_fpscr_regnum | 1086 && (regno == tdep->ppc_fpscr_regnum |
| 1083 || regno == PPC_ORIG_R3_REGNUM | 1087 || regno == PPC_ORIG_R3_REGNUM |
| 1084 || regno == PPC_TRAP_REGNUM)) | 1088 || regno == PPC_TRAP_REGNUM)) |
| 1085 { | 1089 { |
| 1086 /* Some older kernel versions don't allow fpscr, orig_r3 | 1090 /* Some older kernel versions don't allow fpscr, orig_r3 |
| 1087 or trap to be written. */ | 1091 or trap to be written. */ |
| 1088 continue; | 1092 continue; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1340 if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) | 1344 if (tdep->ppc_vr0_regnum != -1 && tdep->ppc_vrsave_regnum != -1) |
| 1341 store_altivec_registers (regcache, tid); | 1345 store_altivec_registers (regcache, tid); |
| 1342 if (have_ptrace_getsetvsxregs) | 1346 if (have_ptrace_getsetvsxregs) |
| 1343 if (tdep->ppc_vsr0_upper_regnum != -1) | 1347 if (tdep->ppc_vsr0_upper_regnum != -1) |
| 1344 store_vsx_registers (regcache, tid); | 1348 store_vsx_registers (regcache, tid); |
| 1345 if (tdep->ppc_ev0_upper_regnum >= 0) | 1349 if (tdep->ppc_ev0_upper_regnum >= 0) |
| 1346 store_spe_register (regcache, tid, -1); | 1350 store_spe_register (regcache, tid, -1); |
| 1347 } | 1351 } |
| 1348 | 1352 |
| 1349 /* Fetch the AT_HWCAP entry from the aux vector. */ | 1353 /* Fetch the AT_HWCAP entry from the aux vector. */ |
| 1350 unsigned long ppc_linux_get_hwcap (void) | 1354 static unsigned long |
| 1355 ppc_linux_get_hwcap (void) |
| 1351 { | 1356 { |
| 1352 CORE_ADDR field; | 1357 CORE_ADDR field; |
| 1353 | 1358 |
| 1354 if (target_auxv_search (¤t_target, AT_HWCAP, &field)) | 1359 if (target_auxv_search (¤t_target, AT_HWCAP, &field)) |
| 1355 return (unsigned long) field; | 1360 return (unsigned long) field; |
| 1356 | 1361 |
| 1357 return 0; | 1362 return 0; |
| 1358 } | 1363 } |
| 1359 | 1364 |
| 1360 /* The cached DABR value, to install in new threads. | 1365 /* The cached DABR value, to install in new threads. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1409 { | 1414 { |
| 1410 int tid; | 1415 int tid; |
| 1411 | 1416 |
| 1412 tid = TIDGET (inferior_ptid); | 1417 tid = TIDGET (inferior_ptid); |
| 1413 if (tid == 0) | 1418 if (tid == 0) |
| 1414 tid = PIDGET (inferior_ptid); | 1419 tid = PIDGET (inferior_ptid); |
| 1415 | 1420 |
| 1416 /* Check for kernel support for BOOKE debug registers. */ | 1421 /* Check for kernel support for BOOKE debug registers. */ |
| 1417 if (ptrace (PPC_PTRACE_GETHWDBGINFO, tid, 0, &booke_debug_info) >= 0) | 1422 if (ptrace (PPC_PTRACE_GETHWDBGINFO, tid, 0, &booke_debug_info) >= 0) |
| 1418 { | 1423 { |
| 1419 » have_ptrace_booke_interface = 1; | 1424 » /* Check whether ptrace BOOKE interface is functional and |
| 1420 » max_slots_number = booke_debug_info.num_instruction_bps | 1425 » provides any supported feature. */ |
| 1421 » + booke_debug_info.num_data_bps | 1426 » if (booke_debug_info.features != 0) |
| 1422 » + booke_debug_info.num_condition_regs; | 1427 » { |
| 1428 » have_ptrace_booke_interface = 1; |
| 1429 » max_slots_number = booke_debug_info.num_instruction_bps |
| 1430 » + booke_debug_info.num_data_bps |
| 1431 » + booke_debug_info.num_condition_regs; |
| 1432 » return have_ptrace_booke_interface; |
| 1433 » } |
| 1423 } | 1434 } |
| 1424 else | 1435 /* Old school interface and no BOOKE debug registers support. */ |
| 1425 » { | 1436 have_ptrace_booke_interface = 0; |
| 1426 » /* Old school interface and no BOOKE debug registers support. */ | 1437 memset (&booke_debug_info, 0, sizeof (struct ppc_debug_info)); |
| 1427 » have_ptrace_booke_interface = 0; | |
| 1428 » memset (&booke_debug_info, 0, sizeof (struct ppc_debug_info)); | |
| 1429 » } | |
| 1430 } | 1438 } |
| 1431 | 1439 |
| 1432 return have_ptrace_booke_interface; | 1440 return have_ptrace_booke_interface; |
| 1433 } | 1441 } |
| 1434 | 1442 |
| 1435 static int | 1443 static int |
| 1436 ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot) | 1444 ppc_linux_can_use_hw_breakpoint (int type, int cnt, int ot) |
| 1437 { | 1445 { |
| 1438 int total_hw_wp, total_hw_bp; | 1446 int total_hw_wp, total_hw_bp; |
| 1439 | 1447 |
| 1440 if (have_ptrace_booke_interface ()) | 1448 if (have_ptrace_booke_interface ()) |
| 1441 { | 1449 { |
| 1442 /* For PPC BookE processors, the number of available hardware | 1450 /* For PPC BookE processors, the number of available hardware |
| 1443 watchpoints and breakpoints is stored at the booke_debug_info | 1451 watchpoints and breakpoints is stored at the booke_debug_info |
| 1444 struct. */ | 1452 struct. */ |
| 1445 total_hw_bp = booke_debug_info.num_instruction_bps; | 1453 total_hw_bp = booke_debug_info.num_instruction_bps; |
| 1446 total_hw_wp = booke_debug_info.num_data_bps; | 1454 total_hw_wp = booke_debug_info.num_data_bps; |
| 1447 } | 1455 } |
| 1448 else | 1456 else |
| 1449 { | 1457 { |
| 1450 /* For PPC server processors, we accept 1 hardware watchpoint and 0 | 1458 /* For PPC server processors, we accept 1 hardware watchpoint and 0 |
| 1451 hardware breakpoints. */ | 1459 hardware breakpoints. */ |
| 1452 total_hw_bp = 0; | 1460 total_hw_bp = 0; |
| 1453 total_hw_wp = 1; | 1461 total_hw_wp = 1; |
| 1454 } | 1462 } |
| 1455 | 1463 |
| 1456 if (type == bp_hardware_watchpoint || type == bp_read_watchpoint | 1464 if (type == bp_hardware_watchpoint || type == bp_read_watchpoint |
| 1457 || type == bp_access_watchpoint || type == bp_watchpoint) | 1465 || type == bp_access_watchpoint || type == bp_watchpoint) |
| 1458 { | 1466 { |
| 1459 if (cnt > total_hw_wp) | 1467 if (cnt + ot > total_hw_wp) |
| 1460 return -1; | 1468 return -1; |
| 1461 } | 1469 } |
| 1462 else if (type == bp_hardware_breakpoint) | 1470 else if (type == bp_hardware_breakpoint) |
| 1463 { | 1471 { |
| 1464 if (cnt > total_hw_bp) | 1472 if (cnt > total_hw_bp) |
| 1465 return -1; | 1473 return -1; |
| 1466 } | 1474 } |
| 1467 | 1475 |
| 1468 if (!have_ptrace_booke_interface ()) | 1476 if (!have_ptrace_booke_interface ()) |
| 1469 { | 1477 { |
| (...skipping 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2144 saved_dabr_value) < 0) | 2152 saved_dabr_value) < 0) |
| 2145 return -1; | 2153 return -1; |
| 2146 | 2154 |
| 2147 ret = 0; | 2155 ret = 0; |
| 2148 } | 2156 } |
| 2149 | 2157 |
| 2150 return ret; | 2158 return ret; |
| 2151 } | 2159 } |
| 2152 | 2160 |
| 2153 static void | 2161 static void |
| 2154 ppc_linux_new_thread (ptid_t ptid) | 2162 ppc_linux_new_thread (struct lwp_info *lp) |
| 2155 { | 2163 { |
| 2156 int tid = TIDGET (ptid); | 2164 int tid = TIDGET (lp->ptid); |
| 2157 | 2165 |
| 2158 if (have_ptrace_booke_interface ()) | 2166 if (have_ptrace_booke_interface ()) |
| 2159 { | 2167 { |
| 2160 int i; | 2168 int i; |
| 2161 struct thread_points *p; | 2169 struct thread_points *p; |
| 2162 struct hw_break_tuple *hw_breaks; | 2170 struct hw_break_tuple *hw_breaks; |
| 2163 | 2171 |
| 2164 if (VEC_empty (thread_points_p, ppc_threads)) | 2172 if (VEC_empty (thread_points_p, ppc_threads)) |
| 2165 return; | 2173 return; |
| 2166 | 2174 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2206 if (hw_breaks[i].hw_break) | 2214 if (hw_breaks[i].hw_break) |
| 2207 xfree (hw_breaks[i].hw_break); | 2215 xfree (hw_breaks[i].hw_break); |
| 2208 | 2216 |
| 2209 xfree (t->hw_breaks); | 2217 xfree (t->hw_breaks); |
| 2210 xfree (t); | 2218 xfree (t); |
| 2211 } | 2219 } |
| 2212 | 2220 |
| 2213 static int | 2221 static int |
| 2214 ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) | 2222 ppc_linux_stopped_data_address (struct target_ops *target, CORE_ADDR *addr_p) |
| 2215 { | 2223 { |
| 2216 struct siginfo *siginfo_p; | 2224 siginfo_t siginfo; |
| 2217 | 2225 |
| 2218 siginfo_p = linux_nat_get_siginfo (inferior_ptid); | 2226 if (!linux_nat_get_siginfo (inferior_ptid, &siginfo)) |
| 2227 return 0; |
| 2219 | 2228 |
| 2220 if (siginfo_p->si_signo != SIGTRAP | 2229 if (siginfo.si_signo != SIGTRAP |
| 2221 || (siginfo_p->si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */) | 2230 || (siginfo.si_code & 0xffff) != 0x0004 /* TRAP_HWBKPT */) |
| 2222 return 0; | 2231 return 0; |
| 2223 | 2232 |
| 2224 if (have_ptrace_booke_interface ()) | 2233 if (have_ptrace_booke_interface ()) |
| 2225 { | 2234 { |
| 2226 int i; | 2235 int i; |
| 2227 struct thread_points *t; | 2236 struct thread_points *t; |
| 2228 struct hw_break_tuple *hw_breaks; | 2237 struct hw_break_tuple *hw_breaks; |
| 2229 /* The index (or slot) of the *point is passed in the si_errno field. */ | 2238 /* The index (or slot) of the *point is passed in the si_errno field. */ |
| 2230 int slot = siginfo_p->si_errno; | 2239 int slot = siginfo.si_errno; |
| 2231 | 2240 |
| 2232 t = booke_find_thread_points_by_tid (TIDGET (inferior_ptid), 0); | 2241 t = booke_find_thread_points_by_tid (TIDGET (inferior_ptid), 0); |
| 2233 | 2242 |
| 2234 /* Find out if this *point is a hardware breakpoint. | 2243 /* Find out if this *point is a hardware breakpoint. |
| 2235 If so, we should return 0. */ | 2244 If so, we should return 0. */ |
| 2236 if (t) | 2245 if (t) |
| 2237 { | 2246 { |
| 2238 hw_breaks = t->hw_breaks; | 2247 hw_breaks = t->hw_breaks; |
| 2239 for (i = 0; i < max_slots_number; i++) | 2248 for (i = 0; i < max_slots_number; i++) |
| 2240 if (hw_breaks[i].hw_break && hw_breaks[i].slot == slot | 2249 if (hw_breaks[i].hw_break && hw_breaks[i].slot == slot |
| 2241 && hw_breaks[i].hw_break->trigger_type | 2250 && hw_breaks[i].hw_break->trigger_type |
| 2242 == PPC_BREAKPOINT_TRIGGER_EXECUTE) | 2251 == PPC_BREAKPOINT_TRIGGER_EXECUTE) |
| 2243 return 0; | 2252 return 0; |
| 2244 } | 2253 } |
| 2245 } | 2254 } |
| 2246 | 2255 |
| 2247 *addr_p = (CORE_ADDR) (uintptr_t) siginfo_p->si_addr; | 2256 *addr_p = (CORE_ADDR) (uintptr_t) siginfo.si_addr; |
| 2248 return 1; | 2257 return 1; |
| 2249 } | 2258 } |
| 2250 | 2259 |
| 2251 static int | 2260 static int |
| 2252 ppc_linux_stopped_by_watchpoint (void) | 2261 ppc_linux_stopped_by_watchpoint (void) |
| 2253 { | 2262 { |
| 2254 CORE_ADDR addr; | 2263 CORE_ADDR addr; |
| 2255 return ppc_linux_stopped_data_address (¤t_target, &addr); | 2264 return ppc_linux_stopped_data_address (¤t_target, &addr); |
| 2256 } | 2265 } |
| 2257 | 2266 |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2522 | 2531 |
| 2523 t->to_read_description = ppc_linux_read_description; | 2532 t->to_read_description = ppc_linux_read_description; |
| 2524 t->to_auxv_parse = ppc_linux_auxv_parse; | 2533 t->to_auxv_parse = ppc_linux_auxv_parse; |
| 2525 | 2534 |
| 2526 observer_attach_thread_exit (ppc_linux_thread_exit); | 2535 observer_attach_thread_exit (ppc_linux_thread_exit); |
| 2527 | 2536 |
| 2528 /* Register the target. */ | 2537 /* Register the target. */ |
| 2529 linux_nat_add_target (t); | 2538 linux_nat_add_target (t); |
| 2530 linux_nat_set_new_thread (t, ppc_linux_new_thread); | 2539 linux_nat_set_new_thread (t, ppc_linux_new_thread); |
| 2531 } | 2540 } |
| OLD | NEW |