Index: stable/11/lib/libproc/_libproc.h =================================================================== --- stable/11/lib/libproc/_libproc.h (revision 316712) +++ stable/11/lib/libproc/_libproc.h (revision 316713) @@ -1,59 +1,61 @@ /*- * Copyright (c) 2008 John Birrell (jb@freebsd.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ -#include -#include +#ifndef __LIBPROC_H_ +#define __LIBPROC_H_ + #include -#include #include + #include #include "libproc.h" struct proc_handle { pid_t pid; /* Process ID. */ - int kq; /* Kernel event queue ID. */ int flags; /* Process flags. */ int status; /* Process status (PS_*). */ int wstat; /* Process wait status. */ rd_agent_t *rdap; /* librtld_db agent */ - rd_loadobj_t *rdobjs; - size_t rdobjsz; - size_t nobjs; - struct lwpstatus lwps; - rd_loadobj_t *rdexec; /* rdobj index of program executable. */ + rd_loadobj_t *rdobjs; /* Array of loaded objects. */ + size_t rdobjsz; /* Array size. */ + size_t nobjs; /* Num. objects currently loaded. */ + rd_loadobj_t *rdexec; /* rdobj for program executable. */ + struct lwpstatus lwps; /* Process status. */ char execname[MAXPATHLEN]; /* Path to program executable. */ }; #ifdef DEBUG #define DPRINTF(...) warn(__VA_ARGS__) #define DPRINTFX(...) warnx(__VA_ARGS__) #else #define DPRINTF(...) do { } while (0) #define DPRINTFX(...) do { } while (0) #endif + +#endif /* __LIBPROC_H_ */ Index: stable/11/lib/libproc/libproc.h =================================================================== --- stable/11/lib/libproc/libproc.h (revision 316712) +++ stable/11/lib/libproc/libproc.h (revision 316713) @@ -1,157 +1,157 @@ /*- * Copyright (c) 2010 The FreeBSD Foundation * Copyright (c) 2008 John Birrell (jb@freebsd.org) * All rights reserved. * * Portions of this software were developed by Rui Paulo under sponsorship * from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $FreeBSD$ */ #ifndef _LIBPROC_H_ #define _LIBPROC_H_ #include #include #include struct ctf_file; struct proc_handle; typedef void (*proc_child_func)(void *); /* Values returned by proc_state(). */ #define PS_IDLE 1 #define PS_STOP 2 #define PS_RUN 3 #define PS_UNDEAD 4 #define PS_DEAD 5 #define PS_LOST 6 /* Reason values for proc_detach(). */ #define PRELEASE_HANG 1 #define PRELEASE_KILL 2 typedef struct prmap { uintptr_t pr_vaddr; /* Virtual address. */ size_t pr_size; /* Mapping size in bytes */ size_t pr_offset; /* Mapping offset in object */ char pr_mapname[PATH_MAX]; /* Mapping filename */ uint8_t pr_mflags; /* Protection flags */ #define MA_READ 0x01 #define MA_WRITE 0x02 #define MA_EXEC 0x04 #define MA_COW 0x08 #define MA_NEEDS_COPY 0x10 #define MA_NOCOREDUMP 0x20 } prmap_t; typedef struct prsyminfo { u_int prs_lmid; /* Map id. */ u_int prs_id; /* Symbol id. */ } prsyminfo_t; typedef int proc_map_f(void *, const prmap_t *, const char *); typedef int proc_sym_f(void *, const GElf_Sym *, const char *); /* Values for ELF sections */ #define PR_SYMTAB 1 #define PR_DYNSYM 2 /* Values for the 'mask' parameter in the iteration functions */ #define BIND_LOCAL 0x0001 #define BIND_GLOBAL 0x0002 #define BIND_WEAK 0x0004 #define BIND_ANY (BIND_LOCAL|BIND_GLOBAL|BIND_WEAK) #define TYPE_NOTYPE 0x0100 #define TYPE_OBJECT 0x0200 #define TYPE_FUNC 0x0400 #define TYPE_SECTION 0x0800 #define TYPE_FILE 0x1000 #define TYPE_ANY (TYPE_NOTYPE|TYPE_OBJECT|TYPE_FUNC|TYPE_SECTION|\ TYPE_FILE) typedef enum { REG_PC, REG_SP, REG_RVAL1, REG_RVAL2 } proc_reg_t; #define SIG2STR_MAX 8 typedef struct lwpstatus { int pr_why; #define PR_REQUESTED 1 #define PR_FAULTED 2 #define PR_SYSENTRY 3 #define PR_SYSEXIT 4 #define PR_SIGNALLED 5 int pr_what; #define FLTBPT -1 } lwpstatus_t; /* Function prototype definitions. */ __BEGIN_DECLS prmap_t *proc_addr2map(struct proc_handle *, uintptr_t); prmap_t *proc_name2map(struct proc_handle *, const char *); char *proc_objname(struct proc_handle *, uintptr_t, char *, size_t); prmap_t *proc_obj2map(struct proc_handle *, const char *); int proc_iter_objs(struct proc_handle *, proc_map_f *, void *); int proc_iter_symbyaddr(struct proc_handle *, const char *, int, int, proc_sym_f *, void *); int proc_addr2sym(struct proc_handle *, uintptr_t, char *, size_t, GElf_Sym *); int proc_attach(pid_t pid, int flags, struct proc_handle **pphdl); int proc_continue(struct proc_handle *); int proc_clearflags(struct proc_handle *, int); int proc_create(const char *, char * const *, proc_child_func *, void *, struct proc_handle **); int proc_detach(struct proc_handle *, int); int proc_getflags(struct proc_handle *); int proc_name2sym(struct proc_handle *, const char *, const char *, GElf_Sym *, prsyminfo_t *); struct ctf_file *proc_name2ctf(struct proc_handle *, const char *); int proc_setflags(struct proc_handle *, int); int proc_state(struct proc_handle *); pid_t proc_getpid(struct proc_handle *); int proc_wstatus(struct proc_handle *); int proc_getwstat(struct proc_handle *); char * proc_signame(int, char *, size_t); int proc_read(struct proc_handle *, void *, size_t, size_t); const lwpstatus_t *proc_getlwpstatus(struct proc_handle *); void proc_free(struct proc_handle *); rd_agent_t *proc_rdagent(struct proc_handle *); void proc_updatesyms(struct proc_handle *); int proc_bkptset(struct proc_handle *, uintptr_t, unsigned long *); int proc_bkptdel(struct proc_handle *, uintptr_t, unsigned long); void proc_bkptregadj(unsigned long *); int proc_bkptexec(struct proc_handle *, unsigned long); int proc_regget(struct proc_handle *, proc_reg_t, unsigned long *); int proc_regset(struct proc_handle *, proc_reg_t, unsigned long); __END_DECLS -#endif /* !_LIBPROC_H_ */ +#endif /* _LIBPROC_H_ */ Index: stable/11/lib/libproc/proc_bkpt.c =================================================================== --- stable/11/lib/libproc/proc_bkpt.c (revision 316712) +++ stable/11/lib/libproc/proc_bkpt.c (revision 316713) @@ -1,262 +1,262 @@ -/* - * Copyright (c) 2010 The FreeBSD Foundation - * All rights reserved. - * +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ #include __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include #include #include + #include "_libproc.h" #if defined(__aarch64__) #define AARCH64_BRK 0xd4200000 #define AARCH64_BRK_IMM16_SHIFT 5 #define AARCH64_BRK_IMM16_VAL (0xd << AARCH64_BRK_IMM16_SHIFT) #define BREAKPOINT_INSTR (AARCH64_BRK | AARCH64_BRK_IMM16_VAL) #define BREAKPOINT_INSTR_SZ 4 #elif defined(__amd64__) || defined(__i386__) #define BREAKPOINT_INSTR 0xcc /* int 0x3 */ #define BREAKPOINT_INSTR_SZ 1 #define BREAKPOINT_ADJUST_SZ BREAKPOINT_INSTR_SZ #elif defined(__arm__) #define BREAKPOINT_INSTR 0xe7ffffff /* bkpt */ #define BREAKPOINT_INSTR_SZ 4 #elif defined(__mips__) #define BREAKPOINT_INSTR 0xd /* break */ #define BREAKPOINT_INSTR_SZ 4 #elif defined(__powerpc__) #define BREAKPOINT_INSTR 0x7fe00008 /* trap */ #define BREAKPOINT_INSTR_SZ 4 #elif defined(__riscv__) #define BREAKPOINT_INSTR 0x00100073 /* sbreak */ #define BREAKPOINT_INSTR_SZ 4 #else #error "Add support for your architecture" #endif static int proc_stop(struct proc_handle *phdl) { int status; if (kill(proc_getpid(phdl), SIGSTOP) == -1) { DPRINTF("kill %d", proc_getpid(phdl)); return (-1); } else if (waitpid(proc_getpid(phdl), &status, WSTOPPED) == -1) { DPRINTF("waitpid %d", proc_getpid(phdl)); return (-1); } else if (!WIFSTOPPED(status)) { DPRINTFX("waitpid: unexpected status 0x%x", status); return (-1); } return (0); } int proc_bkptset(struct proc_handle *phdl, uintptr_t address, unsigned long *saved) { struct ptrace_io_desc piod; unsigned long paddr, caddr; int ret = 0, stopped; *saved = 0; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || phdl->status == PS_IDLE) { errno = ENOENT; return (-1); } DPRINTFX("adding breakpoint at 0x%lx", address); stopped = 0; if (phdl->status != PS_STOP) { if (proc_stop(phdl) != 0) return (-1); stopped = 1; } /* * Read the original instruction. */ caddr = address; paddr = 0; piod.piod_op = PIOD_READ_I; piod.piod_offs = (void *)caddr; piod.piod_addr = &paddr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { - DPRINTF("ERROR: couldn't read instruction at address 0x%" - PRIuPTR, address); + DPRINTF("ERROR: couldn't read instruction at address 0x%jx", + (uintmax_t)address); ret = -1; goto done; } *saved = paddr; /* * Write a breakpoint instruction to that address. */ caddr = address; paddr = BREAKPOINT_INSTR; piod.piod_op = PIOD_WRITE_I; piod.piod_offs = (void *)caddr; piod.piod_addr = &paddr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { - DPRINTF("ERROR: couldn't write instruction at address 0x%" - PRIuPTR, address); + DPRINTF("ERROR: couldn't write instruction at address 0x%jx", + (uintmax_t)address); ret = -1; goto done; } done: if (stopped) /* Restart the process if we had to stop it. */ proc_continue(phdl); return (ret); } int proc_bkptdel(struct proc_handle *phdl, uintptr_t address, unsigned long saved) { struct ptrace_io_desc piod; unsigned long paddr, caddr; int ret = 0, stopped; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || phdl->status == PS_IDLE) { errno = ENOENT; return (-1); } DPRINTFX("removing breakpoint at 0x%lx", address); stopped = 0; if (phdl->status != PS_STOP) { if (proc_stop(phdl) != 0) return (-1); stopped = 1; } /* * Overwrite the breakpoint instruction that we setup previously. */ caddr = address; paddr = saved; piod.piod_op = PIOD_WRITE_I; piod.piod_offs = (void *)caddr; piod.piod_addr = &paddr; piod.piod_len = BREAKPOINT_INSTR_SZ; if (ptrace(PT_IO, proc_getpid(phdl), (caddr_t)&piod, 0) < 0) { - DPRINTF("ERROR: couldn't write instruction at address 0x%" - PRIuPTR, address); + DPRINTF("ERROR: couldn't write instruction at address 0x%jx", + (uintmax_t)address); ret = -1; } if (stopped) /* Restart the process if we had to stop it. */ proc_continue(phdl); - + return (ret); } /* * Decrement pc so that we delete the breakpoint at the correct * address, i.e. at the BREAKPOINT_INSTR address. * * This is only needed on some architectures where the pc value * when reading registers points at the instruction after the * breakpoint, e.g. x86. */ void proc_bkptregadj(unsigned long *pc) { (void)pc; #ifdef BREAKPOINT_ADJUST_SZ *pc = *pc - BREAKPOINT_ADJUST_SZ; #endif } /* * Step over the breakpoint. */ int proc_bkptexec(struct proc_handle *phdl, unsigned long saved) { unsigned long pc; unsigned long samesaved; int status; if (proc_regget(phdl, REG_PC, &pc) < 0) { DPRINTFX("ERROR: couldn't get PC register"); return (-1); } proc_bkptregadj(&pc); if (proc_bkptdel(phdl, pc, saved) < 0) { DPRINTFX("ERROR: couldn't delete breakpoint"); return (-1); } /* * Go back in time and step over the new instruction just * set up by proc_bkptdel(). */ proc_regset(phdl, REG_PC, pc); if (ptrace(PT_STEP, proc_getpid(phdl), (caddr_t)1, 0) < 0) { DPRINTFX("ERROR: ptrace step failed"); return (-1); } proc_wstatus(phdl); status = proc_getwstat(phdl); if (!WIFSTOPPED(status)) { DPRINTFX("ERROR: don't know why process stopped"); return (-1); } /* * Restore the breakpoint. The saved instruction should be * the same as the one that we were passed in. */ if (proc_bkptset(phdl, pc, &samesaved) < 0) { DPRINTFX("ERROR: couldn't restore breakpoint"); return (-1); } assert(samesaved == saved); return (0); } Index: stable/11/lib/libproc/proc_create.c =================================================================== --- stable/11/lib/libproc/proc_create.c (revision 316712) +++ stable/11/lib/libproc/proc_create.c (revision 316713) @@ -1,189 +1,190 @@ /*- * Copyright (c) 2008 John Birrell (jb@freebsd.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ + +#include +__FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include "_libproc.h" static int proc_init(pid_t, int, int, struct proc_handle *); static int proc_init(pid_t pid, int flags, int status, struct proc_handle *phdl) { int mib[4], error; size_t len; memset(phdl, 0, sizeof(*phdl)); phdl->pid = pid; phdl->flags = flags; phdl->status = status; mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PATHNAME; mib[3] = pid; len = sizeof(phdl->execname); if (sysctl(mib, 4, phdl->execname, &len, NULL, 0) != 0) { error = errno; DPRINTF("ERROR: cannot get pathname for child process %d", pid); return (error); } if (len == 0) phdl->execname[0] = '\0'; return (0); } int proc_attach(pid_t pid, int flags, struct proc_handle **pphdl) { struct proc_handle *phdl; int error = 0; int status; if (pid == 0 || pid == getpid()) return (EINVAL); /* * Allocate memory for the process handle, a structure containing * all things related to the process. */ if ((phdl = malloc(sizeof(struct proc_handle))) == NULL) return (ENOMEM); elf_version(EV_CURRENT); error = proc_init(pid, flags, PS_RUN, phdl); if (error != 0) goto out; if (ptrace(PT_ATTACH, phdl->pid, 0, 0) != 0) { error = errno; DPRINTF("ERROR: cannot ptrace child process %d", pid); goto out; } /* Wait for the child process to stop. */ if (waitpid(pid, &status, WUNTRACED) == -1) { error = errno; DPRINTF("ERROR: child process %d didn't stop as expected", pid); goto out; } /* Check for an unexpected status. */ if (WIFSTOPPED(status) == 0) DPRINTFX("ERROR: child process %d status 0x%x", pid, status); else phdl->status = PS_STOP; out: if (error) proc_free(phdl); else *pphdl = phdl; return (error); } int proc_create(const char *file, char * const *argv, proc_child_func *pcf, void *child_arg, struct proc_handle **pphdl) { struct proc_handle *phdl; int error = 0; int status; pid_t pid; /* * Allocate memory for the process handle, a structure containing * all things related to the process. */ if ((phdl = malloc(sizeof(struct proc_handle))) == NULL) return (ENOMEM); elf_version(EV_CURRENT); /* Fork a new process. */ if ((pid = vfork()) == -1) error = errno; else if (pid == 0) { /* The child expects to be traced. */ if (ptrace(PT_TRACE_ME, 0, 0, 0) != 0) _exit(1); if (pcf != NULL) (*pcf)(child_arg); /* Execute the specified file: */ execvp(file, argv); /* Couldn't execute the file. */ _exit(2); } else { /* The parent owns the process handle. */ error = proc_init(pid, 0, PS_IDLE, phdl); if (error != 0) goto bad; /* Wait for the child process to stop. */ if (waitpid(pid, &status, WUNTRACED) == -1) { error = errno; DPRINTF("ERROR: child process %d didn't stop as expected", pid); goto bad; } /* Check for an unexpected status. */ if (WIFSTOPPED(status) == 0) { error = errno; DPRINTFX("ERROR: child process %d status 0x%x", pid, status); goto bad; } else phdl->status = PS_STOP; } bad: if (error) proc_free(phdl); else *pphdl = phdl; return (error); } void proc_free(struct proc_handle *phdl) { free(phdl); } Index: stable/11/lib/libproc/proc_regs.c =================================================================== --- stable/11/lib/libproc/proc_regs.c (revision 316712) +++ stable/11/lib/libproc/proc_regs.c (revision 316713) @@ -1,153 +1,154 @@ -/* - * Copyright (c) 2010 The FreeBSD Foundation - * All rights reserved. - * +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include + #include "_libproc.h" int proc_regget(struct proc_handle *phdl, proc_reg_t reg, unsigned long *regvalue) { struct reg regs; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || phdl->status == PS_IDLE) { errno = ENOENT; return (-1); } memset(®s, 0, sizeof(regs)); if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) return (-1); switch (reg) { case REG_PC: #if defined(__aarch64__) *regvalue = regs.elr; #elif defined(__amd64__) *regvalue = regs.r_rip; #elif defined(__arm__) *regvalue = regs.r_pc; #elif defined(__i386__) *regvalue = regs.r_eip; #elif defined(__mips__) *regvalue = regs.r_regs[PC]; #elif defined(__powerpc__) *regvalue = regs.pc; #elif defined(__riscv__) *regvalue = regs.sepc; #endif break; case REG_SP: #if defined(__aarch64__) *regvalue = regs.sp; #elif defined(__amd64__) *regvalue = regs.r_rsp; #elif defined(__arm__) *regvalue = regs.r_sp; #elif defined(__i386__) *regvalue = regs.r_esp; #elif defined(__mips__) *regvalue = regs.r_regs[SP]; #elif defined(__powerpc__) *regvalue = regs.fixreg[1]; #elif defined(__riscv__) *regvalue = regs.sp; #endif break; default: DPRINTFX("ERROR: no support for reg number %d", reg); return (-1); } return (0); } int proc_regset(struct proc_handle *phdl, proc_reg_t reg, unsigned long regvalue) { struct reg regs; if (phdl->status == PS_DEAD || phdl->status == PS_UNDEAD || phdl->status == PS_IDLE) { errno = ENOENT; return (-1); } if (ptrace(PT_GETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) return (-1); switch (reg) { case REG_PC: #if defined(__aarch64__) regs.elr = regvalue; #elif defined(__amd64__) regs.r_rip = regvalue; #elif defined(__arm__) regs.r_pc = regvalue; #elif defined(__i386__) regs.r_eip = regvalue; #elif defined(__mips__) regs.r_regs[PC] = regvalue; #elif defined(__powerpc__) regs.pc = regvalue; #elif defined(__riscv__) regs.sepc = regvalue; #endif break; case REG_SP: #if defined(__aarch64__) regs.sp = regvalue; #elif defined(__amd64__) regs.r_rsp = regvalue; #elif defined(__arm__) regs.r_sp = regvalue; #elif defined(__i386__) regs.r_esp = regvalue; #elif defined(__mips__) regs.r_regs[PC] = regvalue; #elif defined(__powerpc__) regs.fixreg[1] = regvalue; #elif defined(__riscv__) regs.sp = regvalue; #endif break; default: DPRINTFX("ERROR: no support for reg number %d", reg); return (-1); } if (ptrace(PT_SETREGS, proc_getpid(phdl), (caddr_t)®s, 0) < 0) return (-1); return (0); } Index: stable/11/lib/libproc/proc_rtld.c =================================================================== --- stable/11/lib/libproc/proc_rtld.c (revision 316712) +++ stable/11/lib/libproc/proc_rtld.c (revision 316713) @@ -1,84 +1,84 @@ -/* - * Copyright (c) 2010 The FreeBSD Foundation - * All rights reserved. - * +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ #include __FBSDID("$FreeBSD$"); #include #include #include #include -#include "libproc.h" + #include "_libproc.h" static int map_iter(const rd_loadobj_t *lop, void *arg) { struct proc_handle *phdl = arg; if (phdl->nobjs >= phdl->rdobjsz) { phdl->rdobjsz *= 2; phdl->rdobjs = reallocf(phdl->rdobjs, sizeof(*phdl->rdobjs) * phdl->rdobjsz); if (phdl->rdobjs == NULL) return (-1); } if (strcmp(lop->rdl_path, phdl->execname) == 0 && (lop->rdl_prot & RD_RDL_X) != 0) phdl->rdexec = &phdl->rdobjs[phdl->nobjs]; memcpy(&phdl->rdobjs[phdl->nobjs++], lop, sizeof(*lop)); return (0); } rd_agent_t * proc_rdagent(struct proc_handle *phdl) { if (phdl->rdap == NULL && phdl->status != PS_UNDEAD && phdl->status != PS_IDLE) { if ((phdl->rdap = rd_new(phdl)) != NULL) { phdl->rdobjs = malloc(sizeof(*phdl->rdobjs) * 64); phdl->rdobjsz = 64; if (phdl->rdobjs == NULL) return (phdl->rdap); rd_loadobj_iter(phdl->rdap, map_iter, phdl); } } return (phdl->rdap); } void proc_updatesyms(struct proc_handle *phdl) { memset(phdl->rdobjs, 0, sizeof(*phdl->rdobjs) * phdl->rdobjsz); phdl->nobjs = 0; rd_loadobj_iter(phdl->rdap, map_iter, phdl); } Index: stable/11/lib/libproc/proc_util.c =================================================================== --- stable/11/lib/libproc/proc_util.c (revision 316712) +++ stable/11/lib/libproc/proc_util.c (revision 316713) @@ -1,230 +1,235 @@ /*- * Copyright (c) 2010 The FreeBSD Foundation * Copyright (c) 2008 John Birrell (jb@freebsd.org) * All rights reserved. - * + * * Portions of this software were developed by Rui Paulo under sponsorship * from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. - * - * $FreeBSD$ */ +#include +__FBSDID("$FreeBSD$"); + #include #include #include + #include #include #include #include #include + #include "_libproc.h" int proc_clearflags(struct proc_handle *phdl, int mask) { if (phdl == NULL) return (EINVAL); phdl->flags &= ~mask; return (0); } /* * NB: we return -1 as the Solaris libproc Psetrun() function. */ int proc_continue(struct proc_handle *phdl) { - int pending = 0; + int pending; if (phdl == NULL) return (-1); if (phdl->status == PS_STOP && WSTOPSIG(phdl->wstat) != SIGTRAP) pending = WSTOPSIG(phdl->wstat); + else + pending = 0; if (ptrace(PT_CONTINUE, phdl->pid, (caddr_t)(uintptr_t)1, pending) != 0) return (-1); phdl->status = PS_RUN; return (0); } int proc_detach(struct proc_handle *phdl, int reason) { int status; if (phdl == NULL) return (EINVAL); if (reason == PRELEASE_KILL) { kill(phdl->pid, SIGKILL); return (0); } if (ptrace(PT_DETACH, phdl->pid, 0, 0) != 0 && errno == ESRCH) return (0); if (errno == EBUSY) { kill(phdl->pid, SIGSTOP); waitpid(phdl->pid, &status, WUNTRACED); ptrace(PT_DETACH, phdl->pid, 0, 0); kill(phdl->pid, SIGCONT); return (0); } return (0); } int proc_getflags(struct proc_handle *phdl) { if (phdl == NULL) return (-1); - return(phdl->flags); + return (phdl->flags); } int proc_setflags(struct proc_handle *phdl, int mask) { if (phdl == NULL) return (EINVAL); phdl->flags |= mask; return (0); } int proc_state(struct proc_handle *phdl) { if (phdl == NULL) return (-1); return (phdl->status); } pid_t proc_getpid(struct proc_handle *phdl) { if (phdl == NULL) return (-1); return (phdl->pid); } int proc_wstatus(struct proc_handle *phdl) { int status; if (phdl == NULL) return (-1); if (waitpid(phdl->pid, &status, WUNTRACED) < 0) { if (errno != EINTR) DPRINTF("waitpid"); return (-1); } if (WIFSTOPPED(status)) phdl->status = PS_STOP; if (WIFEXITED(status) || WIFSIGNALED(status)) phdl->status = PS_UNDEAD; phdl->wstat = status; return (phdl->status); } int proc_getwstat(struct proc_handle *phdl) { if (phdl == NULL) return (-1); return (phdl->wstat); } char * proc_signame(int sig, char *name, size_t namesz) { strlcpy(name, strsignal(sig), namesz); return (name); } int proc_read(struct proc_handle *phdl, void *buf, size_t size, size_t addr) { struct ptrace_io_desc piod; if (phdl == NULL) return (-1); piod.piod_op = PIOD_READ_D; piod.piod_len = size; piod.piod_addr = (void *)buf; piod.piod_offs = (void *)addr; if (ptrace(PT_IO, phdl->pid, (caddr_t)&piod, 0) < 0) return (-1); return (piod.piod_len); } const lwpstatus_t * proc_getlwpstatus(struct proc_handle *phdl) { struct ptrace_lwpinfo lwpinfo; lwpstatus_t *psp = &phdl->lwps; siginfo_t *siginfo; if (phdl == NULL) return (NULL); if (ptrace(PT_LWPINFO, phdl->pid, (caddr_t)&lwpinfo, sizeof(lwpinfo)) < 0) return (NULL); siginfo = &lwpinfo.pl_siginfo; if (lwpinfo.pl_event == PL_EVENT_SIGNAL && (lwpinfo.pl_flags & PL_FLAG_SI) != 0) { if (siginfo->si_signo == SIGTRAP && (siginfo->si_code == TRAP_BRKPT || siginfo->si_code == TRAP_TRACE)) { psp->pr_why = PR_FAULTED; psp->pr_what = FLTBPT; } else { psp->pr_why = PR_SIGNALLED; psp->pr_what = siginfo->si_signo; } } else if (lwpinfo.pl_flags & PL_FLAG_SCE) { psp->pr_why = PR_SYSENTRY; } else if (lwpinfo.pl_flags & PL_FLAG_SCX) { psp->pr_why = PR_SYSEXIT; } return (psp); } Index: stable/11/lib/librtld_db/rtld_db.c =================================================================== --- stable/11/lib/librtld_db/rtld_db.c (revision 316712) +++ stable/11/lib/librtld_db/rtld_db.c (revision 316713) @@ -1,254 +1,254 @@ -/* - * Copyright (c) 2010 The FreeBSD Foundation - * All rights reserved. - * +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); -#include -#include +#include +#include #include #include #include #include #include #include #include #include #include "rtld_db.h" static int _librtld_db_debug = 0; #define DPRINTF(...) do { \ if (_librtld_db_debug) { \ fprintf(stderr, "librtld_db: DEBUG: "); \ fprintf(stderr, __VA_ARGS__); \ } \ } while (0) void rd_delete(rd_agent_t *rdap) { free(rdap); } const char * rd_errstr(rd_err_e rderr) { switch (rderr) { case RD_ERR: return "generic error"; case RD_OK: return "no error"; case RD_NOCAPAB: return "capability not supported"; case RD_DBERR: return "database error"; case RD_NOBASE: return "NOBASE"; case RD_NOMAPS: return "NOMAPS"; default: return "unknown error"; } } rd_err_e rd_event_addr(rd_agent_t *rdap, rd_event_e event, rd_notify_t *notify) { rd_err_e ret; DPRINTF("%s rdap %p event %d notify %p\n", __func__, rdap, event, notify); ret = RD_OK; switch (event) { case RD_NONE: break; case RD_PREINIT: notify->type = RD_NOTIFY_BPT; notify->u.bptaddr = rdap->rda_preinit_addr; break; case RD_POSTINIT: notify->type = RD_NOTIFY_BPT; notify->u.bptaddr = rdap->rda_postinit_addr; break; case RD_DLACTIVITY: notify->type = RD_NOTIFY_BPT; notify->u.bptaddr = rdap->rda_dlactivity_addr; break; default: ret = RD_ERR; break; } return (ret); } rd_err_e rd_event_enable(rd_agent_t *rdap __unused, int onoff) { DPRINTF("%s onoff %d\n", __func__, onoff); return (RD_OK); } rd_err_e rd_event_getmsg(rd_agent_t *rdap __unused, rd_event_msg_t *msg) { DPRINTF("%s\n", __func__); msg->type = RD_POSTINIT; msg->u.state = RD_CONSISTENT; return (RD_OK); } rd_err_e rd_init(int version) { char *debug = NULL; if (version == RD_VERSION) { debug = getenv("LIBRTLD_DB_DEBUG"); _librtld_db_debug = debug ? atoi(debug) : 0; return (RD_OK); } else return (RD_NOCAPAB); } rd_err_e rd_loadobj_iter(rd_agent_t *rdap, rl_iter_f *cb, void *clnt_data) { int cnt, i, lastvn = 0; rd_loadobj_t rdl; struct kinfo_vmentry *kves, *kve; DPRINTF("%s\n", __func__); - if ((kves = kinfo_getvmmap(proc_getpid(rdap->rda_php), &cnt)) == NULL) { + if ((kves = kinfo_getvmmap(proc_getpid(rdap->rda_php), &cnt)) == NULL) { warn("ERROR: kinfo_getvmmap() failed"); return (RD_ERR); } for (i = 0; i < cnt; i++) { kve = kves + i; if (kve->kve_type == KVME_TYPE_VNODE) lastvn = i; memset(&rdl, 0, sizeof(rdl)); /* * Map the kinfo_vmentry struct to the rd_loadobj structure. */ rdl.rdl_saddr = kve->kve_start; rdl.rdl_eaddr = kve->kve_end; rdl.rdl_offset = kve->kve_offset; if (kve->kve_protection & KVME_PROT_READ) rdl.rdl_prot |= RD_RDL_R; if (kve->kve_protection & KVME_PROT_WRITE) rdl.rdl_prot |= RD_RDL_W; if (kve->kve_protection & KVME_PROT_EXEC) rdl.rdl_prot |= RD_RDL_X; strlcpy(rdl.rdl_path, kves[lastvn].kve_path, sizeof(rdl.rdl_path)); (*cb)(&rdl, clnt_data); } free(kves); return (RD_OK); } void rd_log(const int onoff) { DPRINTF("%s\n", __func__); (void)onoff; } rd_agent_t * rd_new(struct proc_handle *php) { rd_agent_t *rdap; rdap = malloc(sizeof(rd_agent_t)); if (rdap) { memset(rdap, 0, sizeof(rd_agent_t)); rdap->rda_php = php; rd_reset(rdap); } return (rdap); } rd_err_e rd_objpad_enable(rd_agent_t *rdap, size_t padsize) { DPRINTF("%s\n", __func__); (void)rdap; (void)padsize; return (RD_ERR); } rd_err_e rd_plt_resolution(rd_agent_t *rdap, uintptr_t pc, struct proc *proc, uintptr_t plt_base, rd_plt_info_t *rpi) { DPRINTF("%s\n", __func__); (void)rdap; (void)pc; (void)proc; (void)plt_base; (void)rpi; return (RD_ERR); } rd_err_e rd_reset(rd_agent_t *rdap) { GElf_Sym sym; if (proc_name2sym(rdap->rda_php, "ld-elf.so.1", "r_debug_state", &sym, NULL) < 0) return (RD_ERR); DPRINTF("found r_debug_state at 0x%lx\n", (unsigned long)sym.st_value); rdap->rda_preinit_addr = sym.st_value; rdap->rda_dlactivity_addr = sym.st_value; if (proc_name2sym(rdap->rda_php, "ld-elf.so.1", "_r_debug_postinit", &sym, NULL) < 0) return (RD_ERR); DPRINTF("found _r_debug_postinit at 0x%lx\n", (unsigned long)sym.st_value); rdap->rda_postinit_addr = sym.st_value; return (RD_OK); } Index: stable/11/lib/librtld_db/rtld_db.h =================================================================== --- stable/11/lib/librtld_db/rtld_db.h (revision 316712) +++ stable/11/lib/librtld_db/rtld_db.h (revision 316713) @@ -1,152 +1,152 @@ -/* - * Copyright (c) 2010 The FreeBSD Foundation - * All rights reserved. - * +/*- + * Copyright (c) 2010 The FreeBSD Foundation + * All rights reserved. + * * This software was developed by Rui Paulo under sponsorship from the - * FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * FreeBSD Foundation. * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * * $FreeBSD$ - */ + */ #ifndef _RTLD_DB_H_ #define _RTLD_DB_H_ #include #include #include #define RD_VERSION 1 typedef enum { RD_OK, RD_ERR, RD_DBERR, RD_NOCAPAB, RD_NODYNAM, RD_NOBASE, RD_NOMAPS } rd_err_e; typedef struct rd_agent { struct proc_handle *rda_php; uintptr_t rda_dlactivity_addr; uintptr_t rda_preinit_addr; uintptr_t rda_postinit_addr; } rd_agent_t; typedef struct rd_loadobj { uintptr_t rdl_saddr; /* start address */ uintptr_t rdl_eaddr; /* end address */ uint32_t rdl_offset; uint8_t rdl_prot; #define RD_RDL_R 0x01 #define RD_RDL_W 0x02 #define RD_RDL_X 0x04 enum { RDL_TYPE_NONE = 0, RDL_TYPE_DEF, RDL_TYPE_VNODE, RDL_TYPE_SWAP, RDL_TYPE_DEV, /* XXX some types missing */ RDL_TYPE_UNKNOWN = 255 } rdl_type; unsigned char rdl_path[PATH_MAX]; } rd_loadobj_t; typedef enum { RD_NONE = 0, RD_PREINIT, RD_POSTINIT, RD_DLACTIVITY } rd_event_e; typedef enum { RD_NOTIFY_BPT, RD_NOTIFY_AUTOBPT, RD_NOTIFY_SYSCALL } rd_notify_e; typedef struct rd_notify { rd_notify_e type; union { uintptr_t bptaddr; long syscallno; } u; } rd_notify_t; typedef enum { RD_NOSTATE = 0, RD_CONSISTENT, RD_ADD, RD_DELETE } rd_state_e; typedef struct rd_event_msg { rd_event_e type; union { rd_state_e state; } u; } rd_event_msg_t; typedef enum { RD_RESOLVE_NONE, RD_RESOLVE_STEP, RD_RESOLVE_TARGET, RD_RESOLVE_TARGET_STEP } rd_skip_e; typedef struct rd_plt_info { rd_skip_e pi_skip_method; long pi_nstep; uintptr_t pi_target; uintptr_t pi_baddr; unsigned int pi_flags; } rd_plt_info_t; #define RD_FLG_PI_PLTBOUND 0x0001 __BEGIN_DECLS struct proc_handle; void rd_delete(rd_agent_t *); const char *rd_errstr(rd_err_e); rd_err_e rd_event_addr(rd_agent_t *, rd_event_e, rd_notify_t *); rd_err_e rd_event_enable(rd_agent_t *, int); rd_err_e rd_event_getmsg(rd_agent_t *, rd_event_msg_t *); rd_err_e rd_init(int); typedef int rl_iter_f(const rd_loadobj_t *, void *); rd_err_e rd_loadobj_iter(rd_agent_t *, rl_iter_f *, void *); void rd_log(const int); rd_agent_t *rd_new(struct proc_handle *); rd_err_e rd_objpad_enable(rd_agent_t *, size_t); struct proc; rd_err_e rd_plt_resolution(rd_agent_t *, uintptr_t, struct proc *, uintptr_t, rd_plt_info_t *); rd_err_e rd_reset(rd_agent_t *); __END_DECLS #endif /* _RTLD_DB_H_ */ Index: stable/11 =================================================================== --- stable/11 (revision 316712) +++ stable/11 (revision 316713) Property changes on: stable/11 ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head:r303532,309591