Skip to content

Support building glibc for riscv32/riscv64 #20909

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 7, 2024
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* This file is automatically generated. */
#ifndef __GNU_LIB_NAMES_H
# error "Never use <gnu/lib-names-lp64.h> directly; include <gnu/lib-names.h> instead."
# error "Never use <gnu/lib-names-ilp32d.h> directly; include <gnu/lib-names.h> instead."
#endif

#define LD_LINUX_RISCV64_LP64_SO "ld-linux-riscv64-lp64.so.1"
#define LD_SO "ld-linux-riscv64-lp64.so.1"
#define LD_LINUX_RISCV32_ILP32D_SO "ld-linux-riscv32-ilp32d.so.1"
#define LD_SO "ld-linux-riscv32-ilp32d.so.1"
#define LIBANL_SO "libanl.so.1"
#define LIBBROKENLOCALE_SO "libBrokenLocale.so.1"
#define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0"
Expand All @@ -24,4 +24,4 @@
#define LIBRESOLV_SO "libresolv.so.2"
#define LIBRT_SO "librt.so.1"
#define LIBTHREAD_DB_SO "libthread_db.so.1"
#define LIBUTIL_SO "libutil.so.1"
#define LIBUTIL_SO "libutil.so.1"
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,11 @@
#define __stub___compat_uselib
#define __stub_chflags
#define __stub_fchflags
#define __stub_feclearexcept
#define __stub_fedisableexcept
#define __stub_feenableexcept
#define __stub_fegetenv
#define __stub_fegetexcept
#define __stub_fegetexceptflag
#define __stub_fegetmode
#define __stub_fegetround
#define __stub_feholdexcept
#define __stub_feraiseexcept
#define __stub_fesetenv
#define __stub_fesetexcept
#define __stub_fesetexceptflag
#define __stub_fesetmode
#define __stub_fesetround
#define __stub_fetestexcept
#define __stub_feupdateenv
#define __stub_gtty
#define __stub_revoke
#define __stub_setlogin
#define __stub_sigreturn
#define __stub_stty
#define __stub_stty
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* This file is automatically generated. */
#ifndef __GNU_LIB_NAMES_H
# error "Never use <gnu/lib-names-ilp32.h> directly; include <gnu/lib-names.h> instead."
# error "Never use <gnu/lib-names-lp64d.h> directly; include <gnu/lib-names.h> instead."
#endif

#define LD_LINUX_RISCV32_ILP32_SO "ld-linux-riscv32-ilp32.so.1"
#define LD_SO "ld-linux-riscv32-ilp32.so.1"
#define LD_LINUX_RISCV64_LP64D_SO "ld-linux-riscv64-lp64d.so.1"
#define LD_SO "ld-linux-riscv64-lp64d.so.1"
#define LIBANL_SO "libanl.so.1"
#define LIBBROKENLOCALE_SO "libBrokenLocale.so.1"
#define LIBC_MALLOC_DEBUG_SO "libc_malloc_debug.so.0"
Expand All @@ -24,4 +24,4 @@
#define LIBRESOLV_SO "libresolv.so.2"
#define LIBRT_SO "librt.so.1"
#define LIBTHREAD_DB_SO "libthread_db.so.1"
#define LIBUTIL_SO "libutil.so.1"
#define LIBUTIL_SO "libutil.so.1"
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,11 @@
#define __stub___compat_uselib
#define __stub_chflags
#define __stub_fchflags
#define __stub_feclearexcept
#define __stub_fedisableexcept
#define __stub_feenableexcept
#define __stub_fegetenv
#define __stub_fegetexcept
#define __stub_fegetexceptflag
#define __stub_fegetmode
#define __stub_fegetround
#define __stub_feholdexcept
#define __stub_feraiseexcept
#define __stub_fesetenv
#define __stub_fesetexcept
#define __stub_fesetexceptflag
#define __stub_fesetmode
#define __stub_fesetround
#define __stub_fetestexcept
#define __stub_feupdateenv
#define __stub_gtty
#define __stub_revoke
#define __stub_setlogin
#define __stub_sigreturn
#define __stub_stty
#define __stub_stty
20 changes: 17 additions & 3 deletions lib/std/Target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,21 @@ pub const Os = struct {
.min = .{ .major = 4, .minor = 19, .patch = 0 },
.max = .{ .major = 6, .minor = 5, .patch = 7 },
},
.glibc = .{ .major = 2, .minor = 28, .patch = 0 },
.glibc = blk: {
const default_min = .{ .major = 2, .minor = 28, .patch = 0 };

for (std.zig.target.available_libcs) |libc| {
// We don't know the ABI here. We can get away with not checking it
// for now, but that may not always remain true.
if (libc.os != tag or libc.arch != arch) continue;

if (libc.glibc_min) |min| {
if (min.order(default_min) == .gt) break :blk min;
}
}

break :blk default_min;
},
},
},

