[RFC PATCH] types.h: use GCC supplied typedefs if appropriate

Dave Martin Dave.Martin at arm.com
Thu Aug 8 13:43:09 EDT 2013


On Thu, Aug 08, 2013 at 01:06:50PM +0200, Ard Biesheuvel wrote:
> GCC supplies a set of builtin defines that are meant to be used in the typedefs
> for types such as uint8_t, uint16_t etc. In fact, this is exactly what the
> stdint.h header does (of which GCC supplies its own version for freestanding
> builds). So in stdint.h, the types are defined as
> 
> typedef __UINT16_TYPE__ uint16_t
> typedef __UINT32_TYPE__ uint32_t
> 
> However, types.h in the kernel contains its own type definitions for these
> stdint.h types, and these do not depend on the GCC builtins.
> 
> In the ARM world, both bare metal and glibc targeted versions of GCC are
> supported for building the kernel, and unfortunately, these do not agree on the
> definition of __UINT32_TYPE__ (likewise for __INT32_TYPE__ and __UINTPTR_TYPE__)
> - bare metal uses 'long unsigned int'
> - glibc GCC uses 'unsigned int'
> 
> The result of this is that, while it is perfectly feasible in principle to
> support code that includes 'stdint.h' by compiling with -ffreestanding, (such as
> code using NEON intrinsics, whose header 'arm_neon.h' includes 'stdint.h'), in
> practice this breaks because we may end up with conflicting type definitions for
> uint32_t (and uintptr_t) depending on whether you are using bare metal GCC or
> glibc GCC.
> 
> Arguably, this is a GCC issue because a) it does not pick up on the fact that
> 'typedef unsigned int uint32_t' and 'typedef long unsigned int uint32_t' are not
> in fact conflicting or b) it maintains this trivial difference between bare
> metal and glibc targeted build configs.
> 
> However, even if I am aware that stdint.h support or matters related to it may
> be controversial subjects, fixing it in the kernel is not /that/ obtrusive, and
> solves matters for older GCCs as well, hence this RFC patch.

This should go to LKML and linux-arch: if this change is no problem for
ARM, that doesn't mean that no other arch would be affected.

There are probably a few non-portable assumptions about the underlying
type of uint32_t floating about, particularly under drivers/ (use
of this type with printk would be the classic case).


That doesn't mean it's inappropriate to fix it, but I think this needs
a wider audience.

Cheers
---Dave

> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
> ---
>  include/linux/types.h | 55 +++++++++++++++++++++++++++++++++++++++------------
>  1 file changed, 42 insertions(+), 13 deletions(-)
> 
> diff --git a/include/linux/types.h b/include/linux/types.h
> index 4d118ba..40c5925 100644
> --- a/include/linux/types.h
> +++ b/include/linux/types.h
> @@ -33,7 +33,11 @@ typedef __kernel_gid32_t	gid_t;
>  typedef __kernel_uid16_t        uid16_t;
>  typedef __kernel_gid16_t        gid16_t;
>  
> -typedef unsigned long		uintptr_t;
> +#ifndef __UINTPTR_TYPE__
> +#define __UINTPTR_TYPE__	unsigned long
> +#endif
> +
> +typedef __UINTPTR_TYPE__	uintptr_t;
>  
>  #ifdef CONFIG_UID16
>  /* This is defined by include/asm-{arch}/posix_types.h */
> @@ -91,26 +95,51 @@ typedef unsigned short		ushort;
>  typedef unsigned int		uint;
>  typedef unsigned long		ulong;
>  
> +#ifndef __UINT8_TYPE__
> +#define __UINT8_TYPE__		__u8
> +#endif
> +#ifndef __INT8_TYPE__
> +#define __INT8_TYPE__		__s8
> +#endif
> +#ifndef __UINT16_TYPE__
> +#define __UINT16_TYPE__		__u16
> +#endif
> +#ifndef __INT16_TYPE__
> +#define __INT16_TYPE__		__s16
> +#endif
> +#ifndef __UINT32_TYPE__
> +#define __UINT32_TYPE__		__u32
> +#endif
> +#ifndef __INT32_TYPE__
> +#define __INT32_TYPE__		__s32
> +#endif
> +#ifndef __UINT64_TYPE__
> +#define __UINT64_TYPE__		__u64
> +#endif
> +#ifndef __INT64_TYPE__
> +#define __INT64_TYPE__		__s64
> +#endif
> +
>  #ifndef __BIT_TYPES_DEFINED__
>  #define __BIT_TYPES_DEFINED__
>  
> -typedef		__u8		u_int8_t;
> -typedef		__s8		int8_t;
> -typedef		__u16		u_int16_t;
> -typedef		__s16		int16_t;
> -typedef		__u32		u_int32_t;
> -typedef		__s32		int32_t;
> +typedef		__UINT8_TYPE__	u_int8_t;
> +typedef		__INT8_TYPE__	int8_t;
> +typedef		__UINT16_TYPE__	u_int16_t;
> +typedef		__INT16_TYPE__	int16_t;
> +typedef		__UINT32_TYPE__	u_int32_t;
> +typedef		__INT32_TYPE__	int32_t;
>  
>  #endif /* !(__BIT_TYPES_DEFINED__) */
>  
> -typedef		__u8		uint8_t;
> -typedef		__u16		uint16_t;
> -typedef		__u32		uint32_t;
> +typedef		__UINT8_TYPE__	uint8_t;
> +typedef		__UINT16_TYPE__	uint16_t;
> +typedef		__UINT32_TYPE__	uint32_t;
>  
>  #if defined(__GNUC__)
> -typedef		__u64		uint64_t;
> -typedef		__u64		u_int64_t;
> -typedef		__s64		int64_t;
> +typedef		__UINT64_TYPE__	uint64_t;
> +typedef		__UINT64_TYPE__	u_int64_t;
> +typedef		__INT64_TYPE__	int64_t;
>  #endif
>  
>  /* this is a special 64bit data type that is 8-byte aligned */
> -- 
> 1.8.1.2
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



More information about the linux-arm-kernel mailing list