[PATCH] [RFC] Define lock-obj in gpg-error.h

Jörg Krause joerg.krause at embedded.rocks
Mon Mar 28 11:13:35 CEST 2016


The current mechanism for cross-compiling libgpg-error uses a cross-compiled
gen-posix-lock-obj on the target to create a lock-obj file which has to be
placed in the syscfg directory afterwards. Depending on the toolchain triplet
name the corresponding lock-obj file is used to in the configuration step by
the mkheader tool to insert the lock-obj file into gpg-error.h before
compilation.

This mechanism has some drawbacks:
1) It relies on the toolchains triplet. The toolchain triplet has to match a
   triplet in syscfg otherwise libgpg-error cannot be build. This means that
   using toolchains like armv6-rpi-linux-gnueabi, arm-none-linux-gnueabi,
   aarch64-linux-gnu, or arm-buildroot-linux-uclibcgnueabihf are not supported
   by default.
2) A toolchains triplet does not tell us about the builtin features. Consider
   a uClibc based toolchain named arm-unknown-linux-gnueabi was configured
   without thread support. Using the lock-obj file from syscfg will produce
   a wrong threads based lock-obj instead of a dummy lock-obj.
3) Cross-compiling gen-posix-lock-obj and run it on the target to output a
   lock-obj file is an unnecessary step and can be easily avoided.

The first issue might be bypassed by adding every possible triplet to syscfg,
but might up end in having a vast number of triplets. However, the second issue
cannot be avoided when using syscfg, but can be with this patch.

Cross-compiling gen-posix-lock-obj, running it on the target to output a
lock-obj defined at compile-time, copying this lock-obj file to syscfg and have
mkheader insert this information into gpg-error.h before compilation does the
same as defining the lock-obj in gpg-error.h directly. The compilation units
and so the build binaries are totally equal.

This patch was tested with three targets:
1) ARM Cortex A9 with musl based toolchain from Buildroot
2) AARCH64 (little endian) with glibc based toolchain from Linaro
3) i686 with glibc based toolchain from Sourcery CodeBench for the x86/x86_64

The following symlinks were created to allow building with the unsupported
toolchain triples:
1) arm-buildroot-linux-musleabihf -> arm-unknown-linux-gnuabihf
2) aarch64-linux-gnu -> aarch64-unknown-linux-gnu
3) no symlink required

All three tests build exactly the same binary with and without patch applied,
e.g ..:

diff libgpg-error/aarch64/orig/libgpg-error.so.0.17.0 libgpg-error/aarch64/patched/libgpg-error.so.0.17.0

.. does not output any difference.

Note that the patch was only tested for Linux targets, so further tests for
Windows and other Unixes may be required.

Signed-off-by: Jörg Krause <joerg.krause at embedded.rocks>
---
 src/gpg-error.h.in | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index f0043f3..46958a0 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -22,10 +22,24 @@
 #ifndef GPG_ERROR_H
 #define GPG_ERROR_H	1
 
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <stddef.h>
 #include <stdio.h>
 #include <stdarg.h>
 
+#ifdef USE_POSIX_THREADS
+#include <pthread.h>
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+#include "w32-lock-obj.h"
+#else
+#include "posix-lock-obj.h"
+#endif
+
 /* The version string of this header. */
 #define GPG_ERROR_VERSION @version@
 #define GPGRT_VERSION     @version@
@@ -429,7 +443,54 @@ gpg_error_from_syserror (void)
 

 /* Lock functions.  */
 
- at include:lock-obj@
+/* Special requirements for certain platforms.  */
+#if defined(__sun) && !defined (__LP64__) && !defined(_LP64)
+/* Solaris on 32-bit architecture.  */
+# define USE_DOUBLE_FOR_ALIGNMENT 1
+#else
+# define USE_DOUBLE_FOR_ALIGNMENT 0
+#endif
+#if defined(__hppa__)
+# define USE_LONG_DOUBLE_FOR_ALIGNMENT 1
+#else
+# define USE_LONG_DOUBLE_FOR_ALIGNMENT 0
+#endif
+
+#ifdef USE_POSIX_THREADS
+
+/* Check that configure did its job.  */
+#if SIZEOF_PTHREAD_MUTEX_T < 4
+# error sizeof pthread_mutex_t is not known.
+#endif
+
+typedef struct
+{
+  long _vers;
+  union {
+    volatile char _priv[SIZEOF_PTHREAD_MUTEX_T];
+# if USE_DOUBLE_FOR_ALIGNMENT
+    double _xd_align;
+# elif USE_LONG_DOUBLE_FOR_ALIGNMENT
+    long double _xld_align;
+# endif
+    long _x_align;
+    long *_xp_align;
+  } u;
+} gpgrt_lock_t;
+
+#define GPGRT_LOCK_INITIALIZER { LOCK_ABI_VERSION, PTHREAD_MUTEX_INITIALIZER }
+
+#else /* USE_POSIX_THREADS */
+
+/* Dummy object - no locking available. */
+typedef struct
+{
+  long _vers;
+} gpgrt_lock_t;
+
+#define GPGRT_LOCK_INITIALIZER { LOCK_ABI_VERSION }
+
+#endif /* USE_POSIX_THREADS */
 
 #define GPGRT_LOCK_DEFINE(name) \
   static gpgrt_lock_t name  = GPGRT_LOCK_INITIALIZER
-- 
2.7.4



More information about the Gnupg-devel mailing list