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