Fix pointer size issues on VMS
authorRichard Levitte <levitte@openssl.org>
Wed, 30 Mar 2016 04:40:37 +0000 (06:40 +0200)
committerRichard Levitte <levitte@openssl.org>
Wed, 30 Mar 2016 18:25:08 +0000 (20:25 +0200)
On VMS, the C compiler can work with 32-bit and 64-bit pointers, and
the command line determines what the initial pointer size shall be.

However, there is some functionality that only works with 32-bit
pointers.  In this case, it's gethostbyname(), getservbyname() and
accompanying structures, so we need to make sure that we define our
own pointers as 32-bit ones.

Furthermore, there seems to be a bug in VMS C netdb.h, where struct
addrinfo is always defined with 32-bit pointers no matter what, but
the functions handling it are adapted to the initial pointer size.
This leads to pointer size warnings when compiling with
/POINTER_SIZE=64.  The workaround is to force struct addrinfo to be
the 64-bit variant if the initial pointer size is 64.

Reviewed-by: Andy Polyakov <appro@openssl.org>
crypto/bio/b_addr.c
crypto/bio/bio_lcl.h

index 663ec2ee071837f70311f55f0c1378e915e37cb6..ed4c1397d97bc9ba3839a654081adf9eb7ac6d48 100644 (file)
@@ -722,6 +722,15 @@ int BIO_lookup(const char *host, const char *service,
     } else {
 #endif
         const struct hostent *he;
+/*
+ * Because struct hostent is defined for 32-bit pointers only with
+ * VMS C, we need to make sure that '&he_fallback_address' and
+ * '&he_fallback_addresses' are 32-bit pointers
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
         /* Windows doesn't seem to have in_addr_t */
 #ifdef OPENSSL_SYS_WINDOWS
         static uint32_t he_fallback_address;
@@ -735,6 +744,10 @@ int BIO_lookup(const char *host, const char *service,
         static const struct hostent he_fallback =
             { NULL, NULL, AF_INET, sizeof(he_fallback_address),
               (char **)&he_fallback_addresses };
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
+
         struct servent *se;
         /* Apprently, on WIN64, s_proto and s_port have traded places... */
 #ifdef _WIN64
@@ -782,7 +795,19 @@ int BIO_lookup(const char *host, const char *service,
         } else {
             char *endp = NULL;
             long portnum = strtol(service, &endp, 10);
+
+/*
+ * Because struct servent is defined for 32-bit pointers only with
+ * VMS C, we need to make sure that 'proto' is a 32-bit pointer.
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
             char *proto = NULL;
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
 
             switch (socktype) {
             case SOCK_STREAM:
@@ -819,7 +844,19 @@ int BIO_lookup(const char *host, const char *service,
         *res = NULL;
 
         {
+/*
+ * Because hostent::h_addr_list is an array of 32-bit pointers with VMS C,
+ * we must make sure our iterator designates the same element type, hence
+ * the pointer size dance.
+ */
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size save
+# pragma pointer_size 32
+#endif
             char **addrlistp;
+#if defined(OPENSSL_SYS_VMS) && defined(__DECC)
+# pragma pointer_size restore
+#endif
             size_t addresses;
             BIO_ADDRINFO *tmp_bai = NULL;
 
index 1e409f8e134f8c55c8fea48851c60ccf2ef80590..7f3b22268a1e530c6f610bfc6f8e0eacc7f3381c 100644 (file)
 # endif
 
 # ifdef AI_PASSIVE
+
+/*
+ * There's a bug in VMS C header file netdb.h, where struct addrinfo
+ * always is the P32 variant, but the functions that handle that structure,
+ * such as getaddrinfo() and freeaddrinfo() adapt to the initial pointer
+ * size.  The easiest workaround is to force struct addrinfo to be the
+ * 64-bit variant when compiling in P64 mode.
+ */
+#  if defined(OPENSSL_SYS_VMS) && __INITIAL_POINTER_SIZE == 64
+#   define addrinfo __addrinfo64
+#  endif
+
 #  define bio_addrinfo_st addrinfo
 #  define bai_family      ai_family
 #  define bai_socktype    ai_socktype