svn commit: r306562 - head/usr.bin/kdump

John Baldwin jhb at FreeBSD.org
Sat Oct 1 22:01:42 UTC 2016


Author: jhb
Date: Sat Oct  1 22:01:41 2016
New Revision: 306562
URL: https://svnweb.freebsd.org/changeset/base/306562

Log:
  Handle 64-bit system call arguments (off_t, id_t).
  
  In particular, 64-bit system call arguments use up two register_t
  arguments for 32-bit processes.  They must also be aligned on a 64-bit
  boundary on 32-bit powerpc processes.  This fixes the decoding of
  lseek(), procctl(), and wait6() arguments for 32-bit processes (both
  native and via freebsd32).
  
  Note that the ktrace system call return record only returns a single
  register, so the return value of lseek is always truncated to the low
  32-bits for 32-bit processes.

Modified:
  head/usr.bin/kdump/kdump.c

Modified: head/usr.bin/kdump/kdump.c
==============================================================================
--- head/usr.bin/kdump/kdump.c	Sat Oct  1 20:46:01 2016	(r306561)
+++ head/usr.bin/kdump/kdump.c	Sat Oct  1 22:01:41 2016	(r306562)
@@ -74,6 +74,7 @@ extern int errno;
 #include <netdb.h>
 #include <nl_types.h>
 #include <pwd.h>
+#include <stddef.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -132,6 +133,27 @@ static struct ktr_header ktr_header;
 #define TIME_FORMAT	"%b %e %T %Y"
 #define eqs(s1, s2)	(strcmp((s1), (s2)) == 0)
 
+#define	print_number64(first,i,n,c) do {				\
+	uint64_t __v;							\
+									\
+	if (quad_align && (((ptrdiff_t)((i) - (first))) & 1) == 1) {	\
+		(i)++;							\
+		(n)--;							\
+	}								\
+	if (quad_slots == 2)						\
+		__v = (uint64_t)(uint32_t)(i)[0] |			\
+		    ((uint64_t)(uint32_t)(i)[1]) << 32;			\
+	else								\
+		__v = (uint64_t)*(i);					\
+	if (decimal)							\
+		printf("%c%jd", (c), (intmax_t)__v);			\
+	else								\
+		printf("%c%#jx", (c), (uintmax_t)__v);			\
+	(i) += quad_slots;						\
+	(n) -= quad_slots;						\
+	(c) = ',';							\
+} while (0)
+
 #define print_number(i,n,c) do {					\
 	if (decimal)							\
 		printf("%c%jd", c, (intmax_t)*i);			\
@@ -705,16 +727,25 @@ void
 ktrsyscall(struct ktr_syscall *ktr, u_int sv_flags)
 {
 	int narg = ktr->ktr_narg;
-	register_t *ip;
+	register_t *ip, *first;
 	intmax_t arg;
+	int quad_align, quad_slots;
 
 	syscallname(ktr->ktr_code, sv_flags);
-	ip = &ktr->ktr_args[0];
+	ip = first = &ktr->ktr_args[0];
 	if (narg) {
 		char c = '(';
 		if (fancy &&
 		    (sv_flags == 0 ||
 		    (sv_flags & SV_ABI_MASK) == SV_ABI_FREEBSD)) {
+			quad_align = 0;
+			if (sv_flags & SV_ILP32) {
+#ifdef __powerpc__
+				quad_align = 1;
+#endif
+				quad_slots = 2;
+			} else
+				quad_slots = 1;
 			switch (ktr->ktr_code) {
 			case SYS_bindat:
 			case SYS_connectat:
@@ -796,7 +827,7 @@ ktrsyscall(struct ktr_syscall *ktr, u_in
 				c = ',';
 				ip++;
 				narg--;
-				print_number(ip, narg, c);
+				print_number64(first, ip, narg, c);
 				print_number(ip, narg, c);
 				putchar(',');
 				wait6optname(*ip);
@@ -996,7 +1027,7 @@ ktrsyscall(struct ktr_syscall *ktr, u_in
 				print_number(ip, narg, c);
 				/* Hidden 'pad' argument, not in lseek(2) */
 				print_number(ip, narg, c);
-				print_number(ip, narg, c);
+				print_number64(first, ip, narg, c);
 				putchar(',');
 				whencename(*ip);
 				ip++;
@@ -1005,8 +1036,7 @@ ktrsyscall(struct ktr_syscall *ktr, u_in
 #endif
 			case SYS_lseek:
 				print_number(ip, narg, c);
-				/* Hidden 'pad' argument, not in lseek(2) */
-				print_number(ip, narg, c);
+				print_number64(first, ip, narg, c);
 				putchar(',');
 				whencename(*ip);
 				ip++;
@@ -1285,7 +1315,7 @@ ktrsyscall(struct ktr_syscall *ktr, u_in
 				c = ',';
 				ip++;
 				narg--;
-				print_number(ip, narg, c);
+				print_number64(first, ip, narg, c);
 				putchar(',');
 				procctlcmdname(*ip);
 				ip++;


More information about the svn-src-head mailing list