Index: stable/7/usr.bin/kdump/Makefile =================================================================== --- stable/7/usr.bin/kdump/Makefile (revision 220267) +++ stable/7/usr.bin/kdump/Makefile (revision 220268) @@ -1,18 +1,32 @@ # @(#)Makefile 8.1 (Berkeley) 6/6/93 # $FreeBSD$ +.if (${MACHINE_ARCH} == "amd64") +SFX= 32 +.endif + .PATH: ${.CURDIR}/../ktrace PROG= kdump SRCS= kdump.c ioctl.c kdump_subr.c subr.c CFLAGS+= -I${.CURDIR}/../ktrace -I${.CURDIR} -I${.CURDIR}/../.. -CLEANFILES= ioctl.c kdump_subr.c +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" +SRCS+= linux_syscalls.c +.endif +CLEANFILES= ioctl.c kdump_subr.c linux_syscalls.c + ioctl.c: mkioctls sh ${.CURDIR}/mkioctls ${DESTDIR}/usr/include > ${.TARGET} kdump_subr.c: mksubr sh ${.CURDIR}/mksubr ${DESTDIR}/usr/include > ${.TARGET} + +linux_syscalls.c: + /bin/sh ${.CURDIR}/../../sys/kern/makesyscalls.sh \ + ${.CURDIR}/../../sys/${MACHINE_ARCH}/linux${SFX}/syscalls.master ${.CURDIR}/linux_syscalls.conf + echo "int nlinux_syscalls = sizeof(linux_syscallnames) / sizeof(linux_syscallnames[0]);" \ + >> linux_syscalls.c .include Index: stable/7/usr.bin/kdump/kdump.1 =================================================================== --- stable/7/usr.bin/kdump/kdump.1 (revision 220267) +++ stable/7/usr.bin/kdump/kdump.1 (revision 220268) @@ -1,183 +1,185 @@ .\" Copyright (c) 1990, 1993 .\" The Regents of the University of California. 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. .\" 3. All advertising materials mentioning features or use of this software .\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. .\" .\" @(#)kdump.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" .Dd February 23, 2008 .Dt KDUMP 1 .Os .Sh NAME .Nm kdump .Nd display kernel trace data .Sh SYNOPSIS .Nm -.Op Fl dEnlHRsT +.Op Fl dEnlHRsTA .Op Fl f Ar trfile .Op Fl m Ar maxdata .Op Fl p Ar pid .Op Fl t Ar trstr .Sh DESCRIPTION The .Nm command displays the kernel trace files produced with .Xr ktrace 1 in human readable format. By default, the file .Pa ktrace.out in the current directory is displayed. .Pp The options are as follows: .Bl -tag -width Fl .It Fl d Display all numbers in decimal. .It Fl E Display elapsed timestamps (time since beginning of trace). .It Fl f Ar trfile Display the specified file instead of .Pa ktrace.out . .It Fl H List the thread ID (tid) of the thread with each trace record, if available. If no thread ID is available, 0 will be printed. .It Fl l Loop reading the trace file, once the end-of-file is reached, waiting for more data. .It Fl m Ar maxdata Display at most .Ar maxdata bytes when decoding .Tn I/O . .It Fl n Suppress ad hoc translations. Normally .Nm tries to decode many system calls into a more human readable format. For example, .Xr ioctl 2 values are replaced with the macro name and .Va errno values are replaced with the .Xr strerror 3 string. Suppressing this feature yields a more consistent output format and is easily amenable to further processing. .It Fl p Ar pid Display only trace events that correspond to the process .Ar pid . This may be useful when there are multiple processes recorded in the same trace file. .It Fl R Display relative timestamps (time since previous entry). .It Fl r When decoding STRU records, display structure members such as UIDs, GIDs, dates etc. symbolically instead of numerically. .It Fl s Suppress display of I/O data. .It Fl T Display absolute timestamps for each entry (seconds since epoch). +.It Fl A +Display description of the ABI of traced process. .It Fl t Ar trstr See the .Fl t option of .Xr ktrace 1 . .El .Pp The output format of .Nm is line oriented with several fields. The example below shows a section of a kdump generated by the following commands: .Bd -literal -offset indent ?> ktrace echo "ktrace" ?> kdump 85045 echo CALL writev(0x1,0x804b030,0x2) 85045 echo GIO fd 1 wrote 7 bytes "ktrace " 85045 echo RET writev 7 .Ed .Pp The first field is the PID of the process being traced. The second field is the name of the program being traced. The third field is the operation that the kernel performed on behalf of the process. If thread IDs are being printed, then an additional thread ID column will be added to the output between the PID field and program name field. .Pp In the first line above, the kernel executes the .Xr writev 2 system call on behalf of the process so this is a .Li CALL operation. The fourth field shows the system call that was executed, including its arguments. The .Xr writev 2 system call takes a file descriptor, in this case 1, or standard output, then a pointer to the iovector to write, and the number of iovectors that are to be written. In the second line we see the operation was .Li GIO , for general I/O, and that file descriptor 1 had seven bytes written to it. This is followed by the seven bytes that were written, the string .Qq Li ktrace with a carriage return and line feed. The last line is the .Li RET operation, showing a return from the kernel, what system call we are returning from, and the return value that the process received. Seven bytes were written by the .Xr writev 2 system call, so 7 is the return value. .Pp The possible operations are: .Bl -column -offset indent ".Li CALL" ".No data from user process" .It Sy Name Ta Sy Operation Ta Sy Fourth field .It Li CALL Ta enter syscall Ta syscall name and arguments .It Li RET Ta return from syscall Ta syscall name and return value .It Li NAMI Ta file name lookup Ta path to file .It Li GIO Ta general I/O Ta fd, read/write, number of bytes .It Li PSIG Ta signal Ta signal name, handler, mask, code .It Li CSW Ta context switch Ta stop/resume user/kernel .It Li USER Ta data from user process Ta the data .It Li STRU Ta various syscalls Ta structure .It Li SCTL Ta Xr sysctl 3 requests Ta MIB name .El .Sh SEE ALSO .Xr ktrace 1 .Sh HISTORY The .Nm command appeared in .Bx 4.4 . Index: stable/7/usr.bin/kdump/kdump.c =================================================================== --- stable/7/usr.bin/kdump/kdump.c (revision 220267) +++ stable/7/usr.bin/kdump/kdump.c (revision 220268) @@ -1,1377 +1,1578 @@ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #ifndef lint static const char copyright[] = "@(#) Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint #if 0 static char sccsid[] = "@(#)kdump.c 8.1 (Berkeley) 6/6/93"; #endif #endif /* not lint */ #include __FBSDID("$FreeBSD$"); #define _KERNEL extern int errno; #include #undef _KERNEL #include #include #define _KERNEL #include #undef _KERNEL #include #include #include #include #include +#include #include +#include #ifdef IPX #include #include #endif #ifdef NETATALK #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ktrace.h" #include "kdump_subr.h" +u_int abidump(struct ktr_header *); +int fetchprocinfo(struct ktr_header *, u_int *); int fread_tail(void *, int, int); void dumpheader(struct ktr_header *); -void ktrsyscall(struct ktr_syscall *); -void ktrsysret(struct ktr_sysret *); +void ktrsyscall(struct ktr_syscall *, u_int); +void ktrsysret(struct ktr_sysret *, u_int); void ktrnamei(char *, int); void hexdump(char *, int, int); void visdump(char *, int, int); void ktrgenio(struct ktr_genio *, int); void ktrpsig(struct ktr_psig *); void ktrcsw(struct ktr_csw *); void ktruser(int, unsigned char *); void ktrsockaddr(struct sockaddr *); void ktrstat(struct stat *); void ktrstruct(char *, size_t); void usage(void); const char *ioctlname(u_long); int timestamp, decimal, fancy = 1, suppressdata, tail, threads, maxdata, - resolv = 0; + resolv = 0, abiflag = 0; const char *tracefile = DEF_TRACEFILE; struct ktr_header ktr_header; #define TIME_FORMAT "%b %e %T %Y" #define eqs(s1, s2) (strcmp((s1), (s2)) == 0) +#define print_number(i,n,c) do { \ + if (decimal) \ + printf("%c%ld", c, (long)*i); \ + else \ + printf("%c%#lx", c, (long)*i); \ + i++; \ + n--; \ + c = ','; \ + } while (0); + +#if defined(__amd64__) || defined(__i386__) + +void linux_ktrsyscall(struct ktr_syscall *); +void linux_ktrsysret(struct ktr_sysret *); +extern char *linux_syscallnames[]; +extern int nlinux_syscalls; + +/* + * from linux.h + * Linux syscalls return negative errno's, we do positive and map them + */ +static int bsd_to_linux_errno[ELAST + 1] = { + -0, -1, -2, -3, -4, -5, -6, -7, -8, -9, + -10, -35, -12, -13, -14, -15, -16, -17, -18, -19, + -20, -21, -22, -23, -24, -25, -26, -27, -28, -29, + -30, -31, -32, -33, -34, -11,-115,-114, -88, -89, + -90, -91, -92, -93, -94, -95, -96, -97, -98, -99, + -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, + -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, + -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, + -6, -6, -43, -42, -75,-125, -84, -95, -16, -74, + -72, -67, -71 +}; +#endif + +struct proc_info +{ + TAILQ_ENTRY(proc_info) info; + u_int sv_flags; + pid_t pid; +}; + +TAILQ_HEAD(trace_procs, proc_info) trace_procs; + int main(int argc, char *argv[]) { int ch, ktrlen, size; void *m; int trpoints = ALL_POINTS; int drop_logged; pid_t pid = 0; + u_int sv_flags; (void) setlocale(LC_CTYPE, ""); - while ((ch = getopt(argc,argv,"f:dElm:np:HRrsTt:")) != -1) + while ((ch = getopt(argc,argv,"f:dElm:np:AHRrsTt:")) != -1) switch((char)ch) { + case 'A': + abiflag = 1; + break; case 'f': tracefile = optarg; break; case 'd': decimal = 1; break; case 'l': tail = 1; break; case 'm': maxdata = atoi(optarg); break; case 'n': fancy = 0; break; case 'p': pid = atoi(optarg); break; case 'r': resolv = 1; break; case 's': suppressdata = 1; break; case 'E': timestamp = 3; /* elapsed timestamp */ break; case 'H': threads = 1; break; case 'R': timestamp = 2; /* relative timestamp */ break; case 'T': timestamp = 1; break; case 't': trpoints = getpoints(optarg); if (trpoints < 0) errx(1, "unknown trace point in %s", optarg); break; default: usage(); } if (argc > optind) usage(); m = (void *)malloc(size = 1025); if (m == NULL) errx(1, "%s", strerror(ENOMEM)); if (!freopen(tracefile, "r", stdin)) err(1, "%s", tracefile); + TAILQ_INIT(&trace_procs); drop_logged = 0; while (fread_tail(&ktr_header, sizeof(struct ktr_header), 1)) { if (ktr_header.ktr_type & KTR_DROP) { ktr_header.ktr_type &= ~KTR_DROP; if (!drop_logged && threads) { (void)printf( "%6jd %6jd %-8.*s Events dropped.\n", (intmax_t)ktr_header.ktr_pid, ktr_header.ktr_tid > 0 ? (intmax_t)ktr_header.ktr_tid : 0, MAXCOMLEN, ktr_header.ktr_comm); drop_logged = 1; } else if (!drop_logged) { (void)printf("%6jd %-8.*s Events dropped.\n", (intmax_t)ktr_header.ktr_pid, MAXCOMLEN, ktr_header.ktr_comm); drop_logged = 1; } } if (trpoints & (1< size) { m = (void *)realloc(m, ktrlen+1); if (m == NULL) errx(1, "%s", strerror(ENOMEM)); size = ktrlen; } if (ktrlen && fread_tail(m, ktrlen, 1) == 0) errx(1, "data too short"); + if (fetchprocinfo(&ktr_header, (u_int *)m) != 0) + continue; + sv_flags = abidump(&ktr_header); if (pid && ktr_header.ktr_pid != pid) continue; if ((trpoints & (1<ktr_type) { + case KTR_PROCCTOR: + TAILQ_FOREACH(pi, &trace_procs, info) { + if (pi->pid == kth->ktr_pid) { + TAILQ_REMOVE(&trace_procs, pi, info); + break; + } + } + pi = malloc(sizeof(struct proc_info)); + if (pi == NULL) + errx(1, "%s", strerror(ENOMEM)); + pi->sv_flags = *flags; + pi->pid = kth->ktr_pid; + TAILQ_INSERT_TAIL(&trace_procs, pi, info); + return (1); + + case KTR_PROCDTOR: + TAILQ_FOREACH(pi, &trace_procs, info) { + if (pi->pid == kth->ktr_pid) { + TAILQ_REMOVE(&trace_procs, pi, info); + free(pi); + break; + } + } + return (1); + } + + return (0); +} + +u_int +abidump(struct ktr_header *kth) +{ + struct proc_info *pi; + const char *abi; + const char *arch; + u_int flags = 0; + + TAILQ_FOREACH(pi, &trace_procs, info) { + if (pi->pid == kth->ktr_pid) { + flags = pi->sv_flags; + break; + } + } + + if (abiflag == 0) + return (flags); + + switch (flags & SV_ABI_MASK) { + case SV_ABI_LINUX: + abi = "L"; + break; + case SV_ABI_FREEBSD: + abi = "F"; + break; + default: + abi = "U"; + break; + } + + if (flags != 0) { + if (flags & SV_LP64) + arch = "64"; + else + arch = "32"; + } else + arch = "00"; + + printf("%s%s ", abi, arch); + + return (flags); +} + void dumpheader(struct ktr_header *kth) { static char unknown[64]; static struct timeval prevtime, temp; const char *type; switch (kth->ktr_type) { case KTR_SYSCALL: type = "CALL"; break; case KTR_SYSRET: type = "RET "; break; case KTR_NAMEI: type = "NAMI"; break; case KTR_GENIO: type = "GIO "; break; case KTR_PSIG: type = "PSIG"; break; case KTR_CSW: type = "CSW "; break; case KTR_USER: type = "USER"; break; case KTR_STRUCT: type = "STRU"; break; case KTR_SYSCTL: type = "SCTL"; break; + case KTR_PROCCTOR: + /* FALLTHROUGH */ + case KTR_PROCDTOR: + return; default: (void)sprintf(unknown, "UNKNOWN(%d)", kth->ktr_type); type = unknown; } /* * The ktr_tid field was previously the ktr_buffer field, which held * the kernel pointer value for the buffer associated with data * following the record header. It now holds a threadid, but only * for trace files after the change. Older trace files still contain * kernel pointers. Detect this and suppress the results by printing * negative tid's as 0. */ if (threads) (void)printf("%6jd %6jd %-8.*s ", (intmax_t)kth->ktr_pid, kth->ktr_tid > 0 ? (intmax_t)kth->ktr_tid : 0, MAXCOMLEN, kth->ktr_comm); else (void)printf("%6jd %-8.*s ", (intmax_t)kth->ktr_pid, MAXCOMLEN, kth->ktr_comm); if (timestamp) { if (timestamp == 3) { if (prevtime.tv_sec == 0) prevtime = kth->ktr_time; timevalsub(&kth->ktr_time, &prevtime); } if (timestamp == 2) { temp = kth->ktr_time; timevalsub(&kth->ktr_time, &prevtime); prevtime = temp; } (void)printf("%jd.%06ld ", (intmax_t)kth->ktr_time.tv_sec, kth->ktr_time.tv_usec); } (void)printf("%s ", type); } #include #define KTRACE #include #undef KTRACE int nsyscalls = sizeof (syscallnames) / sizeof (syscallnames[0]); void -ktrsyscall(struct ktr_syscall *ktr) +ktrsyscall(struct ktr_syscall *ktr, u_int flags) { int narg = ktr->ktr_narg; register_t *ip; - if (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0) + if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || + (ktr->ktr_code >= nsyscalls || ktr->ktr_code < 0)) (void)printf("[%d]", ktr->ktr_code); else (void)printf("%s", syscallnames[ktr->ktr_code]); ip = &ktr->ktr_args[0]; if (narg) { char c = '('; - if (fancy) { - -#define print_number(i,n,c) do { \ - if (decimal) \ - (void)printf("%c%ld", c, (long)*i); \ - else \ - (void)printf("%c%#lx", c, (long)*i); \ - i++; \ - n--; \ - c = ','; \ - } while (0); - + if (fancy && + (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) { if (ktr->ktr_code == SYS_ioctl) { const char *cp; print_number(ip,narg,c); if ((cp = ioctlname(*ip)) != NULL) (void)printf(",%s", cp); else { if (decimal) (void)printf(",%ld", (long)*ip); else (void)printf(",%#lx ", (long)*ip); } c = ','; ip++; narg--; } else if (ktr->ktr_code == SYS_ptrace) { (void)putchar('('); ptraceopname ((int)*ip); c = ','; ip++; narg--; } else if (ktr->ktr_code == SYS_access || ktr->ktr_code == SYS_eaccess) { print_number(ip,narg,c); (void)putchar(','); accessmodename ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_open) { int flags; int mode; print_number(ip,narg,c); flags = *ip; mode = *++ip; (void)putchar(','); flagsandmodename (flags, mode, decimal); ip++; narg-=2; } else if (ktr->ktr_code == SYS_wait4) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); wait4optname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_chmod || ktr->ktr_code == SYS_fchmod || ktr->ktr_code == SYS_lchmod) { print_number(ip,narg,c); (void)putchar(','); modename ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_mknod) { print_number(ip,narg,c); (void)putchar(','); modename ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_getfsstat) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); getfsstatflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_mount) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); mountflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_unmount) { print_number(ip,narg,c); (void)putchar(','); mountflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_recvmsg || ktr->ktr_code == SYS_sendmsg) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); sendrecvflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_recvfrom || ktr->ktr_code == SYS_sendto) { print_number(ip,narg,c); print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); sendrecvflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_chflags || ktr->ktr_code == SYS_fchflags || ktr->ktr_code == SYS_lchflags) { print_number(ip,narg,c); (void)putchar(','); modename((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_kill) { print_number(ip,narg,c); (void)putchar(','); signame((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_reboot) { (void)putchar('('); rebootoptname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_umask) { (void)putchar('('); modename((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_msync) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); msyncflagsname((int)*ip); ip++; narg--; #ifdef SYS_freebsd6_mmap } else if (ktr->ktr_code == SYS_freebsd6_mmap) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); mmapprotname ((int)*ip); (void)putchar(','); ip++; narg--; mmapflagsname ((int)*ip); ip++; narg--; #endif } else if (ktr->ktr_code == SYS_mmap) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); mmapprotname ((int)*ip); (void)putchar(','); ip++; narg--; mmapflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_mprotect) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); mmapprotname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_madvise) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); madvisebehavname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_setpriority) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); prioname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_fcntl) { int cmd; int arg; print_number(ip,narg,c); cmd = *ip; arg = *++ip; (void)putchar(','); fcntlcmdname(cmd, arg, decimal); ip++; narg-=2; } else if (ktr->ktr_code == SYS_socket) { int sockdomain; (void)putchar('('); sockdomain=(int)*ip; sockdomainname(sockdomain); ip++; narg--; (void)putchar(','); socktypename((int)*ip); ip++; narg--; if (sockdomain == PF_INET || sockdomain == PF_INET6) { (void)putchar(','); sockipprotoname((int)*ip); ip++; narg--; } c = ','; } else if (ktr->ktr_code == SYS_setsockopt || ktr->ktr_code == SYS_getsockopt) { print_number(ip,narg,c); (void)putchar(','); sockoptlevelname((int)*ip, decimal); if ((int)*ip == SOL_SOCKET) { ip++; narg--; (void)putchar(','); sockoptname((int)*ip); } ip++; narg--; #ifdef SYS_freebsd6_lseek } else if (ktr->ktr_code == SYS_freebsd6_lseek) { print_number(ip,narg,c); /* Hidden 'pad' argument, not in lseek(2) */ print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); whencename ((int)*ip); ip++; narg--; #endif } else if (ktr->ktr_code == SYS_lseek) { print_number(ip,narg,c); /* Hidden 'pad' argument, not in lseek(2) */ print_number(ip,narg,c); (void)putchar(','); whencename ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_flock) { print_number(ip,narg,c); (void)putchar(','); flockname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_mkfifo || ktr->ktr_code == SYS_mkdir) { print_number(ip,narg,c); (void)putchar(','); modename((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_shutdown) { print_number(ip,narg,c); (void)putchar(','); shutdownhowname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_socketpair) { (void)putchar('('); sockdomainname((int)*ip); ip++; narg--; (void)putchar(','); socktypename((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS_getrlimit || ktr->ktr_code == SYS_setrlimit) { (void)putchar('('); rlimitname((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS_quotactl) { print_number(ip,narg,c); (void)putchar(','); quotactlname((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS_nfssvc) { (void)putchar('('); nfssvcname((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS_rtprio) { (void)putchar('('); rtprioname((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS___semctl) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); semctlname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_semget) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); semgetname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_msgctl) { print_number(ip,narg,c); (void)putchar(','); shmctlname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_shmat) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); shmatname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_shmctl) { print_number(ip,narg,c); (void)putchar(','); shmctlname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_minherit) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); minheritname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_rfork) { (void)putchar('('); rforkname((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS_lio_listio) { (void)putchar('('); lio_listioname((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS_mlockall) { (void)putchar('('); mlockallname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_sched_setscheduler) { print_number(ip,narg,c); (void)putchar(','); schedpolicyname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_sched_get_priority_max || ktr->ktr_code == SYS_sched_get_priority_min) { (void)putchar('('); schedpolicyname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_sendfile) { print_number(ip,narg,c); print_number(ip,narg,c); print_number(ip,narg,c); print_number(ip,narg,c); print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); sendfileflagsname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_kldsym) { print_number(ip,narg,c); (void)putchar(','); kldsymcmdname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_sigprocmask) { (void)putchar('('); sigprocmaskhowname((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS___acl_get_file || ktr->ktr_code == SYS___acl_set_file || ktr->ktr_code == SYS___acl_get_fd || ktr->ktr_code == SYS___acl_set_fd || ktr->ktr_code == SYS___acl_delete_file || ktr->ktr_code == SYS___acl_delete_fd || ktr->ktr_code == SYS___acl_aclcheck_file || ktr->ktr_code == SYS___acl_aclcheck_fd || ktr->ktr_code == SYS___acl_get_link || ktr->ktr_code == SYS___acl_set_link || ktr->ktr_code == SYS___acl_delete_link || ktr->ktr_code == SYS___acl_aclcheck_link) { print_number(ip,narg,c); (void)putchar(','); acltypename((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_sigaction) { (void)putchar('('); signame((int)*ip); ip++; narg--; c = ','; } else if (ktr->ktr_code == SYS_extattrctl) { print_number(ip,narg,c); (void)putchar(','); extattrctlname((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_nmount) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); mountflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_kse_thr_interrupt) { print_number(ip,narg,c); (void)putchar(','); ksethrcmdname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_thr_create) { print_number(ip,narg,c); print_number(ip,narg,c); (void)putchar(','); thrcreateflagsname ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_thr_kill) { print_number(ip,narg,c); (void)putchar(','); signame ((int)*ip); ip++; narg--; } else if (ktr->ktr_code == SYS_kldunloadf) { print_number(ip,narg,c); (void)putchar(','); kldunloadfflagsname ((int)*ip); ip++; narg--; } } while (narg > 0) { print_number(ip,narg,c); } (void)putchar(')'); } (void)putchar('\n'); } void -ktrsysret(struct ktr_sysret *ktr) +ktrsysret(struct ktr_sysret *ktr, u_int flags) { register_t ret = ktr->ktr_retval; int error = ktr->ktr_error; int code = ktr->ktr_code; - if (code >= nsyscalls || code < 0) + if ((flags != 0 && ((flags & SV_ABI_MASK) != SV_ABI_FREEBSD)) || + (code >= nsyscalls || code < 0)) (void)printf("[%d] ", code); else (void)printf("%s ", syscallnames[code]); if (error == 0) { if (fancy) { (void)printf("%ld", (long)ret); if (ret < 0 || ret > 9) (void)printf("/%#lx", (long)ret); } else { if (decimal) (void)printf("%ld", (long)ret); else (void)printf("%#lx", (long)ret); } } else if (error == ERESTART) (void)printf("RESTART"); else if (error == EJUSTRETURN) (void)printf("JUSTRETURN"); else { (void)printf("-1 errno %d", ktr->ktr_error); if (fancy) (void)printf(" %s", strerror(ktr->ktr_error)); } (void)putchar('\n'); } void ktrnamei(char *cp, int len) { (void)printf("\"%.*s\"\n", len, cp); } void hexdump(char *p, int len, int screenwidth) { int n, i; int width; width = 0; do { width += 2; i = 13; /* base offset */ i += (width / 2) + 1; /* spaces every second byte */ i += (width * 2); /* width of bytes */ i += 3; /* " |" */ i += width; /* each byte */ i += 1; /* "|" */ } while (i < screenwidth); width -= 2; for (n = 0; n < len; n += width) { for (i = n; i < n + width; i++) { if ((i % width) == 0) { /* beginning of line */ printf(" 0x%04x", i); } if ((i % 2) == 0) { printf(" "); } if (i < len) printf("%02x", p[i] & 0xff); else printf(" "); } printf(" |"); for (i = n; i < n + width; i++) { if (i >= len) break; if (p[i] >= ' ' && p[i] <= '~') printf("%c", p[i]); else printf("."); } printf("|\n"); } if ((i % width) != 0) printf("\n"); } void visdump(char *dp, int datalen, int screenwidth) { int col = 0; char *cp; int width; char visbuf[5]; (void)printf(" \""); col = 8; for (;datalen > 0; datalen--, dp++) { (void) vis(visbuf, *dp, VIS_CSTYLE, *(dp+1)); cp = visbuf; /* * Keep track of printables and * space chars (like fold(1)). */ if (col == 0) { (void)putchar('\t'); col = 8; } switch(*cp) { case '\n': col = 0; (void)putchar('\n'); continue; case '\t': width = 8 - (col&07); break; default: width = strlen(cp); } if (col + width > (screenwidth-2)) { (void)printf("\\\n\t"); col = 8; } col += width; do { (void)putchar(*cp++); } while (*cp); } if (col == 0) (void)printf(" "); (void)printf("\"\n"); } void ktrgenio(struct ktr_genio *ktr, int len) { int datalen = len - sizeof (struct ktr_genio); char *dp = (char *)ktr + sizeof (struct ktr_genio); static int screenwidth = 0; int i, binary; if (screenwidth == 0) { struct winsize ws; if (fancy && ioctl(fileno(stderr), TIOCGWINSZ, &ws) != -1 && ws.ws_col > 8) screenwidth = ws.ws_col; else screenwidth = 80; } printf("fd %d %s %d byte%s\n", ktr->ktr_fd, ktr->ktr_rw == UIO_READ ? "read" : "wrote", datalen, datalen == 1 ? "" : "s"); if (suppressdata) return; if (maxdata && datalen > maxdata) datalen = maxdata; for (i = 0, binary = 0; i < datalen && binary == 0; i++) { if (dp[i] >= 32 && dp[i] < 127) continue; if (dp[i] == 10 || dp[i] == 13 || dp[i] == 0 || dp[i] == 9) continue; binary = 1; } if (binary) hexdump(dp, datalen, screenwidth); else visdump(dp, datalen, screenwidth); } const char *signames[] = { "NULL", "HUP", "INT", "QUIT", "ILL", "TRAP", "IOT", /* 1 - 6 */ "EMT", "FPE", "KILL", "BUS", "SEGV", "SYS", /* 7 - 12 */ "PIPE", "ALRM", "TERM", "URG", "STOP", "TSTP", /* 13 - 18 */ "CONT", "CHLD", "TTIN", "TTOU", "IO", "XCPU", /* 19 - 24 */ "XFSZ", "VTALRM", "PROF", "WINCH", "29", "USR1", /* 25 - 30 */ "USR2", NULL, /* 31 - 32 */ }; void ktrpsig(struct ktr_psig *psig) { if (psig->signo > 0 && psig->signo < NSIG) (void)printf("SIG%s ", signames[psig->signo]); else (void)printf("SIG %d ", psig->signo); if (psig->action == SIG_DFL) (void)printf("SIG_DFL\n"); else { (void)printf("caught handler=0x%lx mask=0x%x code=0x%x\n", (u_long)psig->action, psig->mask.__bits[0], psig->code); } } void ktrcsw(struct ktr_csw *cs) { (void)printf("%s %s\n", cs->out ? "stop" : "resume", cs->user ? "user" : "kernel"); } #define UTRACE_DLOPEN_START 1 #define UTRACE_DLOPEN_STOP 2 #define UTRACE_DLCLOSE_START 3 #define UTRACE_DLCLOSE_STOP 4 #define UTRACE_LOAD_OBJECT 5 #define UTRACE_UNLOAD_OBJECT 6 #define UTRACE_ADD_RUNDEP 7 #define UTRACE_PRELOAD_FINISHED 8 #define UTRACE_INIT_CALL 9 #define UTRACE_FINI_CALL 10 struct utrace_rtld { char sig[4]; /* 'RTLD' */ int event; void *handle; void *mapbase; size_t mapsize; int refcnt; char name[MAXPATHLEN]; }; void ktruser_rtld(int len, unsigned char *p) { struct utrace_rtld *ut = (struct utrace_rtld *)p; void *parent; int mode; switch (ut->event) { case UTRACE_DLOPEN_START: mode = ut->refcnt; printf("dlopen(%s, ", ut->name); switch (mode & RTLD_MODEMASK) { case RTLD_NOW: printf("RTLD_NOW"); break; case RTLD_LAZY: printf("RTLD_LAZY"); break; default: printf("%#x", mode & RTLD_MODEMASK); } if (mode & RTLD_GLOBAL) printf(" | RTLD_GLOBAL"); if (mode & RTLD_TRACE) printf(" | RTLD_TRACE"); if (mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)) printf(" | %#x", mode & ~(RTLD_MODEMASK | RTLD_GLOBAL | RTLD_TRACE)); printf(")\n"); break; case UTRACE_DLOPEN_STOP: printf("%p = dlopen(%s) ref %d\n", ut->handle, ut->name, ut->refcnt); break; case UTRACE_DLCLOSE_START: printf("dlclose(%p) (%s, %d)\n", ut->handle, ut->name, ut->refcnt); break; case UTRACE_DLCLOSE_STOP: printf("dlclose(%p) finished\n", ut->handle); break; case UTRACE_LOAD_OBJECT: printf("RTLD: loaded %p @ %p - %p (%s)\n", ut->handle, ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, ut->name); break; case UTRACE_UNLOAD_OBJECT: printf("RTLD: unloaded %p @ %p - %p (%s)\n", ut->handle, ut->mapbase, (char *)ut->mapbase + ut->mapsize - 1, ut->name); break; case UTRACE_ADD_RUNDEP: parent = ut->mapbase; printf("RTLD: %p now depends on %p (%s, %d)\n", parent, ut->handle, ut->name, ut->refcnt); break; case UTRACE_PRELOAD_FINISHED: printf("RTLD: LD_PRELOAD finished\n"); break; case UTRACE_INIT_CALL: printf("RTLD: init %p for %p (%s)\n", ut->mapbase, ut->handle, ut->name); break; case UTRACE_FINI_CALL: printf("RTLD: fini %p for %p (%s)\n", ut->mapbase, ut->handle, ut->name); break; default: p += 4; len -= 4; printf("RTLD: %d ", len); while (len--) if (decimal) printf(" %d", *p++); else printf(" %02x", *p++); printf("\n"); } } struct utrace_malloc { void *p; size_t s; void *r; }; void ktruser_malloc(int len, unsigned char *p) { struct utrace_malloc *ut = (struct utrace_malloc *)p; if (ut->p == NULL) { if (ut->s == 0 && ut->r == NULL) printf("malloc_init()\n"); else printf("%p = malloc(%zu)\n", ut->r, ut->s); } else { if (ut->s == 0) printf("free(%p)\n", ut->p); else printf("%p = realloc(%p, %zu)\n", ut->r, ut->p, ut->s); } } void ktruser(int len, unsigned char *p) { if (len >= 8 && bcmp(p, "RTLD", 4) == 0) { ktruser_rtld(len, p); return; } if (len == sizeof(struct utrace_malloc)) { ktruser_malloc(len, p); return; } (void)printf("%d ", len); while (len--) if (decimal) (void)printf(" %d", *p++); else (void)printf(" %02x", *p++); (void)printf("\n"); } void ktrsockaddr(struct sockaddr *sa) { /* TODO: Support additional address families #include struct sockaddr_natm *natm; #include struct sockaddr_nb *nb; */ char addr[64]; /* * note: ktrstruct() has already verified that sa points to a * buffer at least sizeof(struct sockaddr) bytes long and exactly * sa->sa_len bytes long. */ printf("struct sockaddr { "); sockfamilyname(sa->sa_family); printf(", "); #define check_sockaddr_len(n) \ if (sa_##n->s##n##_len < sizeof(struct sockaddr_##n)) { \ printf("invalid"); \ break; \ } switch(sa->sa_family) { case AF_INET: { struct sockaddr_in *sa_in; sa_in = (struct sockaddr_in *)sa; check_sockaddr_len(in); inet_ntop(AF_INET, &sa_in->sin_addr, addr, sizeof addr); printf("%s:%u", addr, ntohs(sa_in->sin_port)); break; } #ifdef NETATALK case AF_APPLETALK: { struct sockaddr_at *sa_at; struct netrange *nr; sa_at = (struct sockaddr_at *)sa; check_sockaddr_len(at); nr = &sa_at->sat_range.r_netrange; printf("%d.%d, %d-%d, %d", ntohs(sa_at->sat_addr.s_net), sa_at->sat_addr.s_node, ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet), nr->nr_phase); break; } #endif case AF_INET6: { struct sockaddr_in6 *sa_in6; sa_in6 = (struct sockaddr_in6 *)sa; check_sockaddr_len(in6); inet_ntop(AF_INET6, &sa_in6->sin6_addr, addr, sizeof addr); printf("[%s]:%u", addr, htons(sa_in6->sin6_port)); break; } #ifdef IPX case AF_IPX: { struct sockaddr_ipx *sa_ipx; sa_ipx = (struct sockaddr_ipx *)sa; check_sockaddr_len(ipx); /* XXX wish we had ipx_ntop */ printf("%s", ipx_ntoa(sa_ipx->sipx_addr)); break; } #endif case AF_UNIX: { struct sockaddr_un *sa_un; sa_un = (struct sockaddr_un *)sa; check_sockaddr_len(un); printf("%.*s", (int)sizeof(sa_un->sun_path), sa_un->sun_path); break; } default: printf("unknown address family"); } printf(" }\n"); } void ktrstat(struct stat *statp) { char mode[12], timestr[PATH_MAX + 4]; struct passwd *pwd; struct group *grp; struct tm *tm; /* * note: ktrstruct() has already verified that statp points to a * buffer exactly sizeof(struct stat) bytes long. */ printf("struct stat {"); strmode(statp->st_mode, mode); printf("dev=%ju, ino=%ju, mode=%s, nlink=%ju, ", (uintmax_t)statp->st_dev, (uintmax_t)statp->st_ino, mode, (uintmax_t)statp->st_nlink); if (resolv == 0 || (pwd = getpwuid(statp->st_uid)) == NULL) printf("uid=%ju, ", (uintmax_t)statp->st_uid); else printf("uid=\"%s\", ", pwd->pw_name); if (resolv == 0 || (grp = getgrgid(statp->st_gid)) == NULL) printf("gid=%ju, ", (uintmax_t)statp->st_gid); else printf("gid=\"%s\", ", grp->gr_name); printf("rdev=%ju, ", (uintmax_t)statp->st_rdev); printf("atime="); if (resolv == 0) printf("%jd", (intmax_t)statp->st_atimespec.tv_sec); else { tm = localtime(&statp->st_atimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); printf("\"%s\"", timestr); } if (statp->st_atimespec.tv_nsec != 0) printf(".%09ld, ", statp->st_atimespec.tv_nsec); else printf(", "); printf("stime="); if (resolv == 0) printf("%jd", (intmax_t)statp->st_mtimespec.tv_sec); else { tm = localtime(&statp->st_mtimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); printf("\"%s\"", timestr); } if (statp->st_mtimespec.tv_nsec != 0) printf(".%09ld, ", statp->st_mtimespec.tv_nsec); else printf(", "); printf("ctime="); if (resolv == 0) printf("%jd", (intmax_t)statp->st_ctimespec.tv_sec); else { tm = localtime(&statp->st_ctimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); printf("\"%s\"", timestr); } if (statp->st_ctimespec.tv_nsec != 0) printf(".%09ld, ", statp->st_ctimespec.tv_nsec); else printf(", "); printf("birthtime="); if (resolv == 0) printf("%jd", (intmax_t)statp->st_birthtimespec.tv_sec); else { tm = localtime(&statp->st_birthtimespec.tv_sec); (void)strftime(timestr, sizeof(timestr), TIME_FORMAT, tm); printf("\"%s\"", timestr); } if (statp->st_birthtimespec.tv_nsec != 0) printf(".%09ld, ", statp->st_birthtimespec.tv_nsec); else printf(", "); printf("size=%jd, blksize=%ju, blocks=%jd, flags=0x%x", (uintmax_t)statp->st_size, (uintmax_t)statp->st_blksize, (intmax_t)statp->st_blocks, statp->st_flags); printf(" }\n"); } void ktrstruct(char *buf, size_t buflen) { char *name, *data; size_t namelen, datalen; int i; for (name = buf, namelen = 0; namelen < buflen && name[namelen] != '\0'; ++namelen) /* nothing */; if (namelen == buflen) goto invalid; if (name[namelen] != '\0') goto invalid; data = buf + namelen + 1; datalen = buflen - namelen - 1; if (datalen == 0) goto invalid; /* sanity check */ for (i = 0; i < namelen; ++i) if (!isalpha((unsigned char)name[i])) goto invalid; if (strcmp(name, "stat") == 0) { if (datalen != sizeof(struct stat)) goto invalid; ktrstat((struct stat *)data); } else if (strcmp(name, "sockaddr") == 0) { if (datalen < sizeof(struct sockaddr) || datalen != ((struct sockaddr *)(data))->sa_len) goto invalid; ktrsockaddr((struct sockaddr *)data); } else { printf("unknown structure\n"); } return; invalid: printf("invalid record\n"); } +#if defined(__amd64__) || defined(__i386__) void +linux_ktrsyscall(struct ktr_syscall *ktr) +{ + int narg = ktr->ktr_narg; + register_t *ip; + + if (ktr->ktr_code >= nlinux_syscalls || ktr->ktr_code < 0) + printf("[%d]", ktr->ktr_code); + else + printf("%s", linux_syscallnames[ktr->ktr_code]); + ip = &ktr->ktr_args[0]; + if (narg) { + char c = '('; + while (narg > 0) + print_number(ip, narg, c); + putchar(')'); + } + putchar('\n'); +} + +void +linux_ktrsysret(struct ktr_sysret *ktr) +{ + register_t ret = ktr->ktr_retval; + int error = ktr->ktr_error; + int code = ktr->ktr_code; + + if (code >= nlinux_syscalls || code < 0) + printf("[%d] ", code); + else + printf("%s ", linux_syscallnames[code]); + + if (error == 0) { + if (fancy) { + printf("%ld", (long)ret); + if (ret < 0 || ret > 9) + printf("/%#lx", (long)ret); + } else { + if (decimal) + printf("%ld", (long)ret); + else + printf("%#lx", (long)ret); + } + } else if (error == ERESTART) + printf("RESTART"); + else if (error == EJUSTRETURN) + printf("JUSTRETURN"); + else { + if (ktr->ktr_error <= ELAST + 1) + error = abs(bsd_to_linux_errno[ktr->ktr_error]); + else + error = 999; + printf("-1 errno %d", error); + if (fancy) + printf(" %s", strerror(ktr->ktr_error)); + } + putchar('\n'); +} +#endif + +void usage(void) { - fprintf(stderr, "usage: kdump [-dEnlHRrsT] [-f trfile] " + fprintf(stderr, "usage: kdump [-dEnlHRrsTA] [-f trfile] " "[-m maxdata] [-p pid] [-t trstr]\n"); exit(1); } Index: stable/7/usr.bin/kdump/linux_syscalls.conf =================================================================== --- stable/7/usr.bin/kdump/linux_syscalls.conf (nonexistent) +++ stable/7/usr.bin/kdump/linux_syscalls.conf (revision 220268) @@ -0,0 +1,11 @@ +# $FreeBSD$ +sysnames="linux_syscalls.c" +sysproto="/dev/null" +sysproto_h=_LINUX_SYSPROTO_H_ +syshdr="/dev/null" +syssw="/dev/null" +sysmk="/dev/null" +syscallprefix="LINUX_SYS_" +switchname="/dev/null" +namesname="linux_syscallnames" +systrace="/dev/null" Property changes on: stable/7/usr.bin/kdump/linux_syscalls.conf ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: stable/7/usr.bin/kdump =================================================================== --- stable/7/usr.bin/kdump (revision 220267) +++ stable/7/usr.bin/kdump (revision 220268) Property changes on: stable/7/usr.bin/kdump ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/usr.bin/kdump:r219043-219044,219138 Index: stable/7/usr.bin/ktrace/ktrace.c =================================================================== --- stable/7/usr.bin/ktrace/ktrace.c (revision 220267) +++ stable/7/usr.bin/ktrace/ktrace.c (revision 220268) @@ -1,208 +1,210 @@ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. */ #ifndef lint static const char copyright[] = "@(#) Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #if 0 #ifndef lint static char sccsid[] = "@(#)ktrace.c 8.1 (Berkeley) 6/6/93"; #endif /* not lint */ #endif #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include "ktrace.h" static char def_tracefile[] = DEF_TRACEFILE; static void no_ktrace(int); static int rpid(char *); static void usage(void); int main(int argc, char *argv[]) { enum { NOTSET, CLEAR, CLEARALL } clear; int append, ch, fd, inherit, ops, pid, pidset, trpoints; const char *tracefile; mode_t omask; struct stat sb; clear = NOTSET; append = ops = pidset = inherit = 0; trpoints = DEF_POINTS; tracefile = def_tracefile; while ((ch = getopt(argc,argv,"aCcdf:g:ip:t:")) != -1) switch((char)ch) { case 'a': append = 1; break; case 'C': clear = CLEARALL; pidset = 1; break; case 'c': clear = CLEAR; break; case 'd': ops |= KTRFLAG_DESCEND; break; case 'f': tracefile = optarg; break; case 'g': pid = -rpid(optarg); pidset = 1; break; case 'i': inherit = 1; break; case 'p': pid = rpid(optarg); pidset = 1; break; case 't': trpoints = getpoints(optarg); if (trpoints < 0) { warnx("unknown facility in %s", optarg); usage(); } break; default: usage(); } argv += optind; argc -= optind; if ((pidset && *argv) || (!pidset && clear == NOTSET && !*argv)) usage(); if (inherit) trpoints |= KTRFAC_INHERIT; (void)signal(SIGSYS, no_ktrace); if (clear != NOTSET) { if (clear == CLEARALL) { ops = KTROP_CLEAR | KTRFLAG_DESCEND; trpoints = ALL_POINTS; pid = 1; } else ops |= pidset ? KTROP_CLEAR : KTROP_CLEARFILE; if (ktrace(tracefile, ops, trpoints, pid) < 0) err(1, "%s", tracefile); exit(0); } omask = umask(S_IRWXG|S_IRWXO); if (append) { if ((fd = open(tracefile, O_CREAT | O_WRONLY | O_NONBLOCK, DEFFILEMODE)) < 0) err(1, "%s", tracefile); if (fstat(fd, &sb) != 0 || sb.st_uid != getuid()) errx(1, "refuse to append to %s not owned by you", tracefile); if (!(S_ISREG(sb.st_mode))) errx(1, "%s not regular file", tracefile); } else { if (unlink(tracefile) == -1 && errno != ENOENT) err(1, "unlink %s", tracefile); if ((fd = open(tracefile, O_CREAT | O_EXCL | O_WRONLY, DEFFILEMODE)) < 0) err(1, "%s", tracefile); } (void)umask(omask); (void)close(fd); + trpoints |= PROC_ABI_POINTS; + if (*argv) { if (ktrace(tracefile, ops, trpoints, getpid()) < 0) err(1, "%s", tracefile); execvp(argv[0], &argv[0]); err(1, "exec of '%s' failed", argv[0]); } else if (ktrace(tracefile, ops, trpoints, pid) < 0) err(1, "%s", tracefile); exit(0); } static int rpid(char *p) { static int first; if (first++) { warnx("only one -g or -p flag is permitted"); usage(); } if (!*p) { warnx("illegal process id"); usage(); } return(atoi(p)); } static void usage(void) { (void)fprintf(stderr, "%s\n%s\n", "usage: ktrace [-aCcdi] [-f trfile] [-g pgrp | -p pid] [-t trstr]", " ktrace [-adi] [-f trfile] [-t trstr] command"); exit(1); } static void no_ktrace(int sig __unused) { (void)fprintf(stderr, "error:\tktrace() system call not supported in the running kernel\n\tre-compile kernel with 'options KTRACE'\n"); exit(1); } Index: stable/7/usr.bin/ktrace/ktrace.h =================================================================== --- stable/7/usr.bin/ktrace/ktrace.h (revision 220267) +++ stable/7/usr.bin/ktrace/ktrace.h (revision 220268) @@ -1,45 +1,47 @@ /*- * Copyright (c) 1988, 1993 * The Regents of the University of California. 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. * * @(#)ktrace.h 8.1 (Berkeley) 6/6/93 * $FreeBSD$ */ #define DEF_POINTS (KTRFAC_SYSCALL | KTRFAC_SYSRET | KTRFAC_NAMEI | \ KTRFAC_GENIO | KTRFAC_PSIG | KTRFAC_USER | \ KTRFAC_STRUCT | KTRFAC_SYSCTL) -#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW) +#define PROC_ABI_POINTS (KTRFAC_PROCCTOR | KTRFAC_PROCDTOR) + +#define ALL_POINTS (DEF_POINTS | KTRFAC_CSW | PROC_ABI_POINTS) #define DEF_TRACEFILE "ktrace.out" int getpoints(char *); Index: stable/7/usr.bin/ktrace =================================================================== --- stable/7/usr.bin/ktrace (revision 220267) +++ stable/7/usr.bin/ktrace (revision 220268) Property changes on: stable/7/usr.bin/ktrace ___________________________________________________________________ Modified: svn:mergeinfo ## -0,0 +0,1 ## Merged /head/usr.bin/ktrace:r219043-219044,219138