From: Oliver Kurth Date: Tue, 5 Jun 2018 22:47:35 +0000 (-0700) Subject: vm_basic_types.h: use system headers for uint64_t, uintptr_t, size_t X-Git-Tag: stable-11.0.0~563 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=140820c8bdc0d2d83909612bc0e877eaff8ff5d0;p=thirdparty%2Fopen-vm-tools.git vm_basic_types.h: use system headers for uint64_t, uintptr_t, size_t Extensive rewrite. Basically standardizes on using stdint.h (C99) and sys/types.h (POSIX) to define interesting types, with several non-trivial caveats: - stdint.h is not available on older Windows compilers. For now, emulate with crtdefs.h + manual definitions. - Linux kernel does not provide stdint.h (gcc-4.5+ does and it's incompatible), and sys/types.h won't work at all. However, linux/types.h gives everything we need. - Linux kernel defines uint64_t as 'long long' (and uintptr_t as 'long' - yes, really), in contrast to Linux userlevel which defines uint64_t as 'long'. Send Linux kernel down a different FMT64 path so we don't get "%llx" / "%lx" mismatches. - VMM and VMKernel don't provide sys/types.h (except VMK's FreeBSD modules). Directly provide definitions here. Net effect of this change is removal of two blocks of code that provide our own definitions of uintptr_t/intptr_t/size_t/ssize_t. Also pruned a few now-unneeded stdint.h and sys/types.h includes as well. Curious observers will inquire why not get size_t from C99 standard header stddef.h. Turns out that header is EXCEPTIONALLY hard to include, which is why I'm using sys/types.h in most places. Actually using stddef.h is left for a later change. --- diff --git a/open-vm-tools/lib/include/vm_basic_types.h b/open-vm-tools/lib/include/vm_basic_types.h index 7a5cbea2d..985f2425d 100644 --- a/open-vm-tools/lib/include/vm_basic_types.h +++ b/open-vm-tools/lib/include/vm_basic_types.h @@ -159,14 +159,86 @@ #endif -#if defined(__cplusplus) && __cplusplus >= 201103L || \ - defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L || \ - defined(__APPLE__) || defined(HAVE_STDINT_H) /* - * We're using instead of below because some C++ code - * deliberately compiles without C++ include paths. + * C99 or equivalent + * Special cases: + * - Linux kernel lacks , preferring + * (and defines uintptr_t since 2.6.24, but not intptr_t) + * - Solaris collides with gcc , but has + * - VMKernel + FreeBSD collides with gcc , but has + * - VMKernel + VMM (+DECODERLIB) share macros with Linux kernel + * - Windows only added in vc10/vs2010 (MSC ver 1600), + * and WDKs lack it. + * + * NB about LLP64 in LP64 environments: + * - Apple uses 'long long' uint64_t + * - Linux kernel uses 'long long' uint64_t + * - Linux userlevel uses 'long' uint64_t */ -#include +#if !defined(VMKERNEL) && !defined(VMM) && !defined(DECODERLIB) && \ + defined(__linux__) && defined(__KERNEL__) +# include +# include +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) + typedef unsigned long uintptr_t; +#endif + typedef signed long intptr_t; +#elif (defined(__sun__) && defined(_KERNEL)) || \ + (defined(VMKERNEL) && defined(__FreeBSD__)) || \ + defined(_SYS_STDINT_H_) +# include +#elif !defined(_MSC_VER) + /* Common case */ +# include +#else + /* COMPAT: until pre-vc10 is retired */ +# include // uintptr_t + typedef unsigned __int64 uint64_t; + typedef unsigned int uint32_t; + typedef unsigned short uint16_t; + typedef unsigned char uint8_t; + + typedef __int64 int64_t; + typedef int int32_t; + typedef short int16_t; + typedef signed char int8_t; +#endif + +/* + * size_t and ssize_t, or equivalent + * Options: + * C90+ has size_t, but is incompatible with many kernels. + * POSIX has size_t and ssize_t, is always available at + * userlevel but is missing from some kernels. + * + * Special cases: + * - Linux kernel (again) does everything via + * - VMKernel may or may not have POSIX headers (tcpip only) + * - VMM does not have POSIX headers + * - Windows does not define ssize_t + */ +#if defined(VMKERNEL) || defined(VMM) || defined(DECODERLIB) + /* Guard against FreeBSD collison. */ +# if !defined(_SIZE_T_DEFINED) && !defined(_SIZE_T) +# define _SIZE_T_DEFINED +# define _SIZE_T + typedef __SIZE_TYPE__ size_t; +#endif +# if !defined(_SSIZE_T_DEFINED) +# define _SSIZE_T_DEFINED + typedef int64_t ssize_t; +# endif +#elif defined(__linux__) && defined(__KERNEL__) + /* provided size_t, ssize_t. */ +#else +# include +# if defined(_WIN64) + typedef int64_t ssize_t; +# elif defined(_WIN32) + typedef int32_t ssize_t; +# endif +#endif + typedef uint64_t uint64; typedef int64_t int64; @@ -177,40 +249,6 @@ typedef int16_t int16; typedef uint8_t uint8; typedef int8_t int8; -#else /* !HAVE_STDINT_H */ - -/* Pre-c99 or pre-c++11; use compiler extension to get 64-bit types */ -#ifdef _MSC_VER - -typedef unsigned __int64 uint64; -typedef signed __int64 int64; - -#elif __GNUC__ -# if defined(VM_X86_64) || defined(VM_ARM_64) -typedef unsigned long uint64; -typedef long int64; -# else -/* - * Only strict c90 (without extensions) lacks a 'long long' type. - * If this declaration fails ... use -std=c99 or -std=gnu90. - */ -typedef unsigned long long uint64; -typedef long long int64; -# endif -#else -# error - Need compiler define for int64/uint64 -#endif /* _MSC_VER */ - -typedef unsigned int uint32; -typedef unsigned short uint16; -typedef unsigned char uint8; - -typedef int int32; -typedef short int16; -typedef signed char int8; - -#endif /* HAVE_STDINT_H */ - /* * The _XTYPEDEF_BOOL guard prevents colliding with: @@ -241,14 +279,6 @@ typedef char Bool; #define IS_BOOL(x) (((x) & ~1) == 0) -/* - * FreeBSD (for the tools build) unconditionally defines these in - * sys/inttypes.h so don't redefine them if this file has already - * been included. [greg] - * - * This applies to Solaris as well. - */ - /* * Before trying to do the includes based on OS defines, see if we can use * feature-based defines to get as much functionality as possible @@ -257,9 +287,6 @@ typedef char Bool; #ifdef HAVE_INTTYPES_H #include #endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif #ifdef HAVE_SYS_INTTYPES_H #include #endif @@ -273,14 +300,11 @@ typedef char Bool; #if !defined(USING_AUTOCONF) # if defined(__FreeBSD__) || defined(sun) -# ifdef KLD_MODULE -# include -# else +# ifndef KLD_MODULE # if __FreeBSD_version >= 500043 # if !defined(VMKERNEL) # include # endif -# include # else # include # endif @@ -288,46 +312,10 @@ typedef char Bool; # elif defined __APPLE__ # if KERNEL # include -# include /* mostly for size_t */ -# include # else # include # include # include -# include -# endif -# elif defined __ANDROID__ -# include -# else -# if !defined(__intptr_t_defined) && !defined(intptr_t) -# ifdef VM_I386 -# define __intptr_t_defined -# if defined(VM_X86_64) -typedef int64 intptr_t; -# else -typedef int32 intptr_t; -# endif -# elif defined(VM_ARM_64) -# define __intptr_t_defined -typedef int64 intptr_t; -# elif defined(__arm__) -# define __intptr_t_defined -typedef int32 intptr_t; -# endif -# endif - -# ifndef _STDINT_H -# ifdef VM_I386 -# if defined(VM_X86_64) -typedef uint64 uintptr_t; -# else -typedef uint32 uintptr_t; -# endif -# elif defined(VM_ARM_64) -typedef uint64 uintptr_t; -# elif defined(__arm__) -typedef uint32 uintptr_t; -# endif # endif # endif #endif @@ -376,10 +364,12 @@ typedef int64 VmTimeVirtualClock; /* Virtual Clock kept in CPU cycles */ #define FMTPD "I" #define FMTH "I" #endif -#elif defined __APPLE__ - /* macOS hosts use the same formatters for 32- and 64-bit. */ +#elif defined __APPLE__ || (!defined VMKERNEL && !defined VMM && \ + !defined DECODERLIB && \ + defined __linux__ && defined __KERNEL__) + /* semi-LLP64 targets; 'long' is 64-bit, but uint64_t is 'long long' */ #define FMT64 "ll" - #if KERNEL + #if defined(__APPLE__) && KERNEL /* macOS osfmk/kern added 'z' length specifier in 10.13 */ #define FMTSZ "l" #else @@ -974,82 +964,6 @@ typedef void * UserVA; #define INFINITE_LOOP() do { } while (1) -/* - * On FreeBSD (for the tools build), size_t is typedef'd if _BSD_SIZE_T_ - * is defined. Use the same logic here so we don't define it twice. [greg] - */ -#ifdef __FreeBSD__ -# ifdef _BSD_SIZE_T_ -# undef _BSD_SIZE_T_ -# ifdef VM_I386 -# ifdef VM_X86_64 - typedef uint64 size_t; -# else - typedef uint32 size_t; -# endif -# endif /* VM_I386 */ -# endif - -# ifdef _BSD_SSIZE_T_ -# undef _BSD_SSIZE_T_ -# ifdef VM_I386 -# ifdef VM_X86_64 - typedef int64 ssize_t; -# else - typedef int32 ssize_t; -# endif -# endif /* VM_I386 */ -# endif - -#else -# if !defined(_SIZE_T) && !defined(_SIZE_T_DEFINED) -# ifdef VM_I386 -# define _SIZE_T -# ifdef VM_X86_64 - typedef uint64 size_t; -# else - typedef uint32 size_t; -# endif -# elif defined(VM_ARM_64) -# define _SIZE_T - typedef uint64 size_t; -# elif defined(__arm__) -# define _SIZE_T - typedef uint32 size_t; -# endif -# endif - -# if !defined(FROBOS) && !defined(_SSIZE_T) && !defined(_SSIZE_T_) && \ - !defined(ssize_t) && !defined(__ssize_t_defined) && \ - !defined(_SSIZE_T_DECLARED) && !defined(_SSIZE_T_DEFINED) && \ - !defined(_SSIZE_T_DEFINED_) -# ifdef VM_I386 -# define _SSIZE_T -# define __ssize_t_defined -# define _SSIZE_T_DECLARED -# define _SSIZE_T_DEFINED_ -# ifdef VM_X86_64 - typedef int64 ssize_t; -# else - typedef int32 ssize_t; -# endif -# elif defined(VM_ARM_64) -# define _SSIZE_T -# define __ssize_t_defined -# define _SSIZE_T_DECLARED -# define _SSIZE_T_DEFINED_ - typedef int64 ssize_t; -# elif defined(__arm__) -# define _SSIZE_T -# define __ssize_t_defined -# define _SSIZE_T_DECLARED -# define _SSIZE_T_DEFINED_ - typedef int32 ssize_t; -# endif -# endif - -#endif - /* * Format modifier for printing pid_t. On sun the pid_t is a ulong, but on * Linux it's an int.