Merge pull request #15101 from motiejus/glibc_compat

glibc: add backwards compatibility for some symbols
This commit is contained in:
Andrew Kelley 2023-04-06 17:15:58 -04:00 committed by GitHub
commit 13aa7871b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 104 additions and 0 deletions

8
lib/libc/glibc/README.md vendored Normal file
View file

@ -0,0 +1,8 @@
glibc headers are slightly patched for backwards compatibility. This is not
good, because it requires to maintain our patchset whlist upgrading glibc.
Until universal headers are real and this file can be removed, these commits
need to be cherry-picked in the future glibc header upgrades:
- 39083c31a550ed80f369f60d35791e98904b8096
- a89813ef282c092a9caf699731c7faaf485acabe

View file

@ -167,6 +167,10 @@ typedef __pid_t pid_t;
effective IDs, not real IDs. */ effective IDs, not real IDs. */
#endif #endif
/* fcntl was a simple symbol until glibc 2.27 inclusive. glibc 2.28 onwards
* re-defines it to fcntl64 (via #define) if _FILE_OFFSET_BITS == 64. */
#if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 28) || __GLIBC__ > 2
/* Do the file control operation described by CMD on FD. /* Do the file control operation described by CMD on FD.
The remaining arguments are interpreted depending on CMD. The remaining arguments are interpreted depending on CMD.
@ -197,6 +201,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW;
# define fcntl __fcntl_time64 # define fcntl __fcntl_time64
# endif # endif
#endif #endif
#else /* glibc 2.27 or lower */
extern int fcntl (int __fd, int __cmd, ...);
#endif
/* Open FILE and return a new file descriptor for it, or -1 on error. /* Open FILE and return a new file descriptor for it, or -1 on error.
OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set

View file

@ -167,6 +167,11 @@ typedef __pid_t pid_t;
effective IDs, not real IDs. */ effective IDs, not real IDs. */
#endif #endif
/* fcntl was a simple symbol until glibc 2.27 inclusive.
* glibc 2.28 onwards converted it to a macro when compiled with
* USE_LARGEFILE64. */
#if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 28) || __GLIBC__ > 2
/* Do the file control operation described by CMD on FD. /* Do the file control operation described by CMD on FD.
The remaining arguments are interpreted depending on CMD. The remaining arguments are interpreted depending on CMD.
@ -197,6 +202,9 @@ extern int __fcntl_time64 (int __fd, int __request, ...) __THROW;
# define fcntl __fcntl_time64 # define fcntl __fcntl_time64
# endif # endif
#endif #endif
#else /* glibc 2.27 or lower */
extern int fcntl (int __fd, int __cmd, ...);
#endif
/* Open FILE and return a new file descriptor for it, or -1 on error. /* Open FILE and return a new file descriptor for it, or -1 on error.
OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set

View file

@ -169,6 +169,28 @@ __END_DECLS
#define res_init __res_init #define res_init __res_init
#define res_isourserver __res_isourserver #define res_isourserver __res_isourserver
/* In glibc 2.33 and earlier res_search, res_nsearch, res_query, res_nquery,
* res_querydomain, res_nquerydomain were #define'd to __res_search,
* __res_nsearch, etc. glibc 2.34 onwards removes the macros and exposes the
* symbols directly. New glibc exposes compat symbols with underscores for
* backwards compatibility. Applications linked to glibc 2.34+ are expected
* to use the non-underscored symbols.
*
* It will be enough to bring the macros back when compiling against the older
* glibc versions.
*
* See glibc commit ea9878ec271c791880fcbbe519d70c42f8113750.
*/
#if (__GLIBC__ == 2 && __GLIBC_MINOR__ < 34)
#define res_search __res_search
#define res_nsearch __res_nsearch
#define res_query __res_query
#define res_nquery __res_nquery
#define res_querydomain __res_querydomain
#define res_nquerydomain __res_nquerydomain
#endif
/* end glibc compat hacks */
#ifdef _LIBC #ifdef _LIBC
# define __RESOLV_DEPRECATED # define __RESOLV_DEPRECATED
# define __RESOLV_DEPRECATED_MSG(msg) # define __RESOLV_DEPRECATED_MSG(msg)

View file

@ -20,6 +20,10 @@ pub const cases = [_]Case{
.build_root = "test/link/interdependent_static_c_libs", .build_root = "test/link/interdependent_static_c_libs",
.import = @import("link/interdependent_static_c_libs/build.zig"), .import = @import("link/interdependent_static_c_libs/build.zig"),
}, },
.{
.build_root = "test/link/glibc_compat",
.import = @import("link/glibc_compat/build.zig"),
},
// WASM Cases // WASM Cases
.{ .{

View file

@ -0,0 +1,18 @@
const std = @import("std");
pub fn build(b: *std.Build) void {
const test_step = b.step("test", "Test");
b.default_step = test_step;
inline for (.{ "aarch64-linux-gnu.2.27", "aarch64-linux-gnu.2.34" }) |t| {
const exe = b.addExecutable(.{
.name = t,
.root_source_file = .{ .path = "main.c" },
.target = std.zig.CrossTarget.parse(
.{ .arch_os_abi = t },
) catch unreachable,
});
exe.linkLibC();
test_step.dependOn(&exe.step);
}
}

View file

@ -0,0 +1,37 @@
#define _FILE_OFFSET_BITS 64
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <resolv.h>
int main() {
/* in glibc 2.28+ and _FILE_OFFSET_BITS=64 fcntl is #define'd to fcntl64
* Thus headers say `fcntl64` exists, but libc.so.6 (the old one)
* disagrees, resulting in a linking error unless headers are made
* backwards-compatible.
*
* Glibc 2.28+:
* FUNC GLOBAL DEFAULT UND fcntl64@GLIBC_2.28 (3):
*
* Glibc 2.27 or older:
* FUNC GLOBAL DEFAULT UND fcntl@GLIBC_2.2.5
*/
printf("address to fcntl: %p\n", fcntl);
/* The following functions became symbols of their own right with glibc
* 2.34+. Before 2.34 resolv.h would #define res_search __res_search; and
* __res_search is a valid symbol since the beginning of time.
*
* On glibc 2.34+ these symbols are linked this way:
* FUNC GLOBAL DEFAULT UND res_search@GLIBC_2.34 (2)
*
* Pre-glibc 2.34:
* FUNC GLOBAL DEFAULT UND __res_search@GLIBC_2.2.5 (4)
*/
printf("address to res_search: %p\n", res_search);
printf("address to res_nsearch: %p\n", res_nsearch);
printf("address to res_query: %p\n", res_query);
printf("address to res_nquery: %p\n", res_nquery);
printf("address to res_querydomain: %p\n", res_querydomain);
printf("address to res_nquerydomain: %p\n", res_nquerydomain);
}