Expand Down Expand Up @@ -1728,8 +1742,8 @@ pub const DynamicLinker = struct {
else => "/lib64/ld-linux-x86-64.so.2",
}),

.riscv32 => init("/lib/ld-linux-riscv32-ilp32.so.1"),
.riscv64 => init("/lib/ld-linux-riscv64-lp64.so.1"),
.riscv32 => init("/lib/ld-linux-riscv32-ilp32d.so.1"),
.riscv64 => init("/lib/ld-linux-riscv64-lp64d.so.1"),

// Architectures in this list have been verified as not having a standard
// dynamic linker path.
Expand Down
2 changes: 1 addition & 1 deletion lib/std/zig/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub const available_libcs = [_]ArchOsAbi{
.{ .arch = .powerpc, .os = .linux, .abi = .gnueabi },
.{ .arch = .powerpc, .os = .linux, .abi = .gnueabihf },
.{ .arch = .powerpc, .os = .linux, .abi = .musl },
.{ .arch = .riscv32, .os = .linux, .abi = .gnuilp32, .glibc_min = .{ .major = 2, .minor = 33, .patch = 0 } },
.{ .arch = .riscv32, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 33, .patch = 0 } },
.{ .arch = .riscv32, .os = .linux, .abi = .musl },
.{ .arch = .riscv64, .os = .linux, .abi = .gnu, .glibc_min = .{ .major = 2, .minor = 27, .patch = 0 } },
.{ .arch = .riscv64, .os = .linux, .abi = .musl },
Expand Down
22 changes: 20 additions & 2 deletions src/glibc.zig
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,21 @@ pub fn loadMetaData(gpa: Allocator, contents: []const u8) LoadMetaDataError!*ABI
return abi;
}

fn useElfInitFini(target: std.Target) bool {
// Legacy architectures use _init/_fini.
return switch (target.cpu.arch) {
.arm, .armeb, .thumb, .thumbeb => true,
.aarch64, .aarch64_be => true,
.m68k => true,
.mips, .mipsel, .mips64, .mips64el => true,
.powerpc, .powerpcle, .powerpc64, .powerpc64le => true,
.s390x => true,
.sparc, .sparc64 => true,
.x86, .x86_64 => true,
else => false,
};
}

pub const CRTFile = enum {
crti_o,
crtn_o,
Expand Down Expand Up @@ -359,8 +374,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre
"-std=gnu11",
"-fgnu89-inline",
"-fmerge-all-constants",
// glibc sets this flag but clang does not support it.
// "-frounding-math",
"-frounding-math",
"-fno-stack-protector",
"-fno-common",
"-fmath-errno",
Expand All @@ -369,6 +383,10 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile, prog_node: std.Progre
});
try add_include_dirs(comp, arena, &args);

if (!useElfInitFini(target)) {
try args.append("-DNO_INITFINI");
}

if (target.cpu.arch == .x86) {
// This prevents i386/sysdep.h from trying to do some
// silly and unnecessary inline asm hack that uses weird
Expand Down
8 changes: 8 additions & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3412,6 +3412,14 @@ fn buildOutputType(
std.log.info("zig can provide libc for related target {s}-{s}.{d}-{s}", .{
@tagName(t.arch), @tagName(t.os), os_ver.major, @tagName(t.abi),
});
} else if (t.glibc_min) |glibc_min| {
std.log.info("zig can provide libc for related target {s}-{s}-{s}.{d}.{d}", .{
@tagName(t.arch),
@tagName(t.os),
@tagName(t.abi),
glibc_min.major,
glibc_min.minor,
});
} else {
std.log.info("zig can provide libc for related target {s}-{s}-{s}", .{
@tagName(t.arch), @tagName(t.os), @tagName(t.abi),
Expand Down
1 change: 0 additions & 1 deletion src/target.zig
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,6 @@ pub fn addrSpaceCastIsValid(

pub fn llvmMachineAbi(target: std.Target) ?[:0]const u8 {
const have_float = switch (target.abi) {
.gnuilp32 => return "ilp32",
.gnueabihf, .musleabihf, .eabihf => true,
else => false,
};
Expand Down
6 changes: 3 additions & 3 deletions tools/process_headers.zig
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,12 @@ const glibc_targets = [_]LibCTarget{
.abi = MultiAbi{ .specific = Abi.gnueabi },
},
LibCTarget{
.name = "riscv32-linux-gnu-rv32imac-ilp32",
.name = "riscv32-linux-gnu-rv32imafdc-ilp32d",
.arch = MultiArch{ .specific = Arch.riscv32 },
.abi = MultiAbi{ .specific = Abi.gnuilp32 },
.abi = MultiAbi{ .specific = Abi.gnu },
},
LibCTarget{
.name = "riscv64-linux-gnu-rv64imac-lp64",
.name = "riscv64-linux-gnu-rv64imafdc-lp64d",
.arch = MultiArch{ .specific = Arch.riscv64 },
.abi = MultiAbi{ .specific = Abi.gnu },
},
Expand Down