• Nicolas Pitre's avatar
    [ARM PATCH] 1565/1: syscall macros clobbering returned error value · 8d4d473c
    Nicolas Pitre authored
    Patch from Nicolas Pitre
    
    In both 2.5.70-rmk1 and 2.4.19-rmk7 the syscall macros are clobering
    the returned error value when building library code.
    
    Example code:
    
    #include <linux/unistd.h>
    #include <errno.h>
    extern int fake_syscall(int x, int y, int z);
    _syscall3(int, fake_syscall, int, x, int, y, int, z)
    
    Current generated code:
    
    fake_syscall:
            @ args = 0, pretend = 0, frame = 0
            @ frame_needed = 0, uses_anonymous_args = 0
            str     lr, [sp, #-4]!
            swi     __NR_fake_syscall
            cmn     r0, #126
            ldrls   pc, [sp], #4
            bl      __errno_location
            rsb     r3, r0, #0
            str     r3, [r0, #0]
            mvn     r0, #0
            ldr     pc, [sp], #4
    
    In the code above, whenever the return value is an error code, it
    is lost due to the call to __errno_location. And because of the
    asm("r0") constraint on the variable __res the compiler continues
    using r0 for it even if it's now a pointer value.  errno ends up with
    a totally bogus value.
    
    With the patch below the above code becomes:
    
    fake_syscall:
            @ args = 0, pretend = 0, frame = 0
            @ frame_needed = 0, uses_anonymous_args = 0
            stmfd   sp!, {r4, lr}
            swi     __NR_fake_syscall
            cmn     r0, #126
            mov     r4, r0
            bls     .L3
            bl      __errno_location
            rsb     r3, r4, #0
            str     r3, [r0, #0]
            mvn     r4, #0
    .L3:
            mov     r0, r4
            ldmfd   sp!, {r4, pc}
    
    which is correct.
    
    Oh and added a small estetic change for generated code too.
    8d4d473c
unistd.h 19 KB