| author | |
| committer | |
| log | 13aa7871b274fd22c7fdf277174a43d09788bd27 |
| tree | 8bee2f5234bf07ddf6e92186d4d0f4e39aae05bc |
| parent | 9f957184a13fd39b74b978a8eb19b4c9eb6afa09 |
| parent | 652e8cf8645c46ec5b5b4e6540f71b9b7e518711 |
| signature |
glibc: add backwards compatibility for some symbols7 files changed, 104 insertions(+), 0 deletions(-)
lib/libc/glibc/README.md created+8| ... | @@ -0,0 +1,8 @@ | ||
| 1 | glibc headers are slightly patched for backwards compatibility. This is not | ||
| 2 | good, because it requires to maintain our patchset whlist upgrading glibc. | ||
| 3 | |||
| 4 | Until universal headers are real and this file can be removed, these commits | ||
| 5 | need to be cherry-picked in the future glibc header upgrades: | ||
| 6 | |||
| 7 | - 39083c31a550ed80f369f60d35791e98904b8096 | ||
| 8 | - a89813ef282c092a9caf699731c7faaf485acabe | ||
lib/libc/glibc/io/fcntl.h+7| ... | @@ -167,6 +167,10 @@ typedef __pid_t pid_t; | ... | @@ -167,6 +167,10 @@ typedef __pid_t pid_t; |
| 167 | 					 effective IDs, not real IDs. */ | 167 | 					 effective IDs, not real IDs. */ |
| 168 | #endif | 168 | #endif |
| 169 | 169 | ||
| 170 | |||
| 171 | /* fcntl was a simple symbol until glibc 2.27 inclusive. glibc 2.28 onwards | ||
| 172 | * re-defines it to fcntl64 (via #define) if _FILE_OFFSET_BITS == 64. */ | ||
| 173 | #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 28) || __GLIBC__ > 2 | ||
| 170 | /* Do the file control operation described by CMD on FD. | 174 | /* Do the file control operation described by CMD on FD. |
| 171 | The remaining arguments are interpreted depending on CMD. | 175 | The remaining arguments are interpreted depending on CMD. |
| 172 | 176 | ||
| ... | @@ -197,6 +201,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW; | ... | @@ -197,6 +201,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW; |
| 197 | # define fcntl __fcntl_time64 | 201 | # define fcntl __fcntl_time64 |
| 198 | # endif | 202 | # endif |
| 199 | #endif | 203 | #endif |
| 204 | #else /* glibc 2.27 or lower */ | ||
| 205 | extern int fcntl (int __fd, int __cmd, ...); | ||
| 206 | #endif | ||
| 200 | 207 | ||
| 201 | /* Open FILE and return a new file descriptor for it, or -1 on error. | 208 | /* Open FILE and return a new file descriptor for it, or -1 on error. |
| 202 | OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set | 209 | OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set |
lib/libc/include/generic-glibc/fcntl.h+8| ... | @@ -167,6 +167,11 @@ typedef __pid_t pid_t; | ... | @@ -167,6 +167,11 @@ typedef __pid_t pid_t; |
| 167 | 					 effective IDs, not real IDs. */ | 167 | 					 effective IDs, not real IDs. */ |
| 168 | #endif | 168 | #endif |
| 169 | 169 | ||
| 170 | |||
| 171 | /* fcntl was a simple symbol until glibc 2.27 inclusive. | ||
| 172 | * glibc 2.28 onwards converted it to a macro when compiled with | ||
| 173 | * USE_LARGEFILE64. */ | ||
| 174 | #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 28) || __GLIBC__ > 2 | ||
| 170 | /* Do the file control operation described by CMD on FD. | 175 | /* Do the file control operation described by CMD on FD. |
| 171 | The remaining arguments are interpreted depending on CMD. | 176 | The remaining arguments are interpreted depending on CMD. |
| 172 | 177 | ||
| ... | @@ -197,6 +202,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW; | ... | @@ -197,6 +202,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW; |
| 197 | # define fcntl __fcntl_time64 | 202 | # define fcntl __fcntl_time64 |
| 198 | # endif | 203 | # endif |
| 199 | #endif | 204 | #endif |
| 205 | #else /* glibc 2.27 or lower */ | ||
| 206 | extern int fcntl (int __fd, int __cmd, ...); | ||
| 207 | #endif | ||
| 200 | 208 | ||
| 201 | /* Open FILE and return a new file descriptor for it, or -1 on error. | 209 | /* Open FILE and return a new file descriptor for it, or -1 on error. |
| 202 | OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set | 210 | OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set |
lib/libc/include/generic-glibc/resolv.h+22| ... | @@ -169,6 +169,28 @@ __END_DECLS | ... | @@ -169,6 +169,28 @@ __END_DECLS |
| 169 | #define res_init		__res_init | 169 | #define res_init		__res_init |
| 170 | #define res_isourserver		__res_isourserver | 170 | #define res_isourserver		__res_isourserver |
| 171 | 171 | ||
| 172 | /* In glibc 2.33 and earlier res_search, res_nsearch, res_query, res_nquery, | ||
| 173 | * res_querydomain, res_nquerydomain were #define'd to __res_search, | ||
| 174 | * __res_nsearch, etc. glibc 2.34 onwards removes the macros and exposes the | ||
| 175 | * symbols directly. New glibc exposes compat symbols with underscores for | ||
| 176 | * backwards compatibility. Applications linked to glibc 2.34+ are expected | ||
| 177 | * to use the non-underscored symbols. | ||
| 178 | * | ||
| 179 | * It will be enough to bring the macros back when compiling against the older | ||
| 180 | * glibc versions. | ||
| 181 | * | ||
| 182 | * See glibc commit ea9878ec271c791880fcbbe519d70c42f8113750. | ||
| 183 | */ | ||
| 184 | #if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 34) | ||
| 185 | #define res_search __res_search | ||
| 186 | #define res_nsearch __res_nsearch | ||
| 187 | #define res_query __res_query | ||
| 188 | #define res_nquery __res_nquery | ||
| 189 | #define res_querydomain __res_querydomain | ||
| 190 | #define res_nquerydomain __res_nquerydomain | ||
| 191 | #endif | ||
| 192 | /* end glibc compat hacks */ | ||
| 193 | |||
| 172 | #ifdef _LIBC | 194 | #ifdef _LIBC |
| 173 | # define __RESOLV_DEPRECATED | 195 | # define __RESOLV_DEPRECATED |
| 174 | # define __RESOLV_DEPRECATED_MSG(msg) | 196 | # define __RESOLV_DEPRECATED_MSG(msg) |
test/link.zig+4| ... | @@ -20,6 +20,10 @@ pub const cases = [_]Case{ | ... | @@ -20,6 +20,10 @@ pub const cases = [_]Case{ |
| 20 | .build_root = "test/link/interdependent_static_c_libs", | 20 | .build_root = "test/link/interdependent_static_c_libs", |
| 21 | .import = @import("link/interdependent_static_c_libs/build.zig"), | 21 | .import = @import("link/interdependent_static_c_libs/build.zig"), |
| 22 | }, | 22 | }, |
| 23 | .{ | ||
| 24 | .build_root = "test/link/glibc_compat", | ||
| 25 | .import = @import("link/glibc_compat/build.zig"), | ||
| 26 | }, | ||
| 23 | 27 | ||
| 24 | // WASM Cases | 28 | // WASM Cases |
| 25 | .{ | 29 | .{ |
test/link/glibc_compat/build.zig created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | |||
| 3 | pub fn build(b: *std.Build) void { | ||
| 4 | const test_step = b.step("test", "Test"); | ||
| 5 | b.default_step = test_step; | ||
| 6 | |||
| 7 | inline for (.{ "aarch64-linux-gnu.2.27", "aarch64-linux-gnu.2.34" }) |t| { | ||
| 8 | const exe = b.addExecutable(.{ | ||
| 9 | .name = t, | ||
| 10 | .root_source_file = .{ .path = "main.c" }, | ||
| 11 | .target = std.zig.CrossTarget.parse( | ||
| 12 | .{ .arch_os_abi = t }, | ||
| 13 | ) catch unreachable, | ||
| 14 | }); | ||
| 15 | exe.linkLibC(); | ||
| 16 | test_step.dependOn(&exe.step); | ||
| 17 | } | ||
| 18 | } | ||
test/link/glibc_compat/main.c created+37| ... | @@ -0,0 +1,37 @@ | ||
| 1 | #define _FILE_OFFSET_BITS 64 | ||
| 2 | #include <unistd.h> | ||
| 3 | #include <fcntl.h> | ||
| 4 | #include <stdio.h> | ||
| 5 | #include <resolv.h> | ||
| 6 | |||
| 7 | int main() { | ||
| 8 | /* in glibc 2.28+ and _FILE_OFFSET_BITS=64 fcntl is #define'd to fcntl64 | ||
| 9 | * Thus headers say `fcntl64` exists, but libc.so.6 (the old one) | ||
| 10 | * disagrees, resulting in a linking error unless headers are made | ||
| 11 | * backwards-compatible. | ||
| 12 | * | ||
| 13 | * Glibc 2.28+: | ||
| 14 | * FUNC GLOBAL DEFAULT UND fcntl64@GLIBC_2.28 (3): | ||
| 15 | * | ||
| 16 | * Glibc 2.27 or older: | ||
| 17 | * FUNC GLOBAL DEFAULT UND fcntl@GLIBC_2.2.5 | ||
| 18 | */ | ||
| 19 | printf("address to fcntl: %p\n", fcntl); | ||
| 20 | |||
| 21 | /* The following functions became symbols of their own right with glibc | ||
| 22 | * 2.34+. Before 2.34 resolv.h would #define res_search __res_search; and | ||
| 23 | * __res_search is a valid symbol since the beginning of time. | ||
| 24 | * | ||
| 25 | * On glibc 2.34+ these symbols are linked this way: | ||
| 26 | * FUNC GLOBAL DEFAULT UND res_search@GLIBC_2.34 (2) | ||
| 27 | * | ||
| 28 | * Pre-glibc 2.34: | ||
| 29 | * FUNC GLOBAL DEFAULT UND __res_search@GLIBC_2.2.5 (4) | ||
| 30 | */ | ||
| 31 | printf("address to res_search: %p\n", res_search); | ||
| 32 | printf("address to res_nsearch: %p\n", res_nsearch); | ||
| 33 | printf("address to res_query: %p\n", res_query); | ||
| 34 | printf("address to res_nquery: %p\n", res_nquery); | ||
| 35 | printf("address to res_querydomain: %p\n", res_querydomain); | ||
| 36 | printf("address to res_nquerydomain: %p\n", res_nquerydomain); | ||
| 37 | } | ||