Commit 652e8cf864

Motiejus Jakštys <motiejus@uber.com>
2023-03-28 19:33:39
glibc compat: add a test and README
1 parent 7e6aeea
Changed files (4)
lib
libc
glibc
test
link
glibc_compat
lib/libc/glibc/README.md
@@ -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
test/link/glibc_compat/build.zig
@@ -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);
+    }
+}
test/link/glibc_compat/main.c
@@ -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);
+}
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
     .{