I'm building on x86_64 GNU/Linux. There are *lots* of (1053) compiler warnings of the class:
warning: cast to pointer from integer of different size caused by the various conversions to/from host-to-target pointer and int types. On x86 the warnings mostly don't occur. An easy way to get an idea of the scale of the build problems is to review the Ubuntu build logs for x86, x86_64, powerpc, and solaris (It's a 0.9.0 build and the solaris build fails, but the x86_64 build log is clear although the line numbers don't match CVS). Fixing it looks to require a variety of fixes, from simple explicit casts in-line, to some complicated review of multiple levels of macros to decide where best to apply a fix. I am aiming to work through all 1053 errors to classify the reasons for them, and then work up a solution for each class. If you could review the details here and provide useful feedback and ides I'd be grateful. I don't want to redo work others are already doing or go against some implicit techniques hidden in the macro nesting in particular. This should be considered alongside Thayne Harbaugh's post "[RFC] linux-user (mostly syscall.c)". Thanks TJ. --- specimen details --- The first warning is also one of the most complex to unravel. It occurs in linux-user/syscall.c in functions target_to_host_cmsg() host_to_target_cmsg() It is caused by use of the macro TARGET_CMSG_FIRSTHDR (which is a reworking of the linux macro CMSG_FIRSTHDR defined in <sys/bits/socket.h>): static inline void target_to_host_cmsg(struct msghdr *msgh, struct target_msghdr *target_msgh) { struct target_cmsghdr *target_cmsg = TARGET_CMSG_FIRSTHDR(target_msgh); The macro is defined thus: linux-user/syscall_defs.h #define TARGET_CMSG_FIRSTHDR(mhdr) \ ((size_t) tswapl((mhdr)->msg_controllen) >= sizeof (struct target_cmsghdr) \ ? (struct target_cmsghdr *) tswapl((mhdr)->msg_control) : (struct target_cmsghdr *) NULL) and the pre-processor generates: struct target_cmsghdr *target_cmsg = ((size_t) tswap32((target_msgh)->msg_controllen) >= sizeof (struct target_cmsghdr) ? (struct target_cmsghdr *) tswap32((target_msgh)->msg_control) : (struct target_cmsghdr *) ((void *)0)); The issue is in the 'true' action: (struct target_cmsghdr *) tswap32((target_msgh)->msg_control) and the fact that the macro wasn't designed to handle different pointer sizes. In this case assigning a 32-bit unsigned int to a 64-bit pointer. The variables are defined as: linux-user/syscall_defs.h struct target_msghdr { ... abi_long msg_control; linux-user/qemu.h #ifdef TARGET_ABI32 typedef uint32_t abi_ulong; typedef int32_t abi_long; #define TARGET_ABI_BITS 32 and the 'tswap' function as: cpu-all.h static inline uint32_t tswap32(uint32_t s) { return s; } So the compiler assigns the 32-bit value returned by tswap32() to the 64-bit pointer 'target_cmsg'. For this case it appears the 'pure' solution would be to use additional macros along the lines of: struct target_cmsghdr *target_cmsg = TARGET_TO_HOST_PTR( TARGET_CMSG_FIRSTHDR(target_msgh)); and define new macros along the lines of TARGET_TO_HOST_PTR HOST_TO_TARGET_PTR The practical solution is to promote the 32-bit unsigned integer to a 64-bit unsigned integer (using a cast) and then let the compiler do implicit conversion to a 64-bit pointer.