232 lines · c
1/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */2/*3 * Compatibility interface for userspace libc header coordination:4 *5 * Define compatibility macros that are used to control the inclusion or6 * exclusion of UAPI structures and definitions in coordination with another7 * userspace C library.8 *9 * This header is intended to solve the problem of UAPI definitions that10 * conflict with userspace definitions. If a UAPI header has such conflicting11 * definitions then the solution is as follows:12 *13 * * Synchronize the UAPI header and the libc headers so either one can be14 * used and such that the ABI is preserved. If this is not possible then15 * no simple compatibility interface exists (you need to write translating16 * wrappers and rename things) and you can't use this interface.17 *18 * Then follow this process:19 *20 * (a) Include libc-compat.h in the UAPI header.21 * e.g. #include <linux/libc-compat.h>22 * This include must be as early as possible.23 *24 * (b) In libc-compat.h add enough code to detect that the comflicting25 * userspace libc header has been included first.26 *27 * (c) If the userspace libc header has been included first define a set of28 * guard macros of the form __UAPI_DEF_FOO and set their values to 1, else29 * set their values to 0.30 *31 * (d) Back in the UAPI header with the conflicting definitions, guard the32 * definitions with:33 * #if __UAPI_DEF_FOO34 * ...35 * #endif36 *37 * This fixes the situation where the linux headers are included *after* the38 * libc headers. To fix the problem with the inclusion in the other order the39 * userspace libc headers must be fixed like this:40 *41 * * For all definitions that conflict with kernel definitions wrap those42 * defines in the following:43 * #if !__UAPI_DEF_FOO44 * ...45 * #endif46 *47 * This prevents the redefinition of a construct already defined by the kernel.48 */49#ifndef _UAPI_LIBC_COMPAT_H50#define _UAPI_LIBC_COMPAT_H51 52/* We have included glibc headers... */53#if defined(__GLIBC__)54 55/* Coordinate with glibc net/if.h header. */56#if defined(_NET_IF_H) && defined(__USE_MISC)57 58/* GLIBC headers included first so don't define anything59 * that would already be defined. */60 61#define __UAPI_DEF_IF_IFCONF 062#define __UAPI_DEF_IF_IFMAP 063#define __UAPI_DEF_IF_IFNAMSIZ 064#define __UAPI_DEF_IF_IFREQ 065/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */66#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 067/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */68#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO69#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 170#endif /* __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO */71 72#else /* _NET_IF_H */73 74/* Linux headers included first, and we must define everything75 * we need. The expectation is that glibc will check the76 * __UAPI_DEF_* defines and adjust appropriately. */77 78#define __UAPI_DEF_IF_IFCONF 179#define __UAPI_DEF_IF_IFMAP 180#define __UAPI_DEF_IF_IFNAMSIZ 181#define __UAPI_DEF_IF_IFREQ 182/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */83#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 184/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */85#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 186 87#endif /* _NET_IF_H */88 89/* Coordinate with glibc netinet/in.h header. */90#if defined(_NETINET_IN_H)91 92/* GLIBC headers included first so don't define anything93 * that would already be defined. */94#define __UAPI_DEF_IN_ADDR 095#define __UAPI_DEF_IN_IPPROTO 096#define __UAPI_DEF_IN_PKTINFO 097#define __UAPI_DEF_IP_MREQ 098#define __UAPI_DEF_SOCKADDR_IN 099#define __UAPI_DEF_IN_CLASS 0100 101#define __UAPI_DEF_IN6_ADDR 0102/* The exception is the in6_addr macros which must be defined103 * if the glibc code didn't define them. This guard matches104 * the guard in glibc/inet/netinet/in.h which defines the105 * additional in6_addr macros e.g. s6_addr16, and s6_addr32. */106#if defined(__USE_MISC) || defined (__USE_GNU)107#define __UAPI_DEF_IN6_ADDR_ALT 0108#else109#define __UAPI_DEF_IN6_ADDR_ALT 1110#endif111#define __UAPI_DEF_SOCKADDR_IN6 0112#define __UAPI_DEF_IPV6_MREQ 0113#define __UAPI_DEF_IPPROTO_V6 0114#define __UAPI_DEF_IPV6_OPTIONS 0115#define __UAPI_DEF_IN6_PKTINFO 0116#define __UAPI_DEF_IP6_MTUINFO 0117 118#else119 120/* Linux headers included first, and we must define everything121 * we need. The expectation is that glibc will check the122 * __UAPI_DEF_* defines and adjust appropriately. */123#define __UAPI_DEF_IN_ADDR 1124#define __UAPI_DEF_IN_IPPROTO 1125#define __UAPI_DEF_IN_PKTINFO 1126#define __UAPI_DEF_IP_MREQ 1127#define __UAPI_DEF_SOCKADDR_IN 1128#define __UAPI_DEF_IN_CLASS 1129 130#define __UAPI_DEF_IN6_ADDR 1131/* We unconditionally define the in6_addr macros and glibc must132 * coordinate. */133#define __UAPI_DEF_IN6_ADDR_ALT 1134#define __UAPI_DEF_SOCKADDR_IN6 1135#define __UAPI_DEF_IPV6_MREQ 1136#define __UAPI_DEF_IPPROTO_V6 1137#define __UAPI_DEF_IPV6_OPTIONS 1138#define __UAPI_DEF_IN6_PKTINFO 1139#define __UAPI_DEF_IP6_MTUINFO 1140 141#endif /* _NETINET_IN_H */142 143/* Definitions for xattr.h */144#if defined(_SYS_XATTR_H)145#define __UAPI_DEF_XATTR 0146#else147#define __UAPI_DEF_XATTR 1148#endif149 150/* If we did not see any headers from any supported C libraries,151 * or we are being included in the kernel, then define everything152 * that we need. Check for previous __UAPI_* definitions to give153 * unsupported C libraries a way to opt out of any kernel definition. */154#else /* !defined(__GLIBC__) */155 156/* Definitions for if.h */157#ifndef __UAPI_DEF_IF_IFCONF158#define __UAPI_DEF_IF_IFCONF 1159#endif160#ifndef __UAPI_DEF_IF_IFMAP161#define __UAPI_DEF_IF_IFMAP 1162#endif163#ifndef __UAPI_DEF_IF_IFNAMSIZ164#define __UAPI_DEF_IF_IFNAMSIZ 1165#endif166#ifndef __UAPI_DEF_IF_IFREQ167#define __UAPI_DEF_IF_IFREQ 1168#endif169/* Everything up to IFF_DYNAMIC, matches net/if.h until glibc 2.23 */170#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS171#define __UAPI_DEF_IF_NET_DEVICE_FLAGS 1172#endif173/* For the future if glibc adds IFF_LOWER_UP, IFF_DORMANT and IFF_ECHO */174#ifndef __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO175#define __UAPI_DEF_IF_NET_DEVICE_FLAGS_LOWER_UP_DORMANT_ECHO 1176#endif177 178/* Definitions for in.h */179#ifndef __UAPI_DEF_IN_ADDR180#define __UAPI_DEF_IN_ADDR 1181#endif182#ifndef __UAPI_DEF_IN_IPPROTO183#define __UAPI_DEF_IN_IPPROTO 1184#endif185#ifndef __UAPI_DEF_IN_PKTINFO186#define __UAPI_DEF_IN_PKTINFO 1187#endif188#ifndef __UAPI_DEF_IP_MREQ189#define __UAPI_DEF_IP_MREQ 1190#endif191#ifndef __UAPI_DEF_SOCKADDR_IN192#define __UAPI_DEF_SOCKADDR_IN 1193#endif194#ifndef __UAPI_DEF_IN_CLASS195#define __UAPI_DEF_IN_CLASS 1196#endif197 198/* Definitions for in6.h */199#ifndef __UAPI_DEF_IN6_ADDR200#define __UAPI_DEF_IN6_ADDR 1201#endif202#ifndef __UAPI_DEF_IN6_ADDR_ALT203#define __UAPI_DEF_IN6_ADDR_ALT 1204#endif205#ifndef __UAPI_DEF_SOCKADDR_IN6206#define __UAPI_DEF_SOCKADDR_IN6 1207#endif208#ifndef __UAPI_DEF_IPV6_MREQ209#define __UAPI_DEF_IPV6_MREQ 1210#endif211#ifndef __UAPI_DEF_IPPROTO_V6212#define __UAPI_DEF_IPPROTO_V6 1213#endif214#ifndef __UAPI_DEF_IPV6_OPTIONS215#define __UAPI_DEF_IPV6_OPTIONS 1216#endif217#ifndef __UAPI_DEF_IN6_PKTINFO218#define __UAPI_DEF_IN6_PKTINFO 1219#endif220#ifndef __UAPI_DEF_IP6_MTUINFO221#define __UAPI_DEF_IP6_MTUINFO 1222#endif223 224/* Definitions for xattr.h */225#ifndef __UAPI_DEF_XATTR226#define __UAPI_DEF_XATTR 1227#endif228 229#endif /* __GLIBC__ */230 231#endif /* _UAPI_LIBC_COMPAT_H */232