@samitouri / QOSamiQemu / commits / cec27d2fa9

linux-user/strace: fix printing of file offsets

Previously, 64-bit file offsets (loff_t) were printed using `print_raw_param()` function, which led to silent truncation of the upper part. This commit fixes this issue by adding two helper functions: 1. print_file_offset32(): prints 32-bit file offsets (off_t) 2. print_file_offset64(): prints 64-bit file offsets (loff_t) Changelog v2: 1. Make `print_file_offset32()` static. 2. Use `last` parameter in `print_file_offset32()`. 3. Rename `low` and `high` parameters of `print_file_offset64()` to `word0`, `word1` respectively 4. Convert `last` to bool for `print_file_offset[32,64]()` 5. Use `PRId64` instead of `PRIu64` for `print_file_offset64()` 6. Fix `print__llseek()` Signed-off-by: Jean-Christian CÎRSTEA <jean.christian.cirstea@gmail.com> Reviewed-by: Helge Deller <deller@gmx.de> Signed-off-by: Helge Deller <deller@gmx.de>

Jean-Christian CÎRSTEA committed Dec 26, 2025 at 19:35 UTC cec27d2fa9cfd8c0018e19a62db590682569aa81
1 file changed +31 -12
linux-user/strace.c
+31 -12
@@ -85,6 +85,10 @@ UNUSED static void print_enums(const struct enums *, abi_long, int);
85 UNUSED static void print_at_dirfd(abi_long, int);
86 UNUSED static void print_file_mode(abi_long, int);
87 UNUSED static void print_open_flags(abi_long, int);
88 +UNUSED static void print_file_offset32(abi_long offset, bool last);
89 +UNUSED static void print_file_offset64(abi_long word0,
90 + abi_long word1,
91 + bool last);
92 UNUSED static void print_syscall_prologue(const struct syscallname *);
93 UNUSED static void print_syscall_epilogue(const struct syscallname *);
94 UNUSED static void print_string(abi_long, int);
@@ -1664,6 +1668,20 @@ print_open_flags(abi_long flags, int last)
1668 print_flags(open_flags, flags, last);
1669 }
1670
1671 +/* Prints 32-bit file offset (off_t) */
1672 +static void
1673 +print_file_offset32(abi_long offset, bool last)
1674 +{
1675 + print_raw_param(TARGET_ABI_FMT_ld, offset, last);
1676 +}
1677 +
1678 +/* Prints 64-bit file offset (loff_t) */
1679 +static void
1680 +print_file_offset64(abi_long word0, abi_long word1, bool last)
1681 +{
1682 + print_raw_param64("%" PRId64, target_offset64(word0, word1), last);
1683 +}
1684 +
1685 static void
1686 print_syscall_prologue(const struct syscallname *sc)
1687 {
@@ -2256,11 +2274,13 @@ print_fallocate(CPUArchState *cpu_env, const struct syscallname *name,
2274 print_raw_param("%d", arg0, 0);
2275 print_flags(falloc_flags, arg1, 0);
2276 #if TARGET_ABI_BITS == 32
2259 - print_raw_param("%" PRIu64, target_offset64(arg2, arg3), 0);
2260 - print_raw_param("%" PRIu64, target_offset64(arg4, arg5), 1);
2277 + /* On 32-bit targets, two registers are used for `loff_t` */
2278 + print_file_offset64(arg2, arg3, false);
2279 + print_file_offset64(arg4, arg5, true);
2280 #else
2262 - print_raw_param(TARGET_ABI_FMT_ld, arg2, 0);
2263 - print_raw_param(TARGET_ABI_FMT_ld, arg3, 1);
2281 + /* On 64-bit targets, one register is used for `loff_t` */
2282 + print_file_offset64(arg2, 0, false);
2283 + print_file_offset64(arg3, 0, true);
2284 #endif
2285 print_syscall_epilogue(name);
2286 }
@@ -2666,8 +2686,7 @@ print__llseek(CPUArchState *cpu_env, const struct syscallname *name,
2686 const char *whence = "UNKNOWN";
2687 print_syscall_prologue(name);
2688 print_raw_param("%d", arg0, 0);
2669 - print_raw_param("%ld", arg1, 0);
2670 - print_raw_param("%ld", arg2, 0);
2689 + print_file_offset64(arg1, arg2, false);
2690 print_pointer(arg3, 0);
2691 switch(arg4) {
2692 case SEEK_SET: whence = "SEEK_SET"; break;
@@ -2688,7 +2707,7 @@ print_lseek(CPUArchState *cpu_env, const struct syscallname *name,
2707 {
2708 print_syscall_prologue(name);
2709 print_raw_param("%d", arg0, 0);
2691 - print_raw_param(TARGET_ABI_FMT_ld, arg1, 0);
2710 + print_file_offset32(arg1, false);
2711 switch (arg2) {
2712 case SEEK_SET:
2713 qemu_log("SEEK_SET"); break;
@@ -2719,7 +2738,7 @@ print_truncate(CPUArchState *cpu_env, const struct syscallname *name,
2738 {
2739 print_syscall_prologue(name);
2740 print_string(arg0, 0);
2722 - print_raw_param(TARGET_ABI_FMT_ld, arg1, 1);
2741 + print_file_offset32(arg1, true);
2742 print_syscall_epilogue(name);
2743 }
2744 #endif
@@ -2736,7 +2755,7 @@ print_truncate64(CPUArchState *cpu_env, const struct syscallname *name,
2755 arg1 = arg2;
2756 arg2 = arg3;
2757 }
2739 - print_raw_param("%" PRIu64, target_offset64(arg1, arg2), 1);
2758 + print_file_offset64(arg1, arg2, true);
2759 print_syscall_epilogue(name);
2760 }
2761 #endif
@@ -2753,7 +2772,7 @@ print_ftruncate64(CPUArchState *cpu_env, const struct syscallname *name,
2772 arg1 = arg2;
2773 arg2 = arg3;
2774 }
2756 - print_raw_param("%" PRIu64, target_offset64(arg1, arg2), 1);
2775 + print_file_offset64(arg1, arg2, true);
2776 print_syscall_epilogue(name);
2777 }
2778 #endif
@@ -3308,7 +3327,7 @@ print_stat(CPUArchState *cpu_env, const struct syscallname *name,
3327 print_syscall_epilogue(name);
3328 }
3329 #define print_lstat print_stat
3311 -#define print_stat64 print_stat
3330 +#define print_stat64 print_stat
3331 #define print_lstat64 print_stat
3332 #endif
3333
@@ -4302,7 +4321,7 @@ print_pread64(CPUArchState *cpu_env, const struct syscallname *name,
4321 print_raw_param("%d", arg0, 0);
4322 print_pointer(arg1, 0);
4323 print_raw_param("%d", arg2, 0);
4305 - print_raw_param("%" PRIu64, target_offset64(arg3, arg4), 1);
4324 + print_file_offset64(arg3, arg4, true);
4325 print_syscall_epilogue(name);
4326 }
4327 #endif