O
O
Oleg2011-09-15 19:08:47
linux
Oleg, 2011-09-15 19:08:47

Arm assembler in Linux kernel?

Good afternoon! Poking around in the Linux kernel sorts, under the ARM architecture, I found the following code, which is used in the copy_from_user function:

#define __range_ok(addr,size) ({ \<br/>
 unsigned long flag, roksum; \<br/>
 __chk_user_ptr(addr); \<br/>
 __asm__(&quot;adds %1, %2, %3; sbcccs %1, %1, %0; movcc %0, #0&quot; \<br/>
 : &quot;=&r&quot; (flag), &quot;=&r&quot; (roksum) \<br/>
 : &quot;r&quot; (addr), &quot;Ir&quot; (size), &quot;&quot; (current_thread_info()-&gt;addr_limit) \<br/>
 : &quot;cc&quot;); \<br/>
 flag; })<br/>

I can't quite figure it out. I already asked a question on stackoverflow, they gave me a link to the documentation and a couple of useful tips, it cleared things up a bit. The fact is that subtraction with a transfer is used here, respectively, the Carry flag is actively used.
As I understand this code:
We add the value of addr and size, the result falls into roksum (?)
We subtract the value of addr_limit from roksum with the transfer, but only if the carry flag is clean (?), the result falls. As a result of the operation, we set or do not set the same carry flag.
If the carry flag was not set, we move the value 0 to the r0 register.
What is not clear: where and how the flag is used, as well as how the result of sbcccs is interpreted, i.e. if an overflow occurs, set the carry flag? And what value, in the end, is given as a result?
I hope someone can help sort out this issue.
Thank you!

Answer the question

In order to leave comments, you need to log in

1 answer(s)
A
apangin, 2011-09-15
@elenbert

flag is used as the return value (note the last line).
As a result, __range_ok will return 0 if and only if addr + size <= addr_limit and no overflow has occurred on addition.
It works like this:
0. flag = addr_limit (assuming addr_limit != 0);
1. roksum = addr + size;
2. if there was no overflow in item 1, then roksum = roksum - addr_limit - 1;
3. if after step 2 rok_sum >= 0, then flag = 0

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question