| 875 | } |
| 876 | |
| 877 | KT_BP_RESULT KittyTraceMgr::setSoftBreakpointAndWait(uintptr_t address, |
| 878 | const std::function<bool(user_regs_struct regs)> &cb, |
| 879 | int timeout_ms) |
| 880 | { |
| 881 | if (!_attached || _pid <= 0 || address == 0) |
| 882 | return KT_BP_FAILED; |
| 883 | |
| 884 | #if defined(__arm__) |
| 885 | bool thumb = address & 1; |
| 886 | if (thumb) |
| 887 | address &= ~1; |
| 888 | else |
| 889 | address &= ~3UL; |
| 890 | #elif defined(__aarch64__) |
| 891 | address &= ~3UL; |
| 892 | #endif |
| 893 | |
| 894 | pid_t tid = _pid; |
| 895 | |
| 896 | std::vector<uint8_t> brk_code(sizeof(uintptr_t), 0); |
| 897 | std::vector<uint8_t> bak_code(sizeof(uintptr_t), 0); |
| 898 | int status = 0; |
| 899 | pid_t wp = 0; |
| 900 | user_regs_struct regs = {}; |
| 901 | |
| 902 | // cleanup failure return |
| 903 | auto failure_return = [&](KT_BP_RESULT res = KT_BP_FAILED) -> KT_BP_RESULT { |
| 904 | KITTY_LOGE("setSoftBreakpointAndWait(%p): Failed.", (void *)address); |
| 905 | pokeMem(address, bak_code.data(), bak_code.size()); |
| 906 | return res; |
| 907 | }; |
| 908 | |
| 909 | auto validate_trap = [this](const user_regs_struct ®s, uintptr_t trap_addr) -> bool { |
| 910 | uintptr_t pc = regs.KT_REG_PC; |
| 911 | uintptr_t max_range = KT_ALIGN_UP(trap_addr + sizeof(KittyTraceInsns::BRKP), sizeof(uintptr_t)); |
| 912 | if (!(pc >= trap_addr && pc <= max_range)) |
| 913 | { |
| 914 | siginfo_t si = {}; |
| 915 | getSignalInfo(&si); |
| 916 | return uintptr_t(si.si_addr) >= trap_addr && uintptr_t(si.si_addr) <= max_range; |
| 917 | } |
| 918 | return true; |
| 919 | }; |
| 920 | |
| 921 | again: |
| 922 | wp = 0; |
| 923 | status = 0; |
| 924 | memset(®s, 0, sizeof(regs)); |
| 925 | |
| 926 | if (!peekMem(address, bak_code.data(), bak_code.size())) |
| 927 | { |
| 928 | KITTY_LOGE("setSoftBreakpointAndWait(%p): Failed to backup memory code.", (void *)address); |
| 929 | return KT_BP_MEM_FAILED; |
| 930 | } |
| 931 | |
| 932 | #if defined(__arm__) |
| 933 | if (thumb) |
| 934 | memcpy(brk_code.data(), KittyTraceInsns::THUMB_BRKP, sizeof(KittyTraceInsns::THUMB_BRKP)); |
nothing calls this directly
no test coverage detected