From owner-svn-src-all@FreeBSD.ORG Thu Mar 3 11:15:01 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id EBB40106564A; Thu, 3 Mar 2011 11:15:00 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id 91CE48FC17; Thu, 3 Mar 2011 11:15:00 +0000 (UTC) Received: from fledge.watson.org (fledge.watson.org [65.122.17.41]) by cyrus.watson.org (Postfix) with ESMTPS id B9A5146B89; Thu, 3 Mar 2011 06:14:59 -0500 (EST) Date: Thu, 3 Mar 2011 11:14:59 +0000 (GMT) From: Robert Watson X-X-Sender: robert@fledge.watson.org To: Dmitry Chagin In-Reply-To: <201103011642.p21GgTaH041022@svn.freebsd.org> Message-ID: References: <201103011642.p21GgTaH041022@svn.freebsd.org> User-Agent: Alpine 2.00 (BSF 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r219138 - head/usr.bin/kdump X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Mar 2011 11:15:01 -0000 On Tue, 1 Mar 2011, Dmitry Chagin wrote: > Teach kdump to decode linux syscalls names too. > > Fix bug introduced in my previous commit: the kernel always dump native > signal numbers, so no need to check the ABI in ktrpsig(). Does this mean that we're eliminating the need for the long-broken linux_kdump? Is there any ABI record in ktrace files, and/or should we add one somehow? I'd love to be able to process a kdump file generated from a blend of ABIs: i.e., if I do ktrace -di tcsh, and then run a bunch of commands from different ABIs (FreeBSD/32-bit Intel, FreeBSD/64-bit Intel, Linux/32-bit Intel, and possible FreeBSD/64 MIPS so that a distributed ktracing tool gathers the results across hosts for a single action), have kdump Just Work. This suggests that a per-record ABI indicator might be useful. Robert > > Suggested by: jhb > MFC after: 1 Month. > > Added: > head/usr.bin/kdump/linux_syscalls.conf (contents, props changed) > Modified: > head/usr.bin/kdump/Makefile > head/usr.bin/kdump/kdump.c > > Modified: head/usr.bin/kdump/Makefile > ============================================================================== > --- head/usr.bin/kdump/Makefile Tue Mar 1 14:54:14 2011 (r219137) > +++ head/usr.bin/kdump/Makefile Tue Mar 1 16:42:28 2011 (r219138) > @@ -1,15 +1,23 @@ > # @(#)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}/../.. > > +.if ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "i386" > +SRCS+= linux_syscalls.c > +.endif > + > WARNS?= 0 > > -CLEANFILES= ioctl.c kdump_subr.c > +CLEANFILES= ioctl.c kdump_subr.c linux_syscalls.c > > ioctl.c: mkioctls > sh ${.CURDIR}/mkioctls ${DESTDIR}/usr/include > ${.TARGET} > @@ -17,4 +25,10 @@ ioctl.c: mkioctls > 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 > > Modified: head/usr.bin/kdump/kdump.c > ============================================================================== > --- head/usr.bin/kdump/kdump.c Tue Mar 1 14:54:14 2011 (r219137) > +++ head/usr.bin/kdump/kdump.c Tue Mar 1 16:42:28 2011 (r219138) > @@ -93,7 +93,7 @@ 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 *, u_int); > +void ktrpsig(struct ktr_psig *); > void ktrcsw(struct ktr_csw *); > void ktruser(int, unsigned char *); > void ktrsockaddr(struct sockaddr *); > @@ -111,6 +111,41 @@ 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; > @@ -233,10 +268,20 @@ main(int argc, char *argv[]) > drop_logged = 0; > switch (ktr_header.ktr_type) { > case KTR_SYSCALL: > - ktrsyscall((struct ktr_syscall *)m, sv_flags); > +#if defined(__amd64__) || defined(__i386__) > + if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX) > + linux_ktrsyscall((struct ktr_syscall *)m); > + else > +#endif > + ktrsyscall((struct ktr_syscall *)m, sv_flags); > break; > case KTR_SYSRET: > - ktrsysret((struct ktr_sysret *)m, sv_flags); > +#if defined(__amd64__) || defined(__i386__) > + if ((sv_flags & SV_ABI_MASK) == SV_ABI_LINUX) > + linux_ktrsysret((struct ktr_sysret *)m); > + else > +#endif > + ktrsysret((struct ktr_sysret *)m, sv_flags); > break; > case KTR_NAMEI: > case KTR_SYSCTL: > @@ -246,7 +291,7 @@ main(int argc, char *argv[]) > ktrgenio((struct ktr_genio *)m, ktrlen); > break; > case KTR_PSIG: > - ktrpsig((struct ktr_psig *)m, sv_flags); > + ktrpsig((struct ktr_psig *)m); > break; > case KTR_CSW: > ktrcsw((struct ktr_csw *)m); > @@ -455,17 +500,6 @@ ktrsyscall(struct ktr_syscall *ktr, u_in > char c = '('; > if (fancy && > (flags == 0 || (flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) { > - > -#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 (ktr->ktr_code == SYS_ioctl) { > const char *cp; > print_number(ip,narg,c); > @@ -1093,10 +1127,9 @@ const char *signames[] = { > }; > > void > -ktrpsig(struct ktr_psig *psig, u_int flags) > +ktrpsig(struct ktr_psig *psig) > { > - if ((flags & SV_ABI_MASK) == SV_ABI_FREEBSD && > - psig->signo > 0 && psig->signo < NSIG) > + if (psig->signo > 0 && psig->signo < NSIG) > (void)printf("SIG%s ", signames[psig->signo]); > else > (void)printf("SIG %d ", psig->signo); > @@ -1471,6 +1504,67 @@ 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) > { > > Added: head/usr.bin/kdump/linux_syscalls.conf > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/usr.bin/kdump/linux_syscalls.conf Tue Mar 1 16:42:28 2011 (r219138) > @@ -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" >