[ARM PATCH] 1565/1: syscall macros clobbering returned error value
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.
Showing
Please register or sign in to comment