Skip to contentSkip to conversation

ARM: teach __asmeq that r12 and ip are the same register

PATCH New Ard Biesheuvel 3 participants 4 messages Jan 28, 2015 Arm (32-bit)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ARM: teach __asmeq that r12 and ip are the same register

The __asmeq macro is used inside inline asm statements to ensure that register asm variables that explicitly specify a register are mapped correctly onto those registers when used in inline asm input and output constraints. However, the string based matching fails to take into account that 'ip' may also be referred to as 'r12', (e.g., by clang), causing false negatives.

Fix this by making __asmeq consider the ("ip","r12") and ("r12","ip") cases specifically.

---
Even though clang shouldn't be susceptible to the same bug, there is still value in retaining these assertions there, so instead of just turning __asmeq into a nop if __clang__ is defined, let's make it work correctly.

 arch/arm/include/asm/compiler.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/include/asm/compiler.h +4 -1
index 8155db2f7fa1..c3a316a59710 100644
@@ -8,8 +8,11 @@
  * This string is meant to be concatenated with the inline asm string and
  * will cause compilation to stop on mismatch.
  * (for details, see gcc PR 15089)
+ * For compatibility with clang, we have to explicitly take the equivalence
+ * of 'r12' and 'ip into account as well.
  */
-#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .ifnc " x y ",ipr12 ; " \
+	".ifnc " x y ",r12ip ; .err ; .endif ; .endif ; .endif\n\t"
 
 
 #endif /* __ASM_ARM_COMPILER_H */
Signature · 1 line
1.8.3.2
#1 lore raw

PATCH 1/1 ARM: teach __asmeq that r12 and ip are the same register

Quoted 11 lines · Ard Biesheuvel

The __asmeq macro is used inside inline asm statements to ensure that register asm variables that explicitly specify a register are mapped correctly onto those registers when used in inline asm input and output constraints. However, the string based matching fails to take into account that 'ip' may also be referred to as 'r12', (e.g., by clang), causing false negatives.

Fix this by making __asmeq consider the ("ip","r12") and ("r12","ip") cases specifically.

gcc is likely to do the same substitution with r10 ("sl") and r11 ("fp"). Might as well add them right away for completeness.

Then, does clang call sp, lr, pc as r13, r14 and r15? I guess not as this is probably against the latest ARM assembly conventions.

Quoted 29 lines

---
Even though clang shouldn't be susceptible to the same bug, there is still value in retaining these assertions there, so instead of just turning __asmeq into a nop if __clang__ is defined, let's make it work correctly.

 arch/arm/include/asm/compiler.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/include/asm/compiler.h +4 -1
index 8155db2f7fa1..c3a316a59710 100644
@@ -8,8 +8,11 @@
  * This string is meant to be concatenated with the inline asm string and
  * will cause compilation to stop on mismatch.
  * (for details, see gcc PR 15089)
+ * For compatibility with clang, we have to explicitly take the equivalence
+ * of 'r12' and 'ip into account as well.
  */
-#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .ifnc " x y ",ipr12 ; " \
+	".ifnc " x y ",r12ip ; .err ; .endif ; .endif ; .endif\n\t"
 
 
 #endif /* __ASM_ARM_COMPILER_H */
Signature · 1 line
1.8.3.2
#2 lore raw

PATCH 1/1 ARM: teach __asmeq that r12 and ip are the same register

Quoted 9 lines · Nicolas Pitre
Quoted 7 lines · Ard Biesheuvel

The __asmeq macro is used inside inline asm statements to ensure that register asm variables that explicitly specify a register are mapped correctly onto those registers when used in inline asm input and output constraints. However, the string based matching fails to take into account that 'ip' may also be referred to as 'r12', (e.g., by clang), causing false negatives.

Quoted 8 lines
Quoted 4 lines

Fix this by making __asmeq consider the ("ip","r12") and ("r12","ip") cases specifically.

gcc is likely to do the same substitution with r10 ("sl") and r11 ("fp"). Might as well add them right away for completeness.

I just checked with my 4.8 gcc toolchain: r11 indeed gets emitted as fp when used in inline asm, but r10 is just r10.
So I should update the patch to include fp as well.

Quoted 3 lines

Then, does clang call sp, lr, pc as r13, r14 and r15? I guess not as this is probably against the latest ARM assembly conventions.

@Behan, could you answer this one?

Quoted 29 lines
Quoted 29 lines

---
Even though clang shouldn't be susceptible to the same bug, there is still value in retaining these assertions there, so instead of just turning __asmeq into a nop if __clang__ is defined, let's make it work correctly.

 arch/arm/include/asm/compiler.h | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
arch/arm/include/asm/compiler.h +4 -2
index 8155db2f7fa1..c3a316a59710 100644
@@ -8,8 +8,11 @@
  * This string is meant to be concatenated with the inline asm string and
  * will cause compilation to stop on mismatch.
  * (for details, see gcc PR 15089)
+ * For compatibility with clang, we have to explicitly take the equivalence
+ * of 'r12' and 'ip into account as well.
  */
-#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .ifnc " x y ",ipr12 ; " \
+     ".ifnc " x y ",r12ip ; .err ; .endif ; .endif ; .endif\n\t"
 
 
 #endif /* __ASM_ARM_COMPILER_H */
--

1.8.3.2

#3 lore raw

PATCH 1/1 ARM: teach __asmeq that r12 and ip are the same register

Quoted 17 lines · Ard Biesheuvel
Quoted 9 lines · Nicolas Pitre
Quoted 7 lines · Ard Biesheuvel

The __asmeq macro is used inside inline asm statements to ensure that register asm variables that explicitly specify a register are mapped correctly onto those registers when used in inline asm input and output constraints. However, the string based matching fails to take into account that 'ip' may also be referred to as 'r12', (e.g., by clang), causing false negatives.

Quoted 7 lines
Quoted 4 lines

Fix this by making __asmeq consider the ("ip","r12") and ("r12","ip") cases specifically.

gcc is likely to do the same substitution with r10 ("sl") and r11 ("fp"). Might as well add them right away for completeness.

Quoted 8 lines

I just checked with my 4.8 gcc toolchain: r11 indeed gets emitted as fp when used in inline asm, but r10 is just r10.
So I should update the patch to include fp as well.

Quoted 3 lines

Then, does clang call sp, lr, pc as r13, r14 and r15? I guess not as this is probably against the latest ARM assembly conventions.

@Behan, could you answer this one?

These are aliased in clang as one would expect.

Behan

Signature · 2 lines
Behan Webster
behanw at converseincode.com