1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Compatibility interface for userspace libc header coordination: 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Define compatibility macros that are used to control the inclusion or 6*4882a593Smuzhiyun * exclusion of UAPI structures and definitions in coordination with another 7*4882a593Smuzhiyun * userspace C library. 8*4882a593Smuzhiyun * 9*4882a593Smuzhiyun * This header is intended to solve the problem of UAPI definitions that 10*4882a593Smuzhiyun * conflict with userspace definitions. If a UAPI header has such conflicting 11*4882a593Smuzhiyun * definitions then the solution is as follows: 12*4882a593Smuzhiyun * 13*4882a593Smuzhiyun * * Synchronize the UAPI header and the libc headers so either one can be 14*4882a593Smuzhiyun * used and such that the ABI is preserved. If this is not possible then 15*4882a593Smuzhiyun * no simple compatibility interface exists (you need to write translating 16*4882a593Smuzhiyun * wrappers and rename things) and you can't use this interface. 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * Then follow this process: 19*4882a593Smuzhiyun * 20*4882a593Smuzhiyun * (a) Include libc-compat.h in the UAPI header. 21*4882a593Smuzhiyun * e.g. #include <linux/libc-compat.h> 22*4882a593Smuzhiyun * This include must be as early as possible. 23*4882a593Smuzhiyun * 24*4882a593Smuzhiyun * (b) In libc-compat.h add enough code to detect that the comflicting 25*4882a593Smuzhiyun * userspace libc header has been included first. 26*4882a593Smuzhiyun * 27*4882a593Smuzhiyun * (c) If the userspace libc header has been included first define a set of 28*4882a593Smuzhiyun * guard macros of the form __UAPI_DEF_FOO and set their values to 1, else 29*4882a593Smuzhiyun * set their values to 0. 30*4882a593Smuzhiyun * 31*4882a593Smuzhiyun * (d) Back in the UAPI header with the conflicting definitions, guard the 32*4882a593Smuzhiyun * definitions with: 33*4882a593Smuzhiyun * #if __UAPI_DEF_FOO 34*4882a593Smuzhiyun * ... 35*4882a593Smuzhiyun * #endif 36*4882a593Smuzhiyun * 37*4882a593Smuzhiyun * This fixes the situation where the linux headers are included *after* the 38*4882a593Smuzhiyun * libc headers. To fix the problem with the inclusion in the other order the 39*4882a593Smuzhiyun * userspace libc headers must be fixed like this: 40*4882a593Smuzhiyun * 41*4882a593Smuzhiyun * * For all definitions that conflict with kernel definitions wrap those 42*4882a593Smuzhiyun * defines in the following: 43*4882a593Smuzhiyun * #if !__UAPI_DEF_FOO 44*4882a593Smuzhiyun * ... 45*4882a593Smuzhiyun * #endif 46*4882a593Smuzhiyun * 47*4882a593Smuzhiyun * This prevents the redefinition of a construct already defined by the kernel. 48*4882a593Smuzhiyun */ 49*4882a593Smuzhiyun #ifndef _UAPI_LIBC_COMPAT_H 50*4882a593Smuzhiyun #define _UAPI_LIBC_COMPAT_H 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /* We have included glibc headers... */ 53*4882a593Smuzhiyun #if defined(__GLIBC__) 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /* Coordinate with glibc net/if.h header. */ 56*4882a593Smuzhiyun #if defined(_NET_IF_H) && defined(__USE_MISC) 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* GLIBC headers included first so don't define anything 59*4882a593Smuzhiyun * that would already be defined. */ 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFCONF 0 62*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFMAP 0 63*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFNAMSIZ 0 64*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFREQ 0 65*4882a593Smuzhiyun /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ 66*4882a593Smuzhiyun #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 0 67*4882a593Smuzhiyun /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ 68*4882a593Smuzhiyun #ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 69*4882a593Smuzhiyun #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 70*4882a593Smuzhiyun #endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */ 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun #else /* _NET_IF_H */ 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun /* Linux headers included first, and we must define everything 75*4882a593Smuzhiyun * we need. The expectation is that glibc will check the 76*4882a593Smuzhiyun * __UAPI_DEF_* defines and adjust appropriately. */ 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFCONF 1 79*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFMAP 1 80*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFNAMSIZ 1 81*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFREQ 1 82*4882a593Smuzhiyun /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ 83*4882a593Smuzhiyun #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 84*4882a593Smuzhiyun /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ 85*4882a593Smuzhiyun #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun #endif /* _NET_IF_H */ 88*4882a593Smuzhiyun 89*4882a593Smuzhiyun /* Coordinate with glibc netinet/in.h header. */ 90*4882a593Smuzhiyun #if defined(_NETINET_IN_H) 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun /* GLIBC headers included first so don't define anything 93*4882a593Smuzhiyun * that would already be defined. */ 94*4882a593Smuzhiyun #define __UAPI_DEF_IN_ADDR 0 95*4882a593Smuzhiyun #define __UAPI_DEF_IN_IPPROTO 0 96*4882a593Smuzhiyun #define __UAPI_DEF_IN_PKTINFO 0 97*4882a593Smuzhiyun #define __UAPI_DEF_IP_MREQ 0 98*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IN 0 99*4882a593Smuzhiyun #define __UAPI_DEF_IN_CLASS 0 100*4882a593Smuzhiyun 101*4882a593Smuzhiyun #define __UAPI_DEF_IN6_ADDR 0 102*4882a593Smuzhiyun /* The exception is the in6_addr macros which must be defined 103*4882a593Smuzhiyun * if the glibc code didn't define them. This guard matches 104*4882a593Smuzhiyun * the guard in glibc/inet/netinet/in.h which defines the 105*4882a593Smuzhiyun * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */ 106*4882a593Smuzhiyun #if defined(__USE_MISC) || defined (__USE_GNU) 107*4882a593Smuzhiyun #define __UAPI_DEF_IN6_ADDR_ALT 0 108*4882a593Smuzhiyun #else 109*4882a593Smuzhiyun #define __UAPI_DEF_IN6_ADDR_ALT 1 110*4882a593Smuzhiyun #endif 111*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IN6 0 112*4882a593Smuzhiyun #define __UAPI_DEF_IPV6_MREQ 0 113*4882a593Smuzhiyun #define __UAPI_DEF_IPPROTO_V6 0 114*4882a593Smuzhiyun #define __UAPI_DEF_IPV6_OPTIONS 0 115*4882a593Smuzhiyun #define __UAPI_DEF_IN6_PKTINFO 0 116*4882a593Smuzhiyun #define __UAPI_DEF_IP6_MTUINFO 0 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun #else 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun /* Linux headers included first, and we must define everything 121*4882a593Smuzhiyun * we need. The expectation is that glibc will check the 122*4882a593Smuzhiyun * __UAPI_DEF_* defines and adjust appropriately. */ 123*4882a593Smuzhiyun #define __UAPI_DEF_IN_ADDR 1 124*4882a593Smuzhiyun #define __UAPI_DEF_IN_IPPROTO 1 125*4882a593Smuzhiyun #define __UAPI_DEF_IN_PKTINFO 1 126*4882a593Smuzhiyun #define __UAPI_DEF_IP_MREQ 1 127*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IN 1 128*4882a593Smuzhiyun #define __UAPI_DEF_IN_CLASS 1 129*4882a593Smuzhiyun 130*4882a593Smuzhiyun #define __UAPI_DEF_IN6_ADDR 1 131*4882a593Smuzhiyun /* We unconditionally define the in6_addr macros and glibc must 132*4882a593Smuzhiyun * coordinate. */ 133*4882a593Smuzhiyun #define __UAPI_DEF_IN6_ADDR_ALT 1 134*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IN6 1 135*4882a593Smuzhiyun #define __UAPI_DEF_IPV6_MREQ 1 136*4882a593Smuzhiyun #define __UAPI_DEF_IPPROTO_V6 1 137*4882a593Smuzhiyun #define __UAPI_DEF_IPV6_OPTIONS 1 138*4882a593Smuzhiyun #define __UAPI_DEF_IN6_PKTINFO 1 139*4882a593Smuzhiyun #define __UAPI_DEF_IP6_MTUINFO 1 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun #endif /* _NETINET_IN_H */ 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /* Coordinate with glibc netipx/ipx.h header. */ 144*4882a593Smuzhiyun #if defined(__NETIPX_IPX_H) 145*4882a593Smuzhiyun 146*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IPX 0 147*4882a593Smuzhiyun #define __UAPI_DEF_IPX_ROUTE_DEFINITION 0 148*4882a593Smuzhiyun #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 0 149*4882a593Smuzhiyun #define __UAPI_DEF_IPX_CONFIG_DATA 0 150*4882a593Smuzhiyun #define __UAPI_DEF_IPX_ROUTE_DEF 0 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun #else /* defined(__NETIPX_IPX_H) */ 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IPX 1 155*4882a593Smuzhiyun #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 156*4882a593Smuzhiyun #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 157*4882a593Smuzhiyun #define __UAPI_DEF_IPX_CONFIG_DATA 1 158*4882a593Smuzhiyun #define __UAPI_DEF_IPX_ROUTE_DEF 1 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun #endif /* defined(__NETIPX_IPX_H) */ 161*4882a593Smuzhiyun 162*4882a593Smuzhiyun /* Definitions for xattr.h */ 163*4882a593Smuzhiyun #if defined(_SYS_XATTR_H) 164*4882a593Smuzhiyun #define __UAPI_DEF_XATTR 0 165*4882a593Smuzhiyun #else 166*4882a593Smuzhiyun #define __UAPI_DEF_XATTR 1 167*4882a593Smuzhiyun #endif 168*4882a593Smuzhiyun 169*4882a593Smuzhiyun /* If we did not see any headers from any supported C libraries, 170*4882a593Smuzhiyun * or we are being included in the kernel, then define everything 171*4882a593Smuzhiyun * that we need. Check for previous __UAPI_* definitions to give 172*4882a593Smuzhiyun * unsupported C libraries a way to opt out of any kernel definition. */ 173*4882a593Smuzhiyun #else /* !defined(__GLIBC__) */ 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun /* Definitions for if.h */ 176*4882a593Smuzhiyun #ifndef __UAPI_DEF_IF_IFCONF 177*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFCONF 1 178*4882a593Smuzhiyun #endif 179*4882a593Smuzhiyun #ifndef __UAPI_DEF_IF_IFMAP 180*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFMAP 1 181*4882a593Smuzhiyun #endif 182*4882a593Smuzhiyun #ifndef __UAPI_DEF_IF_IFNAMSIZ 183*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFNAMSIZ 1 184*4882a593Smuzhiyun #endif 185*4882a593Smuzhiyun #ifndef __UAPI_DEF_IF_IFREQ 186*4882a593Smuzhiyun #define __UAPI_DEF_IF_IFREQ 1 187*4882a593Smuzhiyun #endif 188*4882a593Smuzhiyun /* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */ 189*4882a593Smuzhiyun #ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS 190*4882a593Smuzhiyun #define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1 191*4882a593Smuzhiyun #endif 192*4882a593Smuzhiyun /* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */ 193*4882a593Smuzhiyun #ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 194*4882a593Smuzhiyun #define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1 195*4882a593Smuzhiyun #endif 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun /* Definitions for in.h */ 198*4882a593Smuzhiyun #ifndef __UAPI_DEF_IN_ADDR 199*4882a593Smuzhiyun #define __UAPI_DEF_IN_ADDR 1 200*4882a593Smuzhiyun #endif 201*4882a593Smuzhiyun #ifndef __UAPI_DEF_IN_IPPROTO 202*4882a593Smuzhiyun #define __UAPI_DEF_IN_IPPROTO 1 203*4882a593Smuzhiyun #endif 204*4882a593Smuzhiyun #ifndef __UAPI_DEF_IN_PKTINFO 205*4882a593Smuzhiyun #define __UAPI_DEF_IN_PKTINFO 1 206*4882a593Smuzhiyun #endif 207*4882a593Smuzhiyun #ifndef __UAPI_DEF_IP_MREQ 208*4882a593Smuzhiyun #define __UAPI_DEF_IP_MREQ 1 209*4882a593Smuzhiyun #endif 210*4882a593Smuzhiyun #ifndef __UAPI_DEF_SOCKADDR_IN 211*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IN 1 212*4882a593Smuzhiyun #endif 213*4882a593Smuzhiyun #ifndef __UAPI_DEF_IN_CLASS 214*4882a593Smuzhiyun #define __UAPI_DEF_IN_CLASS 1 215*4882a593Smuzhiyun #endif 216*4882a593Smuzhiyun 217*4882a593Smuzhiyun /* Definitions for in6.h */ 218*4882a593Smuzhiyun #ifndef __UAPI_DEF_IN6_ADDR 219*4882a593Smuzhiyun #define __UAPI_DEF_IN6_ADDR 1 220*4882a593Smuzhiyun #endif 221*4882a593Smuzhiyun #ifndef __UAPI_DEF_IN6_ADDR_ALT 222*4882a593Smuzhiyun #define __UAPI_DEF_IN6_ADDR_ALT 1 223*4882a593Smuzhiyun #endif 224*4882a593Smuzhiyun #ifndef __UAPI_DEF_SOCKADDR_IN6 225*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IN6 1 226*4882a593Smuzhiyun #endif 227*4882a593Smuzhiyun #ifndef __UAPI_DEF_IPV6_MREQ 228*4882a593Smuzhiyun #define __UAPI_DEF_IPV6_MREQ 1 229*4882a593Smuzhiyun #endif 230*4882a593Smuzhiyun #ifndef __UAPI_DEF_IPPROTO_V6 231*4882a593Smuzhiyun #define __UAPI_DEF_IPPROTO_V6 1 232*4882a593Smuzhiyun #endif 233*4882a593Smuzhiyun #ifndef __UAPI_DEF_IPV6_OPTIONS 234*4882a593Smuzhiyun #define __UAPI_DEF_IPV6_OPTIONS 1 235*4882a593Smuzhiyun #endif 236*4882a593Smuzhiyun #ifndef __UAPI_DEF_IN6_PKTINFO 237*4882a593Smuzhiyun #define __UAPI_DEF_IN6_PKTINFO 1 238*4882a593Smuzhiyun #endif 239*4882a593Smuzhiyun #ifndef __UAPI_DEF_IP6_MTUINFO 240*4882a593Smuzhiyun #define __UAPI_DEF_IP6_MTUINFO 1 241*4882a593Smuzhiyun #endif 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /* Definitions for ipx.h */ 244*4882a593Smuzhiyun #ifndef __UAPI_DEF_SOCKADDR_IPX 245*4882a593Smuzhiyun #define __UAPI_DEF_SOCKADDR_IPX 1 246*4882a593Smuzhiyun #endif 247*4882a593Smuzhiyun #ifndef __UAPI_DEF_IPX_ROUTE_DEFINITION 248*4882a593Smuzhiyun #define __UAPI_DEF_IPX_ROUTE_DEFINITION 1 249*4882a593Smuzhiyun #endif 250*4882a593Smuzhiyun #ifndef __UAPI_DEF_IPX_INTERFACE_DEFINITION 251*4882a593Smuzhiyun #define __UAPI_DEF_IPX_INTERFACE_DEFINITION 1 252*4882a593Smuzhiyun #endif 253*4882a593Smuzhiyun #ifndef __UAPI_DEF_IPX_CONFIG_DATA 254*4882a593Smuzhiyun #define __UAPI_DEF_IPX_CONFIG_DATA 1 255*4882a593Smuzhiyun #endif 256*4882a593Smuzhiyun #ifndef __UAPI_DEF_IPX_ROUTE_DEF 257*4882a593Smuzhiyun #define __UAPI_DEF_IPX_ROUTE_DEF 1 258*4882a593Smuzhiyun #endif 259*4882a593Smuzhiyun 260*4882a593Smuzhiyun /* Definitions for xattr.h */ 261*4882a593Smuzhiyun #ifndef __UAPI_DEF_XATTR 262*4882a593Smuzhiyun #define __UAPI_DEF_XATTR 1 263*4882a593Smuzhiyun #endif 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun #endif /* __GLIBC__ */ 266*4882a593Smuzhiyun 267*4882a593Smuzhiyun #endif /* _UAPI_LIBC_COMPAT_H */ 268