1fcf9fc10SMark Johnston /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 35e53a4f9SPedro F. Giffuni * 48eb20f36SRui Paulo * Copyright (c) 2010 The FreeBSD Foundation 58eb20f36SRui Paulo * 68eb20f36SRui Paulo * This software was developed by Rui Paulo under sponsorship from the 78eb20f36SRui Paulo * FreeBSD Foundation. 88eb20f36SRui Paulo * 98eb20f36SRui Paulo * Redistribution and use in source and binary forms, with or without 108eb20f36SRui Paulo * modification, are permitted provided that the following conditions 118eb20f36SRui Paulo * are met: 128eb20f36SRui Paulo * 1. Redistributions of source code must retain the above copyright 138eb20f36SRui Paulo * notice, this list of conditions and the following disclaimer. 148eb20f36SRui Paulo * 2. Redistributions in binary form must reproduce the above copyright 158eb20f36SRui Paulo * notice, this list of conditions and the following disclaimer in the 168eb20f36SRui Paulo * documentation and/or other materials provided with the distribution. 178eb20f36SRui Paulo * 188eb20f36SRui Paulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 198eb20f36SRui Paulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 208eb20f36SRui Paulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 218eb20f36SRui Paulo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 228eb20f36SRui Paulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 238eb20f36SRui Paulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 248eb20f36SRui Paulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 258eb20f36SRui Paulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 268eb20f36SRui Paulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 278eb20f36SRui Paulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 288eb20f36SRui Paulo * SUCH DAMAGE. 298eb20f36SRui Paulo */ 308eb20f36SRui Paulo 318eb20f36SRui Paulo #include <sys/types.h> 328eb20f36SRui Paulo #include <sys/ptrace.h> 338eb20f36SRui Paulo 348eb20f36SRui Paulo #include <err.h> 358eb20f36SRui Paulo #include <stdio.h> 368eb20f36SRui Paulo #include <string.h> 378eb20f36SRui Paulo #include <errno.h> 38fcf9fc10SMark Johnston 398eb20f36SRui Paulo #include "_libproc.h" 408eb20f36SRui Paulo 418eb20f36SRui Paulo int 428eb20f36SRui Paulo proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue) 438eb20f36SRui Paulo { 448eb20f36SRui Paulo struct reg regs; 458eb20f36SRui Paulo 468eb20f36SRui Paulo if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || 478eb20f36SRui Paulo phdl->status == PS_IDLE) { 488eb20f36SRui Paulo errno = ENOENT; 498eb20f36SRui Paulo return (-1); 508eb20f36SRui Paulo } 518eb20f36SRui Paulo memset(®s, 0, sizeof(regs)); 528eb20f36SRui Paulo if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) 538eb20f36SRui Paulo return (-1); 548eb20f36SRui Paulo switch (reg) { 558eb20f36SRui Paulo case REG_PC: 5627e54fb5SRuslan Bukin #if defined(__aarch64__) 5727e54fb5SRuslan Bukin *regvalue = regs.elr; 5827e54fb5SRuslan Bukin #elif defined(__amd64__) 598eb20f36SRui Paulo *regvalue = regs.r_rip; 60fcb56067SGeorge V. Neville-Neil #elif defined(__arm__) 61fcb56067SGeorge V. Neville-Neil *regvalue = regs.r_pc; 628eb20f36SRui Paulo #elif defined(__i386__) 638eb20f36SRui Paulo *regvalue = regs.r_eip; 64c7570492SJustin Hibbits #elif defined(__powerpc__) 65c7570492SJustin Hibbits *regvalue = regs.pc; 66ca20f8ecSRuslan Bukin #elif defined(__riscv) 677dd3aed9SRuslan Bukin *regvalue = regs.sepc; 688eb20f36SRui Paulo #endif 698eb20f36SRui Paulo break; 708eb20f36SRui Paulo case REG_SP: 7127e54fb5SRuslan Bukin #if defined(__aarch64__) 7227e54fb5SRuslan Bukin *regvalue = regs.sp; 7327e54fb5SRuslan Bukin #elif defined(__amd64__) 748eb20f36SRui Paulo *regvalue = regs.r_rsp; 75fcb56067SGeorge V. Neville-Neil #elif defined(__arm__) 76fcb56067SGeorge V. Neville-Neil *regvalue = regs.r_sp; 778eb20f36SRui Paulo #elif defined(__i386__) 788eb20f36SRui Paulo *regvalue = regs.r_esp; 79c7570492SJustin Hibbits #elif defined(__powerpc__) 80c7570492SJustin Hibbits *regvalue = regs.fixreg[1]; 81ca20f8ecSRuslan Bukin #elif defined(__riscv) 827dd3aed9SRuslan Bukin *regvalue = regs.sp; 838eb20f36SRui Paulo #endif 848eb20f36SRui Paulo break; 858eb20f36SRui Paulo default: 8630e81f7eSMark Johnston DPRINTFX("ERROR: no support for reg number %d", reg); 878eb20f36SRui Paulo return (-1); 888eb20f36SRui Paulo } 898eb20f36SRui Paulo 908eb20f36SRui Paulo return (0); 918eb20f36SRui Paulo } 928eb20f36SRui Paulo 938eb20f36SRui Paulo int 948eb20f36SRui Paulo proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue) 958eb20f36SRui Paulo { 968eb20f36SRui Paulo struct reg regs; 978eb20f36SRui Paulo 988eb20f36SRui Paulo if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || 998eb20f36SRui Paulo phdl->status == PS_IDLE) { 1008eb20f36SRui Paulo errno = ENOENT; 1018eb20f36SRui Paulo return (-1); 1028eb20f36SRui Paulo } 1038eb20f36SRui Paulo if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) 1048eb20f36SRui Paulo return (-1); 1058eb20f36SRui Paulo switch (reg) { 1068eb20f36SRui Paulo case REG_PC: 10727e54fb5SRuslan Bukin #if defined(__aarch64__) 10827e54fb5SRuslan Bukin regs.elr = regvalue; 10927e54fb5SRuslan Bukin #elif defined(__amd64__) 1108eb20f36SRui Paulo regs.r_rip = regvalue; 111fcb56067SGeorge V. Neville-Neil #elif defined(__arm__) 112fcb56067SGeorge V. Neville-Neil regs.r_pc = regvalue; 1138eb20f36SRui Paulo #elif defined(__i386__) 1148eb20f36SRui Paulo regs.r_eip = regvalue; 115c7570492SJustin Hibbits #elif defined(__powerpc__) 116c7570492SJustin Hibbits regs.pc = regvalue; 117ca20f8ecSRuslan Bukin #elif defined(__riscv) 1187dd3aed9SRuslan Bukin regs.sepc = regvalue; 1198eb20f36SRui Paulo #endif 1208eb20f36SRui Paulo break; 1218eb20f36SRui Paulo case REG_SP: 12227e54fb5SRuslan Bukin #if defined(__aarch64__) 12327e54fb5SRuslan Bukin regs.sp = regvalue; 12427e54fb5SRuslan Bukin #elif defined(__amd64__) 1258eb20f36SRui Paulo regs.r_rsp = regvalue; 126fcb56067SGeorge V. Neville-Neil #elif defined(__arm__) 127fcb56067SGeorge V. Neville-Neil regs.r_sp = regvalue; 1288eb20f36SRui Paulo #elif defined(__i386__) 1298eb20f36SRui Paulo regs.r_esp = regvalue; 130c7570492SJustin Hibbits #elif defined(__powerpc__) 131c7570492SJustin Hibbits regs.fixreg[1] = regvalue; 132ca20f8ecSRuslan Bukin #elif defined(__riscv) 1337dd3aed9SRuslan Bukin regs.sp = regvalue; 1348eb20f36SRui Paulo #endif 1358eb20f36SRui Paulo break; 1368eb20f36SRui Paulo default: 13730e81f7eSMark Johnston DPRINTFX("ERROR: no support for reg number %d", reg); 1388eb20f36SRui Paulo return (-1); 1398eb20f36SRui Paulo } 1408eb20f36SRui Paulo if (ptrace(PT_SETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) 1418eb20f36SRui Paulo return (-1); 1428eb20f36SRui Paulo 1438eb20f36SRui Paulo return (0); 1448eb20f36SRui Paulo } 145