summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Hommey <mh@glandium.org>2018-07-26 20:39:36 +0900
committerMike Hommey <mh@glandium.org>2018-07-26 20:39:36 +0900
commit7af31ef9525575fa5dffb8d66ac9a454dec57f44 (patch)
tree76a305f3f49bd42c72dd56e6c0e43ceaeb17ea33
parent3ad31a1eb31928145526a8443b5dcaad54b2d786 (diff)
downloadnss-hg-7af31ef9525575fa5dffb8d66ac9a454dec57f44.tar.gz
Bug 1478623 - Add r/w constraints to modified registers to asm blocks in mpi_arm.c. r=fkiefer
While bug 1477929 fixed the obvious build failure, it still allowed the compiler to break things when it inlines the mpi_arm.c functions into its callers via LTO. The problem is that all those assembly blocks take a length as input in a register, and decrement that register. They also update both registers they're passed in with pointers, via post-indexed offsets on ldr and str. But the constraints are not explicit about those writes to the registers, so the compiler may decide to reuse them as if they had their original value in code following the inlined code. It actually happily does so, which leads to interesting crashes.
-rw-r--r--lib/freebl/mpi/mpi_arm.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/lib/freebl/mpi/mpi_arm.c b/lib/freebl/mpi/mpi_arm.c
index 521bb462a..27e4efdad 100644
--- a/lib/freebl/mpi/mpi_arm.c
+++ b/lib/freebl/mpi/mpi_arm.c
@@ -29,17 +29,17 @@ s_mpv_mul_d(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
"1:\n"
"mov r4, #0\n"
"ldr r6, [%0], #4\n"
- "umlal r5, r4, r6, %2\n"
- "str r5, [%3], #4\n"
+ "umlal r5, r4, r6, %3\n"
+ "str r5, [%2], #4\n"
"mov r5, r4\n"
"subs %1, #1\n"
"bne 1b\n"
"2:\n"
- "str r5, [%3]\n"
- :
- : "r"(a), "l"(a_len), "r"(b), "r"(c)
+ "str r5, [%2]\n"
+ : "+r"(a), "+l"(a_len), "+r"(c)
+ : "r"(b)
: "memory", "cc", "%r4", "%r5", "%r6");
}
@@ -57,22 +57,22 @@ s_mpv_mul_d_add(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
"1:\n"
"mov r4, #0\n"
- "ldr r6, [%3]\n"
+ "ldr r6, [%2]\n"
"adds r5, r6\n"
"adc r4, r4, #0\n"
"ldr r6, [%0], #4\n"
- "umlal r5, r4, r6, %2\n"
- "str r5, [%3], #4\n"
+ "umlal r5, r4, r6, %3\n"
+ "str r5, [%2], #4\n"
"mov r5, r4\n"
"subs %1, #1\n"
"bne 1b\n"
"2:\n"
- "str r5, [%3]\n"
- :
- : "r"(a), "l"(a_len), "r"(b), "r"(c)
+ "str r5, [%2]\n"
+ : "+r"(a), "+l"(a_len), "+r"(c)
+ : "r"(b)
: "memory", "cc", "%r4", "%r5", "%r6");
}
@@ -87,12 +87,12 @@ s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
"1:\n"
"mov r4, #0\n"
- "ldr r6, [%3]\n"
+ "ldr r6, [%2]\n"
"adds r5, r6\n"
"adc r4, r4, #0\n"
"ldr r6, [%0], #4\n"
- "umlal r5, r4, r6, %2\n"
- "str r5, [%3], #4\n"
+ "umlal r5, r4, r6, %3\n"
+ "str r5, [%2], #4\n"
"mov r5, r4\n"
"subs %1, #1\n"
@@ -107,16 +107,16 @@ s_mpv_mul_d_add_prop(const mp_digit *a, mp_size a_len, mp_digit b, mp_digit *c)
"2:\n"
"mov r4, #0\n"
- "ldr r6, [%3]\n"
+ "ldr r6, [%2]\n"
"adds r5, r6\n"
"adc r4, r4, #0\n"
- "str r5, [%3], #4\n"
+ "str r5, [%2], #4\n"
"movs r5, r4\n"
"bne 2b\n"
"3:\n"
- :
- : "r"(a), "r"(a_len), "r"(b), "r"(c)
+ : "+r"(a), "+l"(a_len), "+r"(c)
+ : "r"(b)
: "memory", "cc", "%r4", "%r5", "%r6");
}
#endif
@@ -167,8 +167,8 @@ s_mpv_sqr_add_prop(const mp_digit *pa, mp_size a_len, mp_digit *ps)
"bne 2b\n"
"3:"
+ : "+r"(pa), "+r"(a_len), "+r"(ps)
:
- : "r"(pa), "r"(a_len), "r"(ps)
: "memory", "cc", "%r3", "%r4", "%r5", "%r6");
}
#endif