State of register edx on valgrind-freebsd after syscall
karnajit wangkhem
karnajitw at gmail.com
Tue Dec 3 07:36:17 UTC 2019
Hi All,
Below is the valgrind-freebsd I used
https://www.freshports.org/devel/valgrind
https://bitbucket.org/stass/valgrind-freebsd/get/ce1acb28953f.tar.gz?dummy=/
$ ./valgrind --version
valgrind-3.10.1
Please consider the following assembly
============================================================
.section .data
.long 0 /* Valgrind segfaults without this dummy */
.section .text
.global _start
STR0:
.ascii "Hello World\n"
kernel:
int $0x80
ret
_start:
mov $2, %ebx /* Store value 2, 3, 4 in reg ebx, ecx, edx */
mov $3, %ecx
mov $4, %edx
push $12 /* Push arguments on stack as per x86 freebsd
convention */
push $STR0
push $1
mov $4, %eax /* write syscall no == 4 */
call kernel
add %ebx, %eax /* Now lets add all the GP registers */
add %ecx, %eax
add %edx, %eax
push %eax /* We expect 4(edx) + 3(ecx) + 2(ebx) + 12(eax) ==
21 */
mov $1, %eax /* Perform exit syscall */
call kernel
============================================================
compile:
$ clang --target=i386-unknown-freebsd10.3 -nostdlib -nostdinc reg_minimal.s
$ ./a.out
Hello World
$ echo $?
21
$ ./valgrind ./a.out
==69326== Memcheck, a memory error detector
==69326== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==69326== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==69326== Command: ./a.out
==69326==
Hello World
==69326==
==69326== HEAP SUMMARY:
==69326== in use at exit: 0 bytes in 0 blocks
==69326== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==69326==
==69326== All heap blocks were freed -- no leaks are possible
==69326==
==69326== For counts of detected and suppressed errors, rerun with: -v
==69326== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ echo $?
177 <<<<<<<<<< This is
wrong
Now, if we modify the code slightly to return %edx instead, the return
value will looks like this
$ echo $?
160
So, the reason why eax + ebx + ecx + edx returned 177 instead of 21 was
because register edx has been clobbered by valgrind instrumentation of
syscall.
In case of linux, the syscall calling convention is bit different and we
need to pass the arguments in registers ebx, ecx, edx, but even after the
syscall, these register value holds the same argument values
(valgrind-linux valgrind-3.7.0).
Could someone give a pointer to which part of the freebsd-valgrind code
could be responsible for this bug? Or if possible where I can fix this?
Regards,
Karan
More information about the freebsd-hackers
mailing list