authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-06 17:15:58-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-04-06 17:15:58-04:00
log13aa7871b274fd22c7fdf277174a43d09788bd27
tree8bee2f5234bf07ddf6e92186d4d0f4e39aae05bc
parent9f957184a13fd39b74b978a8eb19b4c9eb6afa09
parent652e8cf8645c46ec5b5b4e6540f71b9b7e518711
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15101 from motiejus/glibc_compat

glibc: add backwards compatibility for some symbols

7 files changed, 104 insertions(+), 0 deletions(-)

lib/libc/glibc/README.md created+8
......@@ -0,0 +1,8 @@
1glibc headers are slightly patched for backwards compatibility. This is not
2good, because it requires to maintain our patchset whlist upgrading glibc.
3
4Until universal headers are real and this file can be removed, these commits
5need 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;
167167 effective IDs, not real IDs. */
168168#endif
169169
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
170174/* Do the file control operation described by CMD on FD.
171175 The remaining arguments are interpreted depending on CMD.
172176
......@@ -197,6 +201,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW;
197201# define fcntl __fcntl_time64
198202# endif
199203#endif
204#else /* glibc 2.27 or lower */
205extern int fcntl (int __fd, int __cmd, ...);
206#endif
200207
201208/* Open FILE and return a new file descriptor for it, or -1 on error.
202209 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;
167167 effective IDs, not real IDs. */
168168#endif
169169
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
170175/* Do the file control operation described by CMD on FD.
171176 The remaining arguments are interpreted depending on CMD.
172177
......@@ -197,6 +202,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW;
197202# define fcntl __fcntl_time64
198203# endif
199204#endif
205#else /* glibc 2.27 or lower */
206extern int fcntl (int __fd, int __cmd, ...);
207#endif
200208
201209/* Open FILE and return a new file descriptor for it, or -1 on error.
202210 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
169169#define res_init __res_init
170170#define res_isourserver __res_isourserver
171171
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
172194#ifdef _LIBC
173195# define __RESOLV_DEPRECATED
174196# define __RESOLV_DEPRECATED_MSG(msg)
test/link.zig+4
......@@ -20,6 +20,10 @@ pub const cases = [_]Case{
2020 .build_root = "test/link/interdependent_static_c_libs",
2121 .import = @import("link/interdependent_static_c_libs/build.zig"),
2222 },
23 .{
24 .build_root = "test/link/glibc_compat",
25 .import = @import("link/glibc_compat/build.zig"),
26 },
2327
2428 // WASM Cases
2529 .{
test/link/glibc_compat/build.zig created+18
......@@ -0,0 +1,18 @@
1const std = @import("std");
2
3pub 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
7int 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}