diff --git a/lib/libc/glibc/README.md b/lib/libc/glibc/README.md new file mode 100644 index 000000000000..b7cc65e04e54 --- /dev/null +++ b/lib/libc/glibc/README.md @@ -0,0 +1,9 @@ +glibc sources are slightly patched for backwards compatibility. This is not +good, because it requires to maintain our patchset to glibc headers. + +Until universal headers are real and this file can be removed, these commits +need to be cherry-picked in the future glibc header upgrades: + +Commits: +- 39083c31a550ed80f369f60d35791e98904b8096 +- a89813ef282c092a9caf699731c7faaf485acabe diff --git a/test/link.zig b/test/link.zig index aa0ed4817e33..4b7e7f88d623 100644 --- a/test/link.zig +++ b/test/link.zig @@ -20,6 +20,10 @@ pub const cases = [_]Case{ .build_root = "test/link/interdependent_static_c_libs", .import = @import("link/interdependent_static_c_libs/build.zig"), }, + .{ + .build_root = "test/link/glibc_compat", + .import = @import("link/glibc_compat/build.zig"), + }, // WASM Cases .{ diff --git a/test/link/glibc_compat/build.zig b/test/link/glibc_compat/build.zig new file mode 100644 index 000000000000..f155398f6631 --- /dev/null +++ b/test/link/glibc_compat/build.zig @@ -0,0 +1,23 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const test_step = b.step("test", "Test"); + b.default_step = test_step; + + const targets: []const []const u8 = &.{ + "aarch64-linux-gnu.2.27", + "aarch64-linux-gnu.2.34", + }; + + for (targets) |target| { + const exe = b.addExecutable(.{ + .name = target, + .root_source_file = .{ .path = "main.c" }, + .target = std.zig.CrossTarget.parse( + .{ .arch_os_abi = target }, + ) catch unreachable, + }); + exe.linkLibC(); + test_step.dependOn(&exe.step); + } +} diff --git a/test/link/glibc_compat/main.c b/test/link/glibc_compat/main.c new file mode 100644 index 000000000000..d9059eb8a628 --- /dev/null +++ b/test/link/glibc_compat/main.c @@ -0,0 +1,37 @@ +#define _FILE_OFFSET_BITS 64 +#include +#include +#include +#include + +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); +}