1739 lines · cpp
1//===-- RegisterContextDarwin_arm.cpp -------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "RegisterContextDarwin_arm.h"10#include "RegisterContextDarwinConstants.h"11 12#include "lldb/Utility/DataBufferHeap.h"13#include "lldb/Utility/DataExtractor.h"14#include "lldb/Utility/Endian.h"15#include "lldb/Utility/Log.h"16#include "lldb/Utility/RegisterValue.h"17#include "lldb/Utility/Scalar.h"18#include "llvm/Support/Compiler.h"19 20#include "Plugins/Process/Utility/InstructionUtils.h"21 22#include <memory>23 24#include "Utility/ARM_DWARF_Registers.h"25#include "Utility/ARM_ehframe_Registers.h"26 27#include "llvm/ADT/STLExtras.h"28 29using namespace lldb;30using namespace lldb_private;31 32enum {33 gpr_r0 = 0,34 gpr_r1,35 gpr_r2,36 gpr_r3,37 gpr_r4,38 gpr_r5,39 gpr_r6,40 gpr_r7,41 gpr_r8,42 gpr_r9,43 gpr_r10,44 gpr_r11,45 gpr_r12,46 gpr_r13,47 gpr_sp = gpr_r13,48 gpr_r14,49 gpr_lr = gpr_r14,50 gpr_r15,51 gpr_pc = gpr_r15,52 gpr_cpsr,53 54 fpu_s0,55 fpu_s1,56 fpu_s2,57 fpu_s3,58 fpu_s4,59 fpu_s5,60 fpu_s6,61 fpu_s7,62 fpu_s8,63 fpu_s9,64 fpu_s10,65 fpu_s11,66 fpu_s12,67 fpu_s13,68 fpu_s14,69 fpu_s15,70 fpu_s16,71 fpu_s17,72 fpu_s18,73 fpu_s19,74 fpu_s20,75 fpu_s21,76 fpu_s22,77 fpu_s23,78 fpu_s24,79 fpu_s25,80 fpu_s26,81 fpu_s27,82 fpu_s28,83 fpu_s29,84 fpu_s30,85 fpu_s31,86 fpu_fpscr,87 88 exc_exception,89 exc_fsr,90 exc_far,91 92 dbg_bvr0,93 dbg_bvr1,94 dbg_bvr2,95 dbg_bvr3,96 dbg_bvr4,97 dbg_bvr5,98 dbg_bvr6,99 dbg_bvr7,100 dbg_bvr8,101 dbg_bvr9,102 dbg_bvr10,103 dbg_bvr11,104 dbg_bvr12,105 dbg_bvr13,106 dbg_bvr14,107 dbg_bvr15,108 109 dbg_bcr0,110 dbg_bcr1,111 dbg_bcr2,112 dbg_bcr3,113 dbg_bcr4,114 dbg_bcr5,115 dbg_bcr6,116 dbg_bcr7,117 dbg_bcr8,118 dbg_bcr9,119 dbg_bcr10,120 dbg_bcr11,121 dbg_bcr12,122 dbg_bcr13,123 dbg_bcr14,124 dbg_bcr15,125 126 dbg_wvr0,127 dbg_wvr1,128 dbg_wvr2,129 dbg_wvr3,130 dbg_wvr4,131 dbg_wvr5,132 dbg_wvr6,133 dbg_wvr7,134 dbg_wvr8,135 dbg_wvr9,136 dbg_wvr10,137 dbg_wvr11,138 dbg_wvr12,139 dbg_wvr13,140 dbg_wvr14,141 dbg_wvr15,142 143 dbg_wcr0,144 dbg_wcr1,145 dbg_wcr2,146 dbg_wcr3,147 dbg_wcr4,148 dbg_wcr5,149 dbg_wcr6,150 dbg_wcr7,151 dbg_wcr8,152 dbg_wcr9,153 dbg_wcr10,154 dbg_wcr11,155 dbg_wcr12,156 dbg_wcr13,157 dbg_wcr14,158 dbg_wcr15,159 160 k_num_registers161};162 163#define GPR_OFFSET(idx) ((idx)*4)164#define FPU_OFFSET(idx) ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR))165#define EXC_OFFSET(idx) \166 ((idx)*4 + sizeof(RegisterContextDarwin_arm::GPR) + \167 sizeof(RegisterContextDarwin_arm::FPU))168#define DBG_OFFSET(reg) \169 ((LLVM_EXTENSION offsetof(RegisterContextDarwin_arm::DBG, reg) + \170 sizeof(RegisterContextDarwin_arm::GPR) + \171 sizeof(RegisterContextDarwin_arm::FPU) + \172 sizeof(RegisterContextDarwin_arm::EXC)))173 174#define DEFINE_DBG(reg, i) \175 #reg, NULL, sizeof(((RegisterContextDarwin_arm::DBG *) NULL)->reg[i]), \176 DBG_OFFSET(reg[i]), eEncodingUint, eFormatHex, \177 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \178 LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \179 LLDB_INVALID_REGNUM }, \180 nullptr, nullptr, nullptr,181#define REG_CONTEXT_SIZE \182 (sizeof(RegisterContextDarwin_arm::GPR) + \183 sizeof(RegisterContextDarwin_arm::FPU) + \184 sizeof(RegisterContextDarwin_arm::EXC))185 186static RegisterInfo g_register_infos[] = {187 {"r0",188 nullptr,189 4,190 GPR_OFFSET(0),191 eEncodingUint,192 eFormatHex,193 {ehframe_r0, dwarf_r0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r0},194 nullptr,195 nullptr,196 nullptr,197 },198 {"r1",199 nullptr,200 4,201 GPR_OFFSET(1),202 eEncodingUint,203 eFormatHex,204 {ehframe_r1, dwarf_r1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r1},205 nullptr,206 nullptr,207 nullptr,208 },209 {"r2",210 nullptr,211 4,212 GPR_OFFSET(2),213 eEncodingUint,214 eFormatHex,215 {ehframe_r2, dwarf_r2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r2},216 nullptr,217 nullptr,218 nullptr,219 },220 {"r3",221 nullptr,222 4,223 GPR_OFFSET(3),224 eEncodingUint,225 eFormatHex,226 {ehframe_r3, dwarf_r3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r3},227 nullptr,228 nullptr,229 nullptr,230 },231 {"r4",232 nullptr,233 4,234 GPR_OFFSET(4),235 eEncodingUint,236 eFormatHex,237 {ehframe_r4, dwarf_r4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r4},238 nullptr,239 nullptr,240 nullptr,241 },242 {"r5",243 nullptr,244 4,245 GPR_OFFSET(5),246 eEncodingUint,247 eFormatHex,248 {ehframe_r5, dwarf_r5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r5},249 nullptr,250 nullptr,251 nullptr,252 },253 {"r6",254 nullptr,255 4,256 GPR_OFFSET(6),257 eEncodingUint,258 eFormatHex,259 {ehframe_r6, dwarf_r6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r6},260 nullptr,261 nullptr,262 nullptr,263 },264 {"r7",265 nullptr,266 4,267 GPR_OFFSET(7),268 eEncodingUint,269 eFormatHex,270 {ehframe_r7, dwarf_r7, LLDB_REGNUM_GENERIC_FP, LLDB_INVALID_REGNUM,271 gpr_r7},272 nullptr,273 nullptr,274 nullptr,275 },276 {"r8",277 nullptr,278 4,279 GPR_OFFSET(8),280 eEncodingUint,281 eFormatHex,282 {ehframe_r8, dwarf_r8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r8},283 nullptr,284 nullptr,285 nullptr,286 },287 {"r9",288 nullptr,289 4,290 GPR_OFFSET(9),291 eEncodingUint,292 eFormatHex,293 {ehframe_r9, dwarf_r9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gpr_r9},294 nullptr,295 nullptr,296 nullptr,297 },298 {"r10",299 nullptr,300 4,301 GPR_OFFSET(10),302 eEncodingUint,303 eFormatHex,304 {ehframe_r10, dwarf_r10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,305 gpr_r10},306 nullptr,307 nullptr,308 nullptr,309 },310 {"r11",311 nullptr,312 4,313 GPR_OFFSET(11),314 eEncodingUint,315 eFormatHex,316 {ehframe_r11, dwarf_r11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,317 gpr_r11},318 nullptr,319 nullptr,320 nullptr,321 },322 {"r12",323 nullptr,324 4,325 GPR_OFFSET(12),326 eEncodingUint,327 eFormatHex,328 {ehframe_r12, dwarf_r12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,329 gpr_r12},330 nullptr,331 nullptr,332 nullptr,333 },334 {"sp",335 "r13",336 4,337 GPR_OFFSET(13),338 eEncodingUint,339 eFormatHex,340 {ehframe_sp, dwarf_sp, LLDB_REGNUM_GENERIC_SP, LLDB_INVALID_REGNUM,341 gpr_sp},342 nullptr,343 nullptr,344 nullptr,345 },346 {"lr",347 "r14",348 4,349 GPR_OFFSET(14),350 eEncodingUint,351 eFormatHex,352 {ehframe_lr, dwarf_lr, LLDB_REGNUM_GENERIC_RA, LLDB_INVALID_REGNUM,353 gpr_lr},354 nullptr,355 nullptr,356 nullptr,357 },358 {"pc",359 "r15",360 4,361 GPR_OFFSET(15),362 eEncodingUint,363 eFormatHex,364 {ehframe_pc, dwarf_pc, LLDB_REGNUM_GENERIC_PC, LLDB_INVALID_REGNUM,365 gpr_pc},366 nullptr,367 nullptr,368 nullptr,369 },370 {"cpsr",371 "psr",372 4,373 GPR_OFFSET(16),374 eEncodingUint,375 eFormatHex,376 {ehframe_cpsr, dwarf_cpsr, LLDB_REGNUM_GENERIC_FLAGS, LLDB_INVALID_REGNUM,377 gpr_cpsr},378 nullptr,379 nullptr,380 nullptr,381 },382 383 {"s0",384 nullptr,385 4,386 FPU_OFFSET(0),387 eEncodingIEEE754,388 eFormatFloat,389 {LLDB_INVALID_REGNUM, dwarf_s0, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,390 fpu_s0},391 nullptr,392 nullptr,393 nullptr,394 },395 {"s1",396 nullptr,397 4,398 FPU_OFFSET(1),399 eEncodingIEEE754,400 eFormatFloat,401 {LLDB_INVALID_REGNUM, dwarf_s1, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,402 fpu_s1},403 nullptr,404 nullptr,405 nullptr,406 },407 {"s2",408 nullptr,409 4,410 FPU_OFFSET(2),411 eEncodingIEEE754,412 eFormatFloat,413 {LLDB_INVALID_REGNUM, dwarf_s2, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,414 fpu_s2},415 nullptr,416 nullptr,417 nullptr,418 },419 {"s3",420 nullptr,421 4,422 FPU_OFFSET(3),423 eEncodingIEEE754,424 eFormatFloat,425 {LLDB_INVALID_REGNUM, dwarf_s3, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,426 fpu_s3},427 nullptr,428 nullptr,429 nullptr,430 },431 {"s4",432 nullptr,433 4,434 FPU_OFFSET(4),435 eEncodingIEEE754,436 eFormatFloat,437 {LLDB_INVALID_REGNUM, dwarf_s4, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,438 fpu_s4},439 nullptr,440 nullptr,441 nullptr,442 },443 {"s5",444 nullptr,445 4,446 FPU_OFFSET(5),447 eEncodingIEEE754,448 eFormatFloat,449 {LLDB_INVALID_REGNUM, dwarf_s5, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,450 fpu_s5},451 nullptr,452 nullptr,453 nullptr,454 },455 {"s6",456 nullptr,457 4,458 FPU_OFFSET(6),459 eEncodingIEEE754,460 eFormatFloat,461 {LLDB_INVALID_REGNUM, dwarf_s6, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,462 fpu_s6},463 nullptr,464 nullptr,465 nullptr,466 },467 {"s7",468 nullptr,469 4,470 FPU_OFFSET(7),471 eEncodingIEEE754,472 eFormatFloat,473 {LLDB_INVALID_REGNUM, dwarf_s7, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,474 fpu_s7},475 nullptr,476 nullptr,477 nullptr,478 },479 {"s8",480 nullptr,481 4,482 FPU_OFFSET(8),483 eEncodingIEEE754,484 eFormatFloat,485 {LLDB_INVALID_REGNUM, dwarf_s8, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,486 fpu_s8},487 nullptr,488 nullptr,489 nullptr,490 },491 {"s9",492 nullptr,493 4,494 FPU_OFFSET(9),495 eEncodingIEEE754,496 eFormatFloat,497 {LLDB_INVALID_REGNUM, dwarf_s9, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,498 fpu_s9},499 nullptr,500 nullptr,501 nullptr,502 },503 {"s10",504 nullptr,505 4,506 FPU_OFFSET(10),507 eEncodingIEEE754,508 eFormatFloat,509 {LLDB_INVALID_REGNUM, dwarf_s10, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,510 fpu_s10},511 nullptr,512 nullptr,513 nullptr,514 },515 {"s11",516 nullptr,517 4,518 FPU_OFFSET(11),519 eEncodingIEEE754,520 eFormatFloat,521 {LLDB_INVALID_REGNUM, dwarf_s11, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,522 fpu_s11},523 nullptr,524 nullptr,525 nullptr,526 },527 {"s12",528 nullptr,529 4,530 FPU_OFFSET(12),531 eEncodingIEEE754,532 eFormatFloat,533 {LLDB_INVALID_REGNUM, dwarf_s12, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,534 fpu_s12},535 nullptr,536 nullptr,537 nullptr,538 },539 {"s13",540 nullptr,541 4,542 FPU_OFFSET(13),543 eEncodingIEEE754,544 eFormatFloat,545 {LLDB_INVALID_REGNUM, dwarf_s13, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,546 fpu_s13},547 nullptr,548 nullptr,549 nullptr,550 },551 {"s14",552 nullptr,553 4,554 FPU_OFFSET(14),555 eEncodingIEEE754,556 eFormatFloat,557 {LLDB_INVALID_REGNUM, dwarf_s14, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,558 fpu_s14},559 nullptr,560 nullptr,561 nullptr,562 },563 {"s15",564 nullptr,565 4,566 FPU_OFFSET(15),567 eEncodingIEEE754,568 eFormatFloat,569 {LLDB_INVALID_REGNUM, dwarf_s15, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,570 fpu_s15},571 nullptr,572 nullptr,573 nullptr,574 },575 {"s16",576 nullptr,577 4,578 FPU_OFFSET(16),579 eEncodingIEEE754,580 eFormatFloat,581 {LLDB_INVALID_REGNUM, dwarf_s16, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,582 fpu_s16},583 nullptr,584 nullptr,585 nullptr,586 },587 {"s17",588 nullptr,589 4,590 FPU_OFFSET(17),591 eEncodingIEEE754,592 eFormatFloat,593 {LLDB_INVALID_REGNUM, dwarf_s17, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,594 fpu_s17},595 nullptr,596 nullptr,597 nullptr,598 },599 {"s18",600 nullptr,601 4,602 FPU_OFFSET(18),603 eEncodingIEEE754,604 eFormatFloat,605 {LLDB_INVALID_REGNUM, dwarf_s18, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,606 fpu_s18},607 nullptr,608 nullptr,609 nullptr,610 },611 {"s19",612 nullptr,613 4,614 FPU_OFFSET(19),615 eEncodingIEEE754,616 eFormatFloat,617 {LLDB_INVALID_REGNUM, dwarf_s19, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,618 fpu_s19},619 nullptr,620 nullptr,621 nullptr,622 },623 {"s20",624 nullptr,625 4,626 FPU_OFFSET(20),627 eEncodingIEEE754,628 eFormatFloat,629 {LLDB_INVALID_REGNUM, dwarf_s20, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,630 fpu_s20},631 nullptr,632 nullptr,633 nullptr,634 },635 {"s21",636 nullptr,637 4,638 FPU_OFFSET(21),639 eEncodingIEEE754,640 eFormatFloat,641 {LLDB_INVALID_REGNUM, dwarf_s21, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,642 fpu_s21},643 nullptr,644 nullptr,645 nullptr,646 },647 {"s22",648 nullptr,649 4,650 FPU_OFFSET(22),651 eEncodingIEEE754,652 eFormatFloat,653 {LLDB_INVALID_REGNUM, dwarf_s22, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,654 fpu_s22},655 nullptr,656 nullptr,657 nullptr,658 },659 {"s23",660 nullptr,661 4,662 FPU_OFFSET(23),663 eEncodingIEEE754,664 eFormatFloat,665 {LLDB_INVALID_REGNUM, dwarf_s23, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,666 fpu_s23},667 nullptr,668 nullptr,669 nullptr,670 },671 {"s24",672 nullptr,673 4,674 FPU_OFFSET(24),675 eEncodingIEEE754,676 eFormatFloat,677 {LLDB_INVALID_REGNUM, dwarf_s24, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,678 fpu_s24},679 nullptr,680 nullptr,681 nullptr,682 },683 {"s25",684 nullptr,685 4,686 FPU_OFFSET(25),687 eEncodingIEEE754,688 eFormatFloat,689 {LLDB_INVALID_REGNUM, dwarf_s25, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,690 fpu_s25},691 nullptr,692 nullptr,693 nullptr,694 },695 {"s26",696 nullptr,697 4,698 FPU_OFFSET(26),699 eEncodingIEEE754,700 eFormatFloat,701 {LLDB_INVALID_REGNUM, dwarf_s26, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,702 fpu_s26},703 nullptr,704 nullptr,705 nullptr,706 },707 {"s27",708 nullptr,709 4,710 FPU_OFFSET(27),711 eEncodingIEEE754,712 eFormatFloat,713 {LLDB_INVALID_REGNUM, dwarf_s27, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,714 fpu_s27},715 nullptr,716 nullptr,717 nullptr,718 },719 {"s28",720 nullptr,721 4,722 FPU_OFFSET(28),723 eEncodingIEEE754,724 eFormatFloat,725 {LLDB_INVALID_REGNUM, dwarf_s28, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,726 fpu_s28},727 nullptr,728 nullptr,729 nullptr,730 },731 {"s29",732 nullptr,733 4,734 FPU_OFFSET(29),735 eEncodingIEEE754,736 eFormatFloat,737 {LLDB_INVALID_REGNUM, dwarf_s29, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,738 fpu_s29},739 nullptr,740 nullptr,741 nullptr,742 },743 {"s30",744 nullptr,745 4,746 FPU_OFFSET(30),747 eEncodingIEEE754,748 eFormatFloat,749 {LLDB_INVALID_REGNUM, dwarf_s30, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,750 fpu_s30},751 nullptr,752 nullptr,753 nullptr,754 },755 {"s31",756 nullptr,757 4,758 FPU_OFFSET(31),759 eEncodingIEEE754,760 eFormatFloat,761 {LLDB_INVALID_REGNUM, dwarf_s31, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,762 fpu_s31},763 nullptr,764 nullptr,765 nullptr,766 },767 {"fpscr",768 nullptr,769 4,770 FPU_OFFSET(32),771 eEncodingUint,772 eFormatHex,773 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,774 LLDB_INVALID_REGNUM, fpu_fpscr},775 nullptr,776 nullptr,777 nullptr,778 },779 780 {"exception",781 nullptr,782 4,783 EXC_OFFSET(0),784 eEncodingUint,785 eFormatHex,786 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,787 LLDB_INVALID_REGNUM, exc_exception},788 nullptr,789 nullptr,790 nullptr,791 },792 {"fsr",793 nullptr,794 4,795 EXC_OFFSET(1),796 eEncodingUint,797 eFormatHex,798 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,799 LLDB_INVALID_REGNUM, exc_fsr},800 nullptr,801 nullptr,802 nullptr,803 },804 {"far",805 nullptr,806 4,807 EXC_OFFSET(2),808 eEncodingUint,809 eFormatHex,810 {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,811 LLDB_INVALID_REGNUM, exc_far},812 nullptr,813 nullptr,814 nullptr,815 },816 817 {DEFINE_DBG(bvr, 0)},818 {DEFINE_DBG(bvr, 1)},819 {DEFINE_DBG(bvr, 2)},820 {DEFINE_DBG(bvr, 3)},821 {DEFINE_DBG(bvr, 4)},822 {DEFINE_DBG(bvr, 5)},823 {DEFINE_DBG(bvr, 6)},824 {DEFINE_DBG(bvr, 7)},825 {DEFINE_DBG(bvr, 8)},826 {DEFINE_DBG(bvr, 9)},827 {DEFINE_DBG(bvr, 10)},828 {DEFINE_DBG(bvr, 11)},829 {DEFINE_DBG(bvr, 12)},830 {DEFINE_DBG(bvr, 13)},831 {DEFINE_DBG(bvr, 14)},832 {DEFINE_DBG(bvr, 15)},833 834 {DEFINE_DBG(bcr, 0)},835 {DEFINE_DBG(bcr, 1)},836 {DEFINE_DBG(bcr, 2)},837 {DEFINE_DBG(bcr, 3)},838 {DEFINE_DBG(bcr, 4)},839 {DEFINE_DBG(bcr, 5)},840 {DEFINE_DBG(bcr, 6)},841 {DEFINE_DBG(bcr, 7)},842 {DEFINE_DBG(bcr, 8)},843 {DEFINE_DBG(bcr, 9)},844 {DEFINE_DBG(bcr, 10)},845 {DEFINE_DBG(bcr, 11)},846 {DEFINE_DBG(bcr, 12)},847 {DEFINE_DBG(bcr, 13)},848 {DEFINE_DBG(bcr, 14)},849 {DEFINE_DBG(bcr, 15)},850 851 {DEFINE_DBG(wvr, 0)},852 {DEFINE_DBG(wvr, 1)},853 {DEFINE_DBG(wvr, 2)},854 {DEFINE_DBG(wvr, 3)},855 {DEFINE_DBG(wvr, 4)},856 {DEFINE_DBG(wvr, 5)},857 {DEFINE_DBG(wvr, 6)},858 {DEFINE_DBG(wvr, 7)},859 {DEFINE_DBG(wvr, 8)},860 {DEFINE_DBG(wvr, 9)},861 {DEFINE_DBG(wvr, 10)},862 {DEFINE_DBG(wvr, 11)},863 {DEFINE_DBG(wvr, 12)},864 {DEFINE_DBG(wvr, 13)},865 {DEFINE_DBG(wvr, 14)},866 {DEFINE_DBG(wvr, 15)},867 868 {DEFINE_DBG(wcr, 0)},869 {DEFINE_DBG(wcr, 1)},870 {DEFINE_DBG(wcr, 2)},871 {DEFINE_DBG(wcr, 3)},872 {DEFINE_DBG(wcr, 4)},873 {DEFINE_DBG(wcr, 5)},874 {DEFINE_DBG(wcr, 6)},875 {DEFINE_DBG(wcr, 7)},876 {DEFINE_DBG(wcr, 8)},877 {DEFINE_DBG(wcr, 9)},878 {DEFINE_DBG(wcr, 10)},879 {DEFINE_DBG(wcr, 11)},880 {DEFINE_DBG(wcr, 12)},881 {DEFINE_DBG(wcr, 13)},882 {DEFINE_DBG(wcr, 14)},883 {DEFINE_DBG(wcr, 15)}};884 885// General purpose registers886static uint32_t g_gpr_regnums[] = {887 gpr_r0, gpr_r1, gpr_r2, gpr_r3, gpr_r4, gpr_r5, gpr_r6, gpr_r7, gpr_r8,888 gpr_r9, gpr_r10, gpr_r11, gpr_r12, gpr_sp, gpr_lr, gpr_pc, gpr_cpsr};889 890// Floating point registers891static uint32_t g_fpu_regnums[] = {892 fpu_s0, fpu_s1, fpu_s2, fpu_s3, fpu_s4, fpu_s5, fpu_s6,893 fpu_s7, fpu_s8, fpu_s9, fpu_s10, fpu_s11, fpu_s12, fpu_s13,894 fpu_s14, fpu_s15, fpu_s16, fpu_s17, fpu_s18, fpu_s19, fpu_s20,895 fpu_s21, fpu_s22, fpu_s23, fpu_s24, fpu_s25, fpu_s26, fpu_s27,896 fpu_s28, fpu_s29, fpu_s30, fpu_s31, fpu_fpscr,897};898 899// Exception registers900 901static uint32_t g_exc_regnums[] = {902 exc_exception, exc_fsr, exc_far,903};904 905static size_t k_num_register_infos = std::size(g_register_infos);906 907RegisterContextDarwin_arm::RegisterContextDarwin_arm(908 Thread &thread, uint32_t concrete_frame_idx)909 : RegisterContext(thread, concrete_frame_idx), gpr(), fpu(), exc() {910 uint32_t i;911 for (i = 0; i < kNumErrors; i++) {912 gpr_errs[i] = -1;913 fpu_errs[i] = -1;914 exc_errs[i] = -1;915 }916}917 918RegisterContextDarwin_arm::~RegisterContextDarwin_arm() = default;919 920void RegisterContextDarwin_arm::InvalidateAllRegisters() {921 InvalidateAllRegisterStates();922}923 924size_t RegisterContextDarwin_arm::GetRegisterCount() {925 assert(k_num_register_infos == k_num_registers);926 return k_num_registers;927}928 929const RegisterInfo *930RegisterContextDarwin_arm::GetRegisterInfoAtIndex(size_t reg) {931 assert(k_num_register_infos == k_num_registers);932 if (reg < k_num_registers)933 return &g_register_infos[reg];934 return nullptr;935}936 937size_t RegisterContextDarwin_arm::GetRegisterInfosCount() {938 return k_num_register_infos;939}940 941const RegisterInfo *RegisterContextDarwin_arm::GetRegisterInfos() {942 return g_register_infos;943}944 945// Number of registers in each register set946const size_t k_num_gpr_registers = std::size(g_gpr_regnums);947const size_t k_num_fpu_registers = std::size(g_fpu_regnums);948const size_t k_num_exc_registers = std::size(g_exc_regnums);949 950// Register set definitions. The first definitions at register set index of951// zero is for all registers, followed by other registers sets. The register952// information for the all register set need not be filled in.953static const RegisterSet g_reg_sets[] = {954 {955 "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums,956 },957 {"Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums},958 {"Exception State Registers", "exc", k_num_exc_registers, g_exc_regnums}};959 960const size_t k_num_regsets = std::size(g_reg_sets);961 962size_t RegisterContextDarwin_arm::GetRegisterSetCount() {963 return k_num_regsets;964}965 966const RegisterSet *RegisterContextDarwin_arm::GetRegisterSet(size_t reg_set) {967 if (reg_set < k_num_regsets)968 return &g_reg_sets[reg_set];969 return nullptr;970}971 972// Register information definitions for 32 bit i386.973int RegisterContextDarwin_arm::GetSetForNativeRegNum(int reg) {974 if (reg < fpu_s0)975 return GPRRegSet;976 else if (reg < exc_exception)977 return FPURegSet;978 else if (reg < k_num_registers)979 return EXCRegSet;980 return -1;981}982 983int RegisterContextDarwin_arm::ReadGPR(bool force) {984 int set = GPRRegSet;985 if (force || !RegisterSetIsCached(set)) {986 SetError(set, Read, DoReadGPR(GetThreadID(), set, gpr));987 }988 return GetError(GPRRegSet, Read);989}990 991int RegisterContextDarwin_arm::ReadFPU(bool force) {992 int set = FPURegSet;993 if (force || !RegisterSetIsCached(set)) {994 SetError(set, Read, DoReadFPU(GetThreadID(), set, fpu));995 }996 return GetError(FPURegSet, Read);997}998 999int RegisterContextDarwin_arm::ReadEXC(bool force) {1000 int set = EXCRegSet;1001 if (force || !RegisterSetIsCached(set)) {1002 SetError(set, Read, DoReadEXC(GetThreadID(), set, exc));1003 }1004 return GetError(EXCRegSet, Read);1005}1006 1007int RegisterContextDarwin_arm::ReadDBG(bool force) {1008 int set = DBGRegSet;1009 if (force || !RegisterSetIsCached(set)) {1010 SetError(set, Read, DoReadDBG(GetThreadID(), set, dbg));1011 }1012 return GetError(DBGRegSet, Read);1013}1014 1015int RegisterContextDarwin_arm::WriteGPR() {1016 int set = GPRRegSet;1017 if (!RegisterSetIsCached(set)) {1018 SetError(set, Write, -1);1019 return KERN_INVALID_ARGUMENT;1020 }1021 SetError(set, Write, DoWriteGPR(GetThreadID(), set, gpr));1022 SetError(set, Read, -1);1023 return GetError(GPRRegSet, Write);1024}1025 1026int RegisterContextDarwin_arm::WriteFPU() {1027 int set = FPURegSet;1028 if (!RegisterSetIsCached(set)) {1029 SetError(set, Write, -1);1030 return KERN_INVALID_ARGUMENT;1031 }1032 SetError(set, Write, DoWriteFPU(GetThreadID(), set, fpu));1033 SetError(set, Read, -1);1034 return GetError(FPURegSet, Write);1035}1036 1037int RegisterContextDarwin_arm::WriteEXC() {1038 int set = EXCRegSet;1039 if (!RegisterSetIsCached(set)) {1040 SetError(set, Write, -1);1041 return KERN_INVALID_ARGUMENT;1042 }1043 SetError(set, Write, DoWriteEXC(GetThreadID(), set, exc));1044 SetError(set, Read, -1);1045 return GetError(EXCRegSet, Write);1046}1047 1048int RegisterContextDarwin_arm::WriteDBG() {1049 int set = DBGRegSet;1050 if (!RegisterSetIsCached(set)) {1051 SetError(set, Write, -1);1052 return KERN_INVALID_ARGUMENT;1053 }1054 SetError(set, Write, DoWriteDBG(GetThreadID(), set, dbg));1055 SetError(set, Read, -1);1056 return GetError(DBGRegSet, Write);1057}1058 1059int RegisterContextDarwin_arm::ReadRegisterSet(uint32_t set, bool force) {1060 switch (set) {1061 case GPRRegSet:1062 return ReadGPR(force);1063 case GPRAltRegSet:1064 return ReadGPR(force);1065 case FPURegSet:1066 return ReadFPU(force);1067 case EXCRegSet:1068 return ReadEXC(force);1069 case DBGRegSet:1070 return ReadDBG(force);1071 default:1072 break;1073 }1074 return KERN_INVALID_ARGUMENT;1075}1076 1077int RegisterContextDarwin_arm::WriteRegisterSet(uint32_t set) {1078 // Make sure we have a valid context to set.1079 if (RegisterSetIsCached(set)) {1080 switch (set) {1081 case GPRRegSet:1082 return WriteGPR();1083 case GPRAltRegSet:1084 return WriteGPR();1085 case FPURegSet:1086 return WriteFPU();1087 case EXCRegSet:1088 return WriteEXC();1089 case DBGRegSet:1090 return WriteDBG();1091 default:1092 break;1093 }1094 }1095 return KERN_INVALID_ARGUMENT;1096}1097 1098void RegisterContextDarwin_arm::LogDBGRegisters(Log *log, const DBG &dbg) {1099 if (log) {1100 for (uint32_t i = 0; i < 16; i++)1101 LLDB_LOGF(log,1102 "BVR%-2u/BCR%-2u = { 0x%8.8x, 0x%8.8x } WVR%-2u/WCR%-2u = { "1103 "0x%8.8x, 0x%8.8x }",1104 i, i, dbg.bvr[i], dbg.bcr[i], i, i, dbg.wvr[i], dbg.wcr[i]);1105 }1106}1107 1108bool RegisterContextDarwin_arm::ReadRegister(const RegisterInfo *reg_info,1109 RegisterValue &value) {1110 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];1111 int set = RegisterContextDarwin_arm::GetSetForNativeRegNum(reg);1112 1113 if (set == -1)1114 return false;1115 1116 if (ReadRegisterSet(set, false) != KERN_SUCCESS)1117 return false;1118 1119 switch (reg) {1120 case gpr_r0:1121 case gpr_r1:1122 case gpr_r2:1123 case gpr_r3:1124 case gpr_r4:1125 case gpr_r5:1126 case gpr_r6:1127 case gpr_r7:1128 case gpr_r8:1129 case gpr_r9:1130 case gpr_r10:1131 case gpr_r11:1132 case gpr_r12:1133 case gpr_sp:1134 case gpr_lr:1135 case gpr_pc:1136 value.SetUInt32(gpr.r[reg - gpr_r0]);1137 break;1138 case gpr_cpsr:1139 value.SetUInt32(gpr.cpsr);1140 break;1141 case fpu_s0:1142 case fpu_s1:1143 case fpu_s2:1144 case fpu_s3:1145 case fpu_s4:1146 case fpu_s5:1147 case fpu_s6:1148 case fpu_s7:1149 case fpu_s8:1150 case fpu_s9:1151 case fpu_s10:1152 case fpu_s11:1153 case fpu_s12:1154 case fpu_s13:1155 case fpu_s14:1156 case fpu_s15:1157 case fpu_s16:1158 case fpu_s17:1159 case fpu_s18:1160 case fpu_s19:1161 case fpu_s20:1162 case fpu_s21:1163 case fpu_s22:1164 case fpu_s23:1165 case fpu_s24:1166 case fpu_s25:1167 case fpu_s26:1168 case fpu_s27:1169 case fpu_s28:1170 case fpu_s29:1171 case fpu_s30:1172 case fpu_s31:1173 value.SetUInt32(fpu.floats.s[reg], RegisterValue::eTypeFloat);1174 break;1175 1176 case fpu_fpscr:1177 value.SetUInt32(fpu.fpscr);1178 break;1179 1180 case exc_exception:1181 value.SetUInt32(exc.exception);1182 break;1183 case exc_fsr:1184 value.SetUInt32(exc.fsr);1185 break;1186 case exc_far:1187 value.SetUInt32(exc.far);1188 break;1189 1190 default:1191 value.SetValueToInvalid();1192 return false;1193 }1194 return true;1195}1196 1197bool RegisterContextDarwin_arm::WriteRegister(const RegisterInfo *reg_info,1198 const RegisterValue &value) {1199 const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];1200 int set = GetSetForNativeRegNum(reg);1201 1202 if (set == -1)1203 return false;1204 1205 if (ReadRegisterSet(set, false) != KERN_SUCCESS)1206 return false;1207 1208 switch (reg) {1209 case gpr_r0:1210 case gpr_r1:1211 case gpr_r2:1212 case gpr_r3:1213 case gpr_r4:1214 case gpr_r5:1215 case gpr_r6:1216 case gpr_r7:1217 case gpr_r8:1218 case gpr_r9:1219 case gpr_r10:1220 case gpr_r11:1221 case gpr_r12:1222 case gpr_sp:1223 case gpr_lr:1224 case gpr_pc:1225 case gpr_cpsr:1226 gpr.r[reg - gpr_r0] = value.GetAsUInt32();1227 break;1228 1229 case fpu_s0:1230 case fpu_s1:1231 case fpu_s2:1232 case fpu_s3:1233 case fpu_s4:1234 case fpu_s5:1235 case fpu_s6:1236 case fpu_s7:1237 case fpu_s8:1238 case fpu_s9:1239 case fpu_s10:1240 case fpu_s11:1241 case fpu_s12:1242 case fpu_s13:1243 case fpu_s14:1244 case fpu_s15:1245 case fpu_s16:1246 case fpu_s17:1247 case fpu_s18:1248 case fpu_s19:1249 case fpu_s20:1250 case fpu_s21:1251 case fpu_s22:1252 case fpu_s23:1253 case fpu_s24:1254 case fpu_s25:1255 case fpu_s26:1256 case fpu_s27:1257 case fpu_s28:1258 case fpu_s29:1259 case fpu_s30:1260 case fpu_s31:1261 fpu.floats.s[reg] = value.GetAsUInt32();1262 break;1263 1264 case fpu_fpscr:1265 fpu.fpscr = value.GetAsUInt32();1266 break;1267 1268 case exc_exception:1269 exc.exception = value.GetAsUInt32();1270 break;1271 case exc_fsr:1272 exc.fsr = value.GetAsUInt32();1273 break;1274 case exc_far:1275 exc.far = value.GetAsUInt32();1276 break;1277 1278 default:1279 return false;1280 }1281 return WriteRegisterSet(set) == KERN_SUCCESS;1282}1283 1284bool RegisterContextDarwin_arm::ReadAllRegisterValues(1285 lldb::WritableDataBufferSP &data_sp) {1286 data_sp = std::make_shared<DataBufferHeap>(REG_CONTEXT_SIZE, 0);1287 if (data_sp && ReadGPR(false) == KERN_SUCCESS &&1288 ReadFPU(false) == KERN_SUCCESS && ReadEXC(false) == KERN_SUCCESS) {1289 uint8_t *dst = data_sp->GetBytes();1290 ::memcpy(dst, &gpr, sizeof(gpr));1291 dst += sizeof(gpr);1292 1293 ::memcpy(dst, &fpu, sizeof(fpu));1294 dst += sizeof(gpr);1295 1296 ::memcpy(dst, &exc, sizeof(exc));1297 return true;1298 }1299 return false;1300}1301 1302bool RegisterContextDarwin_arm::WriteAllRegisterValues(1303 const lldb::DataBufferSP &data_sp) {1304 if (data_sp && data_sp->GetByteSize() == REG_CONTEXT_SIZE) {1305 const uint8_t *src = data_sp->GetBytes();1306 ::memcpy(&gpr, src, sizeof(gpr));1307 src += sizeof(gpr);1308 1309 ::memcpy(&fpu, src, sizeof(fpu));1310 src += sizeof(gpr);1311 1312 ::memcpy(&exc, src, sizeof(exc));1313 uint32_t success_count = 0;1314 if (WriteGPR() == KERN_SUCCESS)1315 ++success_count;1316 if (WriteFPU() == KERN_SUCCESS)1317 ++success_count;1318 if (WriteEXC() == KERN_SUCCESS)1319 ++success_count;1320 return success_count == 3;1321 }1322 return false;1323}1324 1325uint32_t RegisterContextDarwin_arm::ConvertRegisterKindToRegisterNumber(1326 lldb::RegisterKind kind, uint32_t reg) {1327 if (kind == eRegisterKindGeneric) {1328 switch (reg) {1329 case LLDB_REGNUM_GENERIC_PC:1330 return gpr_pc;1331 case LLDB_REGNUM_GENERIC_SP:1332 return gpr_sp;1333 case LLDB_REGNUM_GENERIC_FP:1334 return gpr_r7;1335 case LLDB_REGNUM_GENERIC_RA:1336 return gpr_lr;1337 case LLDB_REGNUM_GENERIC_FLAGS:1338 return gpr_cpsr;1339 default:1340 break;1341 }1342 } else if (kind == eRegisterKindDWARF) {1343 switch (reg) {1344 case dwarf_r0:1345 return gpr_r0;1346 case dwarf_r1:1347 return gpr_r1;1348 case dwarf_r2:1349 return gpr_r2;1350 case dwarf_r3:1351 return gpr_r3;1352 case dwarf_r4:1353 return gpr_r4;1354 case dwarf_r5:1355 return gpr_r5;1356 case dwarf_r6:1357 return gpr_r6;1358 case dwarf_r7:1359 return gpr_r7;1360 case dwarf_r8:1361 return gpr_r8;1362 case dwarf_r9:1363 return gpr_r9;1364 case dwarf_r10:1365 return gpr_r10;1366 case dwarf_r11:1367 return gpr_r11;1368 case dwarf_r12:1369 return gpr_r12;1370 case dwarf_sp:1371 return gpr_sp;1372 case dwarf_lr:1373 return gpr_lr;1374 case dwarf_pc:1375 return gpr_pc;1376 case dwarf_spsr:1377 return gpr_cpsr;1378 1379 case dwarf_s0:1380 return fpu_s0;1381 case dwarf_s1:1382 return fpu_s1;1383 case dwarf_s2:1384 return fpu_s2;1385 case dwarf_s3:1386 return fpu_s3;1387 case dwarf_s4:1388 return fpu_s4;1389 case dwarf_s5:1390 return fpu_s5;1391 case dwarf_s6:1392 return fpu_s6;1393 case dwarf_s7:1394 return fpu_s7;1395 case dwarf_s8:1396 return fpu_s8;1397 case dwarf_s9:1398 return fpu_s9;1399 case dwarf_s10:1400 return fpu_s10;1401 case dwarf_s11:1402 return fpu_s11;1403 case dwarf_s12:1404 return fpu_s12;1405 case dwarf_s13:1406 return fpu_s13;1407 case dwarf_s14:1408 return fpu_s14;1409 case dwarf_s15:1410 return fpu_s15;1411 case dwarf_s16:1412 return fpu_s16;1413 case dwarf_s17:1414 return fpu_s17;1415 case dwarf_s18:1416 return fpu_s18;1417 case dwarf_s19:1418 return fpu_s19;1419 case dwarf_s20:1420 return fpu_s20;1421 case dwarf_s21:1422 return fpu_s21;1423 case dwarf_s22:1424 return fpu_s22;1425 case dwarf_s23:1426 return fpu_s23;1427 case dwarf_s24:1428 return fpu_s24;1429 case dwarf_s25:1430 return fpu_s25;1431 case dwarf_s26:1432 return fpu_s26;1433 case dwarf_s27:1434 return fpu_s27;1435 case dwarf_s28:1436 return fpu_s28;1437 case dwarf_s29:1438 return fpu_s29;1439 case dwarf_s30:1440 return fpu_s30;1441 case dwarf_s31:1442 return fpu_s31;1443 1444 default:1445 break;1446 }1447 } else if (kind == eRegisterKindEHFrame) {1448 switch (reg) {1449 case ehframe_r0:1450 return gpr_r0;1451 case ehframe_r1:1452 return gpr_r1;1453 case ehframe_r2:1454 return gpr_r2;1455 case ehframe_r3:1456 return gpr_r3;1457 case ehframe_r4:1458 return gpr_r4;1459 case ehframe_r5:1460 return gpr_r5;1461 case ehframe_r6:1462 return gpr_r6;1463 case ehframe_r7:1464 return gpr_r7;1465 case ehframe_r8:1466 return gpr_r8;1467 case ehframe_r9:1468 return gpr_r9;1469 case ehframe_r10:1470 return gpr_r10;1471 case ehframe_r11:1472 return gpr_r11;1473 case ehframe_r12:1474 return gpr_r12;1475 case ehframe_sp:1476 return gpr_sp;1477 case ehframe_lr:1478 return gpr_lr;1479 case ehframe_pc:1480 return gpr_pc;1481 case ehframe_cpsr:1482 return gpr_cpsr;1483 }1484 } else if (kind == eRegisterKindLLDB) {1485 return reg;1486 }1487 return LLDB_INVALID_REGNUM;1488}1489 1490uint32_t RegisterContextDarwin_arm::NumSupportedHardwareBreakpoints() {1491#if defined(__APPLE__) && defined(__arm__)1492 // Set the init value to something that will let us know that we need to1493 // autodetect how many breakpoints are supported dynamically...1494 static uint32_t g_num_supported_hw_breakpoints = UINT32_MAX;1495 if (g_num_supported_hw_breakpoints == UINT32_MAX) {1496 // Set this to zero in case we can't tell if there are any HW breakpoints1497 g_num_supported_hw_breakpoints = 0;1498 1499 uint32_t register_DBGDIDR;1500 1501 asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));1502 g_num_supported_hw_breakpoints = Bits32(register_DBGDIDR, 27, 24);1503 // Zero is reserved for the BRP count, so don't increment it if it is zero1504 if (g_num_supported_hw_breakpoints > 0)1505 g_num_supported_hw_breakpoints++;1506 }1507 return g_num_supported_hw_breakpoints;1508#else1509 // TODO: figure out remote case here!1510 return 6;1511#endif1512}1513 1514uint32_t RegisterContextDarwin_arm::SetHardwareBreakpoint(lldb::addr_t addr,1515 size_t size) {1516 // Make sure our address isn't bogus1517 if (addr & 1)1518 return LLDB_INVALID_INDEX32;1519 1520 int kret = ReadDBG(false);1521 1522 if (kret == KERN_SUCCESS) {1523 const uint32_t num_hw_breakpoints = NumSupportedHardwareBreakpoints();1524 uint32_t i;1525 for (i = 0; i < num_hw_breakpoints; ++i) {1526 if ((dbg.bcr[i] & BCR_ENABLE) == 0)1527 break; // We found an available hw breakpoint slot (in i)1528 }1529 1530 // See if we found an available hw breakpoint slot above1531 if (i < num_hw_breakpoints) {1532 // Make sure bits 1:0 are clear in our address1533 dbg.bvr[i] = addr & ~((lldb::addr_t)3);1534 1535 if (size == 2 || addr & 2) {1536 uint32_t byte_addr_select = (addr & 2) ? BAS_IMVA_2_3 : BAS_IMVA_0_1;1537 1538 // We have a thumb breakpoint1539 // We have an ARM breakpoint1540 dbg.bcr[i] = BCR_M_IMVA_MATCH | // Stop on address match1541 byte_addr_select | // Set the correct byte address select1542 // so we only trigger on the correct1543 // opcode1544 S_USER | // Which modes should this breakpoint stop in?1545 BCR_ENABLE; // Enable this hardware breakpoint1546 // if (log) log->Printf1547 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(1548 // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /1549 // 0x%8.8x (Thumb)",1550 // addr,1551 // size,1552 // i,1553 // i,1554 // dbg.bvr[i],1555 // dbg.bcr[i]);1556 } else if (size == 4) {1557 // We have an ARM breakpoint1558 dbg.bcr[i] =1559 BCR_M_IMVA_MATCH | // Stop on address match1560 BAS_IMVA_ALL | // Stop on any of the four bytes following the IMVA1561 S_USER | // Which modes should this breakpoint stop in?1562 BCR_ENABLE; // Enable this hardware breakpoint1563 // if (log) log->Printf1564 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(1565 // addr = %8.8p, size = %u ) - BVR%u/BCR%u = 0x%8.8x /1566 // 0x%8.8x (ARM)",1567 // addr,1568 // size,1569 // i,1570 // i,1571 // dbg.bvr[i],1572 // dbg.bcr[i]);1573 }1574 1575 kret = WriteDBG();1576 // if (log) log->Printf1577 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint()1578 // WriteDBG() => 0x%8.8x.", kret);1579 1580 if (kret == KERN_SUCCESS)1581 return i;1582 }1583 // else1584 // {1585 // if (log) log->Printf1586 // ("RegisterContextDarwin_arm::EnableHardwareBreakpoint(addr =1587 // %8.8p, size = %u) => all hardware breakpoint resources are1588 // being used.", addr, size);1589 // }1590 }1591 1592 return LLDB_INVALID_INDEX32;1593}1594 1595bool RegisterContextDarwin_arm::ClearHardwareBreakpoint(uint32_t hw_index) {1596 int kret = ReadDBG(false);1597 1598 const uint32_t num_hw_points = NumSupportedHardwareBreakpoints();1599 if (kret == KERN_SUCCESS) {1600 if (hw_index < num_hw_points) {1601 dbg.bcr[hw_index] = 0;1602 // if (log) log->Printf1603 // ("RegisterContextDarwin_arm::SetHardwareBreakpoint( %u ) -1604 // BVR%u = 0x%8.8x BCR%u = 0x%8.8x",1605 // hw_index,1606 // hw_index,1607 // dbg.bvr[hw_index],1608 // hw_index,1609 // dbg.bcr[hw_index]);1610 1611 kret = WriteDBG();1612 1613 if (kret == KERN_SUCCESS)1614 return true;1615 }1616 }1617 return false;1618}1619 1620uint32_t RegisterContextDarwin_arm::NumSupportedHardwareWatchpoints() {1621#if defined(__APPLE__) && defined(__arm__)1622 // Set the init value to something that will let us know that we need to1623 // autodetect how many watchpoints are supported dynamically...1624 static uint32_t g_num_supported_hw_watchpoints = UINT32_MAX;1625 if (g_num_supported_hw_watchpoints == UINT32_MAX) {1626 // Set this to zero in case we can't tell if there are any HW breakpoints1627 g_num_supported_hw_watchpoints = 0;1628 1629 uint32_t register_DBGDIDR;1630 asm("mrc p14, 0, %0, c0, c0, 0" : "=r"(register_DBGDIDR));1631 g_num_supported_hw_watchpoints = Bits32(register_DBGDIDR, 31, 28) + 1;1632 }1633 return g_num_supported_hw_watchpoints;1634#else1635 // TODO: figure out remote case here!1636 return 2;1637#endif1638}1639 1640uint32_t RegisterContextDarwin_arm::SetHardwareWatchpoint(lldb::addr_t addr,1641 size_t size,1642 bool read,1643 bool write) {1644 const uint32_t num_hw_watchpoints = NumSupportedHardwareWatchpoints();1645 1646 // Can't watch zero bytes1647 if (size == 0)1648 return LLDB_INVALID_INDEX32;1649 1650 // We must watch for either read or write1651 if (!read && !write)1652 return LLDB_INVALID_INDEX32;1653 1654 // Can't watch more than 4 bytes per WVR/WCR pair1655 if (size > 4)1656 return LLDB_INVALID_INDEX32;1657 1658 // We can only watch up to four bytes that follow a 4 byte aligned address1659 // per watchpoint register pair. Since we have at most so we can only watch1660 // until the next 4 byte boundary and we need to make sure we can properly1661 // encode this.1662 uint32_t addr_word_offset = addr % 4;1663 // if (log) log->Printf1664 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() -1665 // addr_word_offset = 0x%8.8x", addr_word_offset);1666 1667 uint32_t byte_mask = ((1u << size) - 1u) << addr_word_offset;1668 // if (log) log->Printf1669 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint() - byte_mask =1670 // 0x%8.8x", byte_mask);1671 if (byte_mask > 0xfu)1672 return LLDB_INVALID_INDEX32;1673 1674 // Read the debug state1675 int kret = ReadDBG(false);1676 1677 if (kret == KERN_SUCCESS) {1678 // Check to make sure we have the needed hardware support1679 uint32_t i = 0;1680 1681 for (i = 0; i < num_hw_watchpoints; ++i) {1682 if ((dbg.wcr[i] & WCR_ENABLE) == 0)1683 break; // We found an available hw breakpoint slot (in i)1684 }1685 1686 // See if we found an available hw breakpoint slot above1687 if (i < num_hw_watchpoints) {1688 // Make the byte_mask into a valid Byte Address Select mask1689 uint32_t byte_address_select = byte_mask << 5;1690 // Make sure bits 1:0 are clear in our address1691 dbg.wvr[i] = addr & ~((lldb::addr_t)3);1692 dbg.wcr[i] = byte_address_select | // Which bytes that follow the IMVA1693 // that we will watch1694 S_USER | // Stop only in user mode1695 (read ? WCR_LOAD : 0) | // Stop on read access?1696 (write ? WCR_STORE : 0) | // Stop on write access?1697 WCR_ENABLE; // Enable this watchpoint;1698 1699 kret = WriteDBG();1700 // if (log) log->Printf1701 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint()1702 // WriteDBG() => 0x%8.8x.", kret);1703 1704 if (kret == KERN_SUCCESS)1705 return i;1706 } else {1707 // if (log) log->Printf1708 // ("RegisterContextDarwin_arm::EnableHardwareWatchpoint(): All1709 // hardware resources (%u) are in use.", num_hw_watchpoints);1710 }1711 }1712 return LLDB_INVALID_INDEX32;1713}1714 1715bool RegisterContextDarwin_arm::ClearHardwareWatchpoint(uint32_t hw_index) {1716 int kret = ReadDBG(false);1717 1718 const uint32_t num_hw_points = NumSupportedHardwareWatchpoints();1719 if (kret == KERN_SUCCESS) {1720 if (hw_index < num_hw_points) {1721 dbg.wcr[hw_index] = 0;1722 // if (log) log->Printf1723 // ("RegisterContextDarwin_arm::ClearHardwareWatchpoint( %u ) -1724 // WVR%u = 0x%8.8x WCR%u = 0x%8.8x",1725 // hw_index,1726 // hw_index,1727 // dbg.wvr[hw_index],1728 // hw_index,1729 // dbg.wcr[hw_index]);1730 1731 kret = WriteDBG();1732 1733 if (kret == KERN_SUCCESS)1734 return true;1735 }1736 }1737 return false;1738}1739