Merge pull request #6096 from tom-cosgrove-arm/bn_mul-fix-x86-pic-compilation-for-gcc-4-2.28

Backport 2.28: bn_mul.h: fix x86 PIC inline ASM compilation with GCC < 5
diff --git a/ChangeLog.d/bn_mul-fix-x86-pic-compilation-for-gcc-4.txt b/ChangeLog.d/bn_mul-fix-x86-pic-compilation-for-gcc-4.txt
new file mode 100644
index 0000000..1d59c22
--- /dev/null
+++ b/ChangeLog.d/bn_mul-fix-x86-pic-compilation-for-gcc-4.txt
@@ -0,0 +1,4 @@
+Bugfix
+   * Fix a long-standing build failure when building x86 PIC code with old
+     gcc (4.x). The code will be slower, but will compile. We do however
+     recommend upgrading to a more recent compiler instead. Fixes #1910.
diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
index 31137cd..029eff2 100644
--- a/include/mbedtls/bn_mul.h
+++ b/include/mbedtls/bn_mul.h
@@ -95,12 +95,28 @@
     ( !defined(__ARMCC_VERSION) || __ARMCC_VERSION >= 6000000 )
 
 /*
+ * GCC < 5.0 treated the x86 ebx (which is used for the GOT) as a
+ * fixed reserved register when building as PIC, leading to errors
+ * like: bn_mul.h:46:13: error: PIC register clobbered by 'ebx' in 'asm'
+ *
+ * This is fixed by an improved register allocator in GCC 5+. From the
+ * release notes:
+ * Register allocation improvements: Reuse of the PIC hard register,
+ * instead of using a fixed register, was implemented on x86/x86-64
+ * targets. This improves generated PIC code performance as more hard
+ * registers can be used.
+ */
+#if defined(__GNUC__) && __GNUC__ < 5 && defined(__PIC__)
+#define MULADDC_CANNOT_USE_EBX
+#endif
+
+/*
  * Disable use of the i386 assembly code below if option -O0, to disable all
  * compiler optimisations, is passed, detected with __OPTIMIZE__
  * This is done as the number of registers used in the assembly code doesn't
  * work with the -O0 option.
  */
-#if defined(__i386__) && defined(__OPTIMIZE__)
+#if defined(__i386__) && defined(__OPTIMIZE__) && !defined(MULADDC_CANNOT_USE_EBX)
 
 #define MULADDC_INIT                        \
     asm(                                    \