This is the section of disassembled code in question. It’s from a Linux kernel module compiled for 4.4.16 on ARMv7.
; Registers used:
; - r3 : unsigned long argp
0000005c mov r1, sp
00000060 bic r2, r1, #0x1fc0
00000064 bic r2, r2, #0x3f
00000068 ldr r4, [r2, #0x8]
0000006c adds r1, r3, #0x1
00000070 sbcslo r1, r1, r4
00000074 movlo r4, #0x0
00000078 cmp r4, #0x0
0000007c bne loc_dc
The stack at this point looks like this:
00 <- SP
04 [padding]
07 u8 arg_kernel
08 pushed[r4]
0c pushed[r5]
10 pushed[r6]
14 pushed[lr]
18 <Previous SP>
Here’s how I decoded this assembly into pseudo-C:
r4 = *(SP & 0xe000 + 8);
r1 = argp + 1;
if (r1 overflowed) {
r1 -= r4;
r4 = 0;
}
if (r4 == 0) {
/* jump */
}
If I got this right, I don’t really understand the purpose of this code. If I made a mistake, I really don’t understand it. Can anyone offer any insight into the purpose of these operations?