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++;
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to