summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2017-01-06 20:32:34 +0000
committerjhb <jhb@FreeBSD.org>2017-01-06 20:32:34 +0000
commit1249c3246b526096f921b435f69a1273d2418b2a (patch)
treea00fa8c617bb7ae53cabc104b468663fb4a29a6d /usr.bin
parent25959c1c21ac52c76bf01f17aa1980dead9177e7 (diff)
downloadFreeBSD-src-1249c3246b526096f921b435f69a1273d2418b2a.zip
FreeBSD-src-1249c3246b526096f921b435f69a1273d2418b2a.tar.gz
MFC 306562: 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.
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/kdump/kdump.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c
index 776909a..be9f7f6 100644
--- a/usr.bin/kdump/kdump.c
+++ b/usr.bin/kdump/kdump.c
@@ -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_int sv_flags)
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_int sv_flags)
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_int sv_flags)
#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_int sv_flags)
c = ',';
ip++;
narg--;
- print_number(ip, narg, c);
+ print_number64(first, ip, narg, c);
putchar(',');
procctlcmdname(*ip);
ip++;
OpenPOWER on IntegriCloud