RT4335: Fix UEFI build of OBJ_NAME_new_index()
authorDavid Woodhouse <David.Woodhouse@intel.com>
Mon, 22 Feb 2016 16:29:12 +0000 (16:29 +0000)
committerRich Salz <rsalz@openssl.org>
Fri, 26 Feb 2016 16:03:28 +0000 (11:03 -0500)
We are using strcmp() as the cmp_func, where in the EDK2 environment
strcmp actually ends up being the external AsciiStrCmp() function —
an EFI library function defined with the Microsoft ABI.

This means that we can't just assign function pointers to it, since
in GCC-hosted builds the ABI of any function *not* explicitly marked
EFIAPI is the native SysV ABI.

Arguably this stupidity ought to be resolved on the UEFI side, but in
the general case that would mean that we need to provide ABI-compatible
wrappers for *all* the "standard" functions, just in case they're used
like this.

And in fact we already have a workaround here for DEC C. So instead of
playing games with casting function pointers, it's nicer just to use a
simple function to wrap the strcmp() call. That cleans up the DEC C
workaround, *and* it works around the UEFI bogosity at the same time.

Signed-off-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
crypto/objects/o_names.c

index 0a07379..5728806 100644 (file)
 #include "obj_lcl.h"
 
 /*
- * Later versions of DEC C has started to add linkage information to certain
- * functions, which makes it tricky to use them as values to regular function
- * pointers.  One way is to define a macro that takes care of casting them
- * correctly.
+ * We define this wrapper for two reasons. Firstly, later versions of
+ * DEC C add linkage information to certain functions, which makes it
+ * tricky to use them as values to regular function pointers.
+ * Secondly, in the EDK2 build environment, the strcmp function is
+ * actually an external function (AsciiStrCmp) with the Microsoft ABI,
+ * so we can't transparently assign function pointers to it.
+ * Arguably the latter is a stupidity of the UEFI environment, but
+ * since the wrapper solves the DEC C issue too, let's just use the
+ * same solution.
  */
-#ifdef OPENSSL_SYS_VMS_DECC
-# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp
+#if defined(OPENSSL_SYS_VMS_DECC) || defined(OPENSSL_SYS_UEFI)
+static int obj_strcmp(const char *a, const char *b)
+{
+       return strcmp(a, b);
+}
 #else
-# define OPENSSL_strcmp strcmp
+#define obj_strcmp strcmp
 #endif
 
 /*
@@ -83,7 +91,7 @@ int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *),
             return (0);
         }
         name_funcs->hash_func = lh_strhash;
-        name_funcs->cmp_func = OPENSSL_strcmp;
+        name_funcs->cmp_func = obj_strcmp;
         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
         sk_NAME_FUNCS_push(name_funcs_stack, name_funcs);
         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);