| author | |
| committer | |
| log | 2f9c5c0644dd516ec0d96f33333a35e6b4deea91 |
| tree | 852e7d7273da760a3a36ea551343f5e01bfe8f5a |
| parent | c784c52819e505620fb1fcb48e59a48c6d8f487e |
| signature |
17 files changed, 430 insertions(+), 532 deletions(-)
lib/std/os.zig+18-14| ... | ... | @@ -2974,18 +2974,26 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void { |
| 2974 | 2974 | } |
| 2975 | 2975 | |
| 2976 | 2976 | pub fn dl_iterate_phdr( |
| 2977 | comptime T: type, | |
| 2978 | callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32, | |
| 2979 | data: ?*T, | |
| 2980 | ) isize { | |
| 2977 | context: var, | |
| 2978 | comptime Error: type, | |
| 2979 | comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void, | |
| 2980 | ) Error!void { | |
| 2981 | const Context = @TypeOf(context); | |
| 2982 | ||
| 2981 | 2983 | if (builtin.object_format != .elf) |
| 2982 | 2984 | @compileError("dl_iterate_phdr is not available for this target"); |
| 2983 | 2985 | |
| 2984 | 2986 | if (builtin.link_libc) { |
| 2985 | return system.dl_iterate_phdr( | |
| 2986 | @ptrCast(std.c.dl_iterate_phdr_callback, callback), | |
| 2987 | @ptrCast(?*c_void, data), | |
| 2988 | ); | |
| 2987 | switch (system.dl_iterate_phdr(struct { | |
| 2988 | fn callbackC(info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int { | |
| 2989 | const context_ptr = @ptrCast(*const Context, @alignCast(@alignOf(*const Context), data)); | |
| 2990 | callback(info, size, context_ptr.*) catch |err| return @errorToInt(err); | |
| 2991 | return 0; | |
| 2992 | } | |
| 2993 | }.callbackC, @intToPtr(?*c_void, @ptrToInt(&context)))) { | |
| 2994 | 0 => return, | |
| 2995 | else => |err| return @errSetCast(Error, @intToError(@intCast(u16, err))), // TODO don't hardcode u16 | |
| 2996 | } | |
| 2989 | 2997 | } |
| 2990 | 2998 | |
| 2991 | 2999 | const elf_base = std.process.getBaseAddress(); |
| ... | ... | @@ -3007,11 +3015,10 @@ pub fn dl_iterate_phdr( |
| 3007 | 3015 | .dlpi_phnum = ehdr.e_phnum, |
| 3008 | 3016 | }; |
| 3009 | 3017 | |
| 3010 | return callback(&info, @sizeOf(dl_phdr_info), data); | |
| 3018 | return callback(&info, @sizeOf(dl_phdr_info), context); | |
| 3011 | 3019 | } |
| 3012 | 3020 | |
| 3013 | 3021 | // Last return value from the callback function |
| 3014 | var last_r: isize = 0; | |
| 3015 | 3022 | while (it.next()) |entry| { |
| 3016 | 3023 | var dlpi_phdr: [*]elf.Phdr = undefined; |
| 3017 | 3024 | var dlpi_phnum: u16 = undefined; |
| ... | ... | @@ -3033,11 +3040,8 @@ pub fn dl_iterate_phdr( |
| 3033 | 3040 | .dlpi_phnum = dlpi_phnum, |
| 3034 | 3041 | }; |
| 3035 | 3042 | |
| 3036 | last_r = callback(&info, @sizeOf(dl_phdr_info), data); | |
| 3037 | if (last_r != 0) break; | |
| 3043 | try callback(&info, @sizeOf(dl_phdr_info), context); | |
| 3038 | 3044 | } |
| 3039 | ||
| 3040 | return last_r; | |
| 3041 | 3045 | } |
| 3042 | 3046 | |
| 3043 | 3047 | pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError; |
lib/std/process.zig+56| ... | ... | @@ -613,3 +613,59 @@ pub fn getBaseAddress() usize { |
| 613 | 613 | else => @compileError("Unsupported OS"), |
| 614 | 614 | } |
| 615 | 615 | } |
| 616 | ||
| 617 | /// Caller owns the result value and each inner slice. | |
| 618 | pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 { | |
| 619 | switch (builtin.link_mode) { | |
| 620 | .Static => return &[_][:0]u8{}, | |
| 621 | .Dynamic => {}, | |
| 622 | } | |
| 623 | const List = std.ArrayList([:0]u8); | |
| 624 | switch (builtin.os) { | |
| 625 | .linux, | |
| 626 | .freebsd, | |
| 627 | .netbsd, | |
| 628 | .dragonfly, | |
| 629 | => { | |
| 630 | var paths = List.init(allocator); | |
| 631 | errdefer { | |
| 632 | const slice = paths.toOwnedSlice(); | |
| 633 | for (slice) |item| { | |
| 634 | allocator.free(item); | |
| 635 | } | |
| 636 | allocator.free(slice); | |
| 637 | } | |
| 638 | try os.dl_iterate_phdr(&paths, error{OutOfMemory}, struct { | |
| 639 | fn callback(info: *os.dl_phdr_info, size: usize, list: *List) !void { | |
| 640 | const name = info.dlpi_name orelse return; | |
| 641 | if (name[0] == '/') { | |
| 642 | const item = try mem.dupeZ(list.allocator, u8, mem.toSliceConst(u8, name)); | |
| 643 | errdefer list.allocator.free(item); | |
| 644 | try list.append(item); | |
| 645 | } | |
| 646 | } | |
| 647 | }.callback); | |
| 648 | return paths.toOwnedSlice(); | |
| 649 | }, | |
| 650 | .macosx, .ios, .watchos, .tvos => { | |
| 651 | var paths = List.init(allocator); | |
| 652 | errdefer { | |
| 653 | const slice = paths.toOwnedSlice(); | |
| 654 | for (slice) |item| { | |
| 655 | allocator.free(item); | |
| 656 | } | |
| 657 | allocator.free(slice); | |
| 658 | } | |
| 659 | const img_count = std.c._dyld_image_count(); | |
| 660 | var i: u32 = 0; | |
| 661 | while (i < img_count) : (i += 1) { | |
| 662 | const name = std.c._dyld_get_image_name(i); | |
| 663 | const item = try mem.dupeZ(allocator, u8, mem.toSliceConst(u8, name)); | |
| 664 | errdefer allocator.free(item); | |
| 665 | try paths.append(item); | |
| 666 | } | |
| 667 | return paths.toOwnedSlice(); | |
| 668 | }, | |
| 669 | else => return error.UnimplementedSelfExeSharedPaths, | |
| 670 | } | |
| 671 | } |
lib/std/target.zig+137| ... | ... | @@ -1037,6 +1037,13 @@ pub const Target = union(enum) { |
| 1037 | 1037 | }; |
| 1038 | 1038 | } |
| 1039 | 1039 | |
| 1040 | pub fn isAndroid(self: Target) bool { | |
| 1041 | return switch (self.getAbi()) { | |
| 1042 | .android => true, | |
| 1043 | else => false, | |
| 1044 | }; | |
| 1045 | } | |
| 1046 | ||
| 1040 | 1047 | pub fn isDragonFlyBSD(self: Target) bool { |
| 1041 | 1048 | return switch (self.getOs()) { |
| 1042 | 1049 | .dragonfly => true, |
| ... | ... | @@ -1196,6 +1203,136 @@ pub const Target = union(enum) { |
| 1196 | 1203 | |
| 1197 | 1204 | return .unavailable; |
| 1198 | 1205 | } |
| 1206 | ||
| 1207 | pub const FloatAbi = enum { | |
| 1208 | hard, | |
| 1209 | soft, | |
| 1210 | soft_fp, | |
| 1211 | }; | |
| 1212 | ||
| 1213 | pub fn getFloatAbi(self: Target) FloatAbi { | |
| 1214 | return switch (self.getAbi()) { | |
| 1215 | .gnueabihf, | |
| 1216 | .eabihf, | |
| 1217 | .musleabihf, | |
| 1218 | => .hard, | |
| 1219 | else => .soft, | |
| 1220 | }; | |
| 1221 | } | |
| 1222 | ||
| 1223 | /// Caller owns returned memory. | |
| 1224 | pub fn getStandardDynamicLinkerPath( | |
| 1225 | self: Target, | |
| 1226 | allocator: *mem.Allocator, | |
| 1227 | ) error{ | |
| 1228 | OutOfMemory, | |
| 1229 | UnknownDynamicLinkerPath, | |
| 1230 | }![:0]u8 { | |
| 1231 | const a = allocator; | |
| 1232 | if (self.isAndroid()) { | |
| 1233 | return mem.dupeZ(a, u8, if (self.getArchPtrBitWidth() == 64) | |
| 1234 | "/system/bin/linker64" | |
| 1235 | else | |
| 1236 | "/system/bin/linker"); | |
| 1237 | } | |
| 1238 | ||
| 1239 | if (self.isMusl()) { | |
| 1240 | var result = try std.Buffer.init(allocator, "/lib/ld-musl-"); | |
| 1241 | defer result.deinit(); | |
| 1242 | ||
| 1243 | var is_arm = false; | |
| 1244 | switch (self.getArch()) { | |
| 1245 | .arm, .thumb => { | |
| 1246 | try result.append("arm"); | |
| 1247 | is_arm = true; | |
| 1248 | }, | |
| 1249 | .armeb, .thumbeb => { | |
| 1250 | try result.append("armeb"); | |
| 1251 | is_arm = true; | |
| 1252 | }, | |
| 1253 | else => |arch| try result.append(@tagName(arch)), | |
| 1254 | } | |
| 1255 | if (is_arm and self.getFloatAbi() == .hard) { | |
| 1256 | try result.append("hf"); | |
| 1257 | } | |
| 1258 | try result.append(".so.1"); | |
| 1259 | return result.toOwnedSlice(); | |
| 1260 | } | |
| 1261 | ||
| 1262 | switch (self.getOs()) { | |
| 1263 | .freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"), | |
| 1264 | .netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"), | |
| 1265 | .dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"), | |
| 1266 | .linux => switch (self.getArch()) { | |
| 1267 | .i386, | |
| 1268 | .sparc, | |
| 1269 | .sparcel, | |
| 1270 | => return mem.dupeZ(a, u8, "/lib/ld-linux.so.2"), | |
| 1271 | ||
| 1272 | .aarch64 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64.so.1"), | |
| 1273 | .aarch64_be => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_be.so.1"), | |
| 1274 | .aarch64_32 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_32.so.1"), | |
| 1275 | ||
| 1276 | .arm, | |
| 1277 | .armeb, | |
| 1278 | .thumb, | |
| 1279 | .thumbeb, | |
| 1280 | => return mem.dupeZ(a, u8, switch (self.getFloatAbi()) { | |
| 1281 | .hard => "/lib/ld-linux-armhf.so.3", | |
| 1282 | else => "/lib/ld-linux.so.3", | |
| 1283 | }), | |
| 1284 | ||
| 1285 | .mips, | |
| 1286 | .mipsel, | |
| 1287 | .mips64, | |
| 1288 | .mips64el, | |
| 1289 | => return error.UnknownDynamicLinkerPath, | |
| 1290 | ||
| 1291 | .powerpc => return mem.dupeZ(a, u8, "/lib/ld.so.1"), | |
| 1292 | .powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"), | |
| 1293 | .s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"), | |
| 1294 | .sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"), | |
| 1295 | .x86_64 => return mem.dupeZ(a, u8, switch (self.getAbi()) { | |
| 1296 | .gnux32 => "/libx32/ld-linux-x32.so.2", | |
| 1297 | else => "/lib64/ld-linux-x86-64.so.2", | |
| 1298 | }), | |
| 1299 | ||
| 1300 | .riscv32 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv32-ilp32.so.1"), | |
| 1301 | .riscv64 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv64-lp64.so.1"), | |
| 1302 | ||
| 1303 | .arc, | |
| 1304 | .avr, | |
| 1305 | .bpfel, | |
| 1306 | .bpfeb, | |
| 1307 | .hexagon, | |
| 1308 | .msp430, | |
| 1309 | .r600, | |
| 1310 | .amdgcn, | |
| 1311 | .tce, | |
| 1312 | .tcele, | |
| 1313 | .xcore, | |
| 1314 | .nvptx, | |
| 1315 | .nvptx64, | |
| 1316 | .le32, | |
| 1317 | .le64, | |
| 1318 | .amdil, | |
| 1319 | .amdil64, | |
| 1320 | .hsail, | |
| 1321 | .hsail64, | |
| 1322 | .spir, | |
| 1323 | .spir64, | |
| 1324 | .kalimba, | |
| 1325 | .shave, | |
| 1326 | .lanai, | |
| 1327 | .wasm32, | |
| 1328 | .wasm64, | |
| 1329 | .renderscript32, | |
| 1330 | .renderscript64, | |
| 1331 | => return error.UnknownDynamicLinkerPath, | |
| 1332 | }, | |
| 1333 | else => return error.UnknownDynamicLinkerPath, | |
| 1334 | } | |
| 1335 | } | |
| 1199 | 1336 | }; |
| 1200 | 1337 | |
| 1201 | 1338 | test "parseCpuFeatureSet" { |
src-self-hosted/introspect.zig+8| ... | ... | @@ -6,6 +6,14 @@ const fs = std.fs; |
| 6 | 6 | |
| 7 | 7 | const warn = std.debug.warn; |
| 8 | 8 | |
| 9 | pub fn detectDynamicLinker(allocator: *mem.Allocator, target: std.Target) ![:0]u8 { | |
| 10 | if (target == .Native) { | |
| 11 | return @import("libc_installation.zig").detectNativeDynamicLinker(allocator); | |
| 12 | } else { | |
| 13 | return target.getStandardDynamicLinkerPath(allocator); | |
| 14 | } | |
| 15 | } | |
| 16 | ||
| 9 | 17 | /// Caller must free result |
| 10 | 18 | pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 { |
| 11 | 19 | const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" }); |
src-self-hosted/libc_installation.zig+38-1| ... | ... | @@ -492,7 +492,7 @@ pub const LibCInstallation = struct { |
| 492 | 492 | const default_cc_exe = if (is_windows) "cc.exe" else "cc"; |
| 493 | 493 | |
| 494 | 494 | /// caller owns returned memory |
| 495 | pub fn ccPrintFileName( | |
| 495 | fn ccPrintFileName( | |
| 496 | 496 | allocator: *Allocator, |
| 497 | 497 | o_file: []const u8, |
| 498 | 498 | want_dirname: enum { full_path, only_dir }, |
| ... | ... | @@ -535,6 +535,43 @@ pub fn ccPrintFileName( |
| 535 | 535 | } |
| 536 | 536 | } |
| 537 | 537 | |
| 538 | /// Caller owns returned memory. | |
| 539 | pub fn detectNativeDynamicLinker(allocator: *Allocator) ![:0]u8 { | |
| 540 | const standard_ld_path = try std.Target.current.getStandardDynamicLinkerPath(allocator); | |
| 541 | var standard_ld_path_resource: ?[:0]u8 = standard_ld_path; // Set to null to avoid freeing it. | |
| 542 | defer if (standard_ld_path_resource) |s| allocator.free(s); | |
| 543 | ||
| 544 | const standard_ld_basename = fs.path.basename(standard_ld_path); | |
| 545 | ||
| 546 | { | |
| 547 | // Best case scenario: the current executable is dynamically linked, and we can iterate | |
| 548 | // over our own shared objects and find a dynamic linker. | |
| 549 | const lib_paths = try std.process.getSelfExeSharedLibPaths(allocator); | |
| 550 | defer allocator.free(lib_paths); | |
| 551 | ||
| 552 | for (lib_paths) |lib_path| { | |
| 553 | if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) { | |
| 554 | return std.mem.dupeZ(allocator, u8, lib_path); | |
| 555 | } | |
| 556 | } | |
| 557 | } | |
| 558 | ||
| 559 | // If Zig is statically linked, such as via distributed binary static builds, the above | |
| 560 | // trick won't work. What are we left with? Try to run the system C compiler and get | |
| 561 | // it to tell us the dynamic linker path. | |
| 562 | return ccPrintFileName(allocator, standard_ld_basename, .full_path) catch |err| switch (err) { | |
| 563 | error.OutOfMemory => return error.OutOfMemory, | |
| 564 | error.LibCRuntimeNotFound, | |
| 565 | error.CCompilerExitCode, | |
| 566 | error.CCompilerCrashed, | |
| 567 | error.UnableToSpawnCCompiler, | |
| 568 | => { | |
| 569 | standard_ld_path_resource = null; // Prevent freeing standard_ld_path. | |
| 570 | return standard_ld_path; | |
| 571 | }, | |
| 572 | }; | |
| 573 | } | |
| 574 | ||
| 538 | 575 | const Search = struct { |
| 539 | 576 | path: []const u8, |
| 540 | 577 | version: []const u8, |
src-self-hosted/stage2.zig+90-13| ... | ... | @@ -109,6 +109,7 @@ const Error = extern enum { |
| 109 | 109 | LibCKernel32LibNotFound, |
| 110 | 110 | UnsupportedArchitecture, |
| 111 | 111 | WindowsSdkNotFound, |
| 112 | UnknownDynamicLinkerPath, | |
| 112 | 113 | }; |
| 113 | 114 | |
| 114 | 115 | const FILE = std.c.FILE; |
| ... | ... | @@ -1012,24 +1013,100 @@ export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: |
| 1012 | 1013 | } |
| 1013 | 1014 | |
| 1014 | 1015 | // ABI warning |
| 1015 | export fn stage2_libc_cc_print_file_name( | |
| 1016 | out_ptr: *[*:0]u8, | |
| 1017 | out_len: *usize, | |
| 1018 | o_file: [*:0]const u8, | |
| 1019 | want_dirname: bool, | |
| 1020 | ) Error { | |
| 1021 | const result = @import("libc_installation.zig").ccPrintFileName( | |
| 1016 | const Stage2Target = extern struct { | |
| 1017 | arch: c_int, | |
| 1018 | sub_arch: c_int, | |
| 1019 | vendor: c_int, | |
| 1020 | os: c_int, | |
| 1021 | abi: c_int, | |
| 1022 | glibc_version: ?*Stage2GLibCVersion, // null means default | |
| 1023 | cpu_features: *Stage2CpuFeatures, | |
| 1024 | is_native: bool, | |
| 1025 | }; | |
| 1026 | ||
| 1027 | // ABI warning | |
| 1028 | const Stage2GLibCVersion = extern struct { | |
| 1029 | major: u32, | |
| 1030 | minor: u32, | |
| 1031 | patch: u32, | |
| 1032 | }; | |
| 1033 | ||
| 1034 | // ABI warning | |
| 1035 | export fn stage2_detect_dynamic_linker(in_target: *const Stage2Target, out_ptr: *[*:0]u8, out_len: *usize) Error { | |
| 1036 | const target: Target = if (in_target.is_native) .Native else .{ | |
| 1037 | .Cross = .{ | |
| 1038 | .arch = switch (enumInt(@TagType(Target.Arch), in_target.arch)) { | |
| 1039 | .arm => .{ .arm = enumInt(Target.Arch.Arm32, in_target.sub_arch) }, | |
| 1040 | .armeb => .{ .armeb = enumInt(Target.Arch.Arm32, in_target.sub_arch) }, | |
| 1041 | .thumb => .{ .thumb = enumInt(Target.Arch.Arm32, in_target.sub_arch) }, | |
| 1042 | .thumbeb => .{ .thumbeb = enumInt(Target.Arch.Arm32, in_target.sub_arch) }, | |
| 1043 | ||
| 1044 | .aarch64 => .{ .aarch64 = enumInt(Target.Arch.Arm64, in_target.sub_arch) }, | |
| 1045 | .aarch64_be => .{ .aarch64_be = enumInt(Target.Arch.Arm64, in_target.sub_arch) }, | |
| 1046 | .aarch64_32 => .{ .aarch64_32 = enumInt(Target.Arch.Arm64, in_target.sub_arch) }, | |
| 1047 | ||
| 1048 | .kalimba => .{ .kalimba = enumInt(Target.Arch.Kalimba, in_target.sub_arch) }, | |
| 1049 | ||
| 1050 | .arc => .arc, | |
| 1051 | .avr => .avr, | |
| 1052 | .bpfel => .bpfel, | |
| 1053 | .bpfeb => .bpfeb, | |
| 1054 | .hexagon => .hexagon, | |
| 1055 | .mips => .mips, | |
| 1056 | .mipsel => .mipsel, | |
| 1057 | .mips64 => .mips64, | |
| 1058 | .mips64el => .mips64el, | |
| 1059 | .msp430 => .msp430, | |
| 1060 | .powerpc => .powerpc, | |
| 1061 | .powerpc64 => .powerpc64, | |
| 1062 | .powerpc64le => .powerpc64le, | |
| 1063 | .r600 => .r600, | |
| 1064 | .amdgcn => .amdgcn, | |
| 1065 | .riscv32 => .riscv32, | |
| 1066 | .riscv64 => .riscv64, | |
| 1067 | .sparc => .sparc, | |
| 1068 | .sparcv9 => .sparcv9, | |
| 1069 | .sparcel => .sparcel, | |
| 1070 | .s390x => .s390x, | |
| 1071 | .tce => .tce, | |
| 1072 | .tcele => .tcele, | |
| 1073 | .i386 => .i386, | |
| 1074 | .x86_64 => .x86_64, | |
| 1075 | .xcore => .xcore, | |
| 1076 | .nvptx => .nvptx, | |
| 1077 | .nvptx64 => .nvptx64, | |
| 1078 | .le32 => .le32, | |
| 1079 | .le64 => .le64, | |
| 1080 | .amdil => .amdil, | |
| 1081 | .amdil64 => .amdil64, | |
| 1082 | .hsail => .hsail, | |
| 1083 | .hsail64 => .hsail64, | |
| 1084 | .spir => .spir, | |
| 1085 | .spir64 => .spir64, | |
| 1086 | .shave => .shave, | |
| 1087 | .lanai => .lanai, | |
| 1088 | .wasm32 => .wasm32, | |
| 1089 | .wasm64 => .wasm64, | |
| 1090 | .renderscript32 => .renderscript32, | |
| 1091 | .renderscript64 => .renderscript64, | |
| 1092 | }, | |
| 1093 | .os = enumInt(Target.Os, in_target.os), | |
| 1094 | .abi = enumInt(Target.Abi, in_target.abi), | |
| 1095 | .cpu_features = in_target.cpu_features.cpu_features, | |
| 1096 | }, | |
| 1097 | }; | |
| 1098 | const result = @import("introspect.zig").detectDynamicLinker( | |
| 1022 | 1099 | std.heap.c_allocator, |
| 1023 | mem.toSliceConst(u8, o_file), | |
| 1024 | if (want_dirname) .only_dir else .full_path, | |
| 1100 | target, | |
| 1025 | 1101 | ) catch |err| switch (err) { |
| 1026 | 1102 | error.OutOfMemory => return .OutOfMemory, |
| 1027 | error.LibCRuntimeNotFound => return .FileNotFound, | |
| 1028 | error.CCompilerExitCode => return .CCompilerExitCode, | |
| 1029 | error.CCompilerCrashed => return .CCompilerCrashed, | |
| 1030 | error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler, | |
| 1103 | error.UnknownDynamicLinkerPath => return .UnknownDynamicLinkerPath, | |
| 1031 | 1104 | }; |
| 1032 | 1105 | out_ptr.* = result.ptr; |
| 1033 | 1106 | out_len.* = result.len; |
| 1034 | 1107 | return .None; |
| 1035 | 1108 | } |
| 1109 | ||
| 1110 | fn enumInt(comptime Enum: type, int: c_int) Enum { | |
| 1111 | return @intToEnum(Enum, @intCast(@TagType(Enum), int)); | |
| 1112 | } |
src-self-hosted/util.zig-137| ... | ... | @@ -2,143 +2,6 @@ const std = @import("std"); |
| 2 | 2 | const Target = std.Target; |
| 3 | 3 | const llvm = @import("llvm.zig"); |
| 4 | 4 | |
| 5 | pub const FloatAbi = enum { | |
| 6 | Hard, | |
| 7 | Soft, | |
| 8 | SoftFp, | |
| 9 | }; | |
| 10 | ||
| 11 | /// TODO expose the arch and subarch separately | |
| 12 | pub fn isArmOrThumb(self: Target) bool { | |
| 13 | return switch (self.getArch()) { | |
| 14 | .arm, | |
| 15 | .armeb, | |
| 16 | .aarch64, | |
| 17 | .aarch64_be, | |
| 18 | .thumb, | |
| 19 | .thumbeb, | |
| 20 | => true, | |
| 21 | else => false, | |
| 22 | }; | |
| 23 | } | |
| 24 | ||
| 25 | pub fn getFloatAbi(self: Target) FloatAbi { | |
| 26 | return switch (self.getAbi()) { | |
| 27 | .gnueabihf, | |
| 28 | .eabihf, | |
| 29 | .musleabihf, | |
| 30 | => .Hard, | |
| 31 | else => .Soft, | |
| 32 | }; | |
| 33 | } | |
| 34 | ||
| 35 | pub fn getDynamicLinkerPath(self: Target) ?[]const u8 { | |
| 36 | const env = self.getAbi(); | |
| 37 | const arch = self.getArch(); | |
| 38 | const os = self.getOs(); | |
| 39 | switch (os) { | |
| 40 | .freebsd => { | |
| 41 | return "/libexec/ld-elf.so.1"; | |
| 42 | }, | |
| 43 | .linux => { | |
| 44 | switch (env) { | |
| 45 | .android => { | |
| 46 | if (self.getArchPtrBitWidth() == 64) { | |
| 47 | return "/system/bin/linker64"; | |
| 48 | } else { | |
| 49 | return "/system/bin/linker"; | |
| 50 | } | |
| 51 | }, | |
| 52 | .gnux32 => { | |
| 53 | if (arch == .x86_64) { | |
| 54 | return "/libx32/ld-linux-x32.so.2"; | |
| 55 | } | |
| 56 | }, | |
| 57 | .musl, | |
| 58 | .musleabi, | |
| 59 | .musleabihf, | |
| 60 | => { | |
| 61 | if (arch == .x86_64) { | |
| 62 | return "/lib/ld-musl-x86_64.so.1"; | |
| 63 | } | |
| 64 | }, | |
| 65 | else => {}, | |
| 66 | } | |
| 67 | switch (arch) { | |
| 68 | .i386, | |
| 69 | .sparc, | |
| 70 | .sparcel, | |
| 71 | => return "/lib/ld-linux.so.2", | |
| 72 | ||
| 73 | .aarch64 => return "/lib/ld-linux-aarch64.so.1", | |
| 74 | ||
| 75 | .aarch64_be => return "/lib/ld-linux-aarch64_be.so.1", | |
| 76 | ||
| 77 | .arm, | |
| 78 | .thumb, | |
| 79 | => return switch (getFloatAbi(self)) { | |
| 80 | .Hard => return "/lib/ld-linux-armhf.so.3", | |
| 81 | else => return "/lib/ld-linux.so.3", | |
| 82 | }, | |
| 83 | ||
| 84 | .armeb, | |
| 85 | .thumbeb, | |
| 86 | => return switch (getFloatAbi(self)) { | |
| 87 | .Hard => return "/lib/ld-linux-armhf.so.3", | |
| 88 | else => return "/lib/ld-linux.so.3", | |
| 89 | }, | |
| 90 | ||
| 91 | .mips, | |
| 92 | .mipsel, | |
| 93 | .mips64, | |
| 94 | .mips64el, | |
| 95 | => return null, | |
| 96 | ||
| 97 | .powerpc => return "/lib/ld.so.1", | |
| 98 | .powerpc64 => return "/lib64/ld64.so.2", | |
| 99 | .powerpc64le => return "/lib64/ld64.so.2", | |
| 100 | .s390x => return "/lib64/ld64.so.1", | |
| 101 | .sparcv9 => return "/lib64/ld-linux.so.2", | |
| 102 | .x86_64 => return "/lib64/ld-linux-x86-64.so.2", | |
| 103 | ||
| 104 | .arc, | |
| 105 | .avr, | |
| 106 | .bpfel, | |
| 107 | .bpfeb, | |
| 108 | .hexagon, | |
| 109 | .msp430, | |
| 110 | .r600, | |
| 111 | .amdgcn, | |
| 112 | .riscv32, | |
| 113 | .riscv64, | |
| 114 | .tce, | |
| 115 | .tcele, | |
| 116 | .xcore, | |
| 117 | .nvptx, | |
| 118 | .nvptx64, | |
| 119 | .le32, | |
| 120 | .le64, | |
| 121 | .amdil, | |
| 122 | .amdil64, | |
| 123 | .hsail, | |
| 124 | .hsail64, | |
| 125 | .spir, | |
| 126 | .spir64, | |
| 127 | .kalimba, | |
| 128 | .shave, | |
| 129 | .lanai, | |
| 130 | .wasm32, | |
| 131 | .wasm64, | |
| 132 | .renderscript32, | |
| 133 | .renderscript64, | |
| 134 | .aarch64_32, | |
| 135 | => return null, | |
| 136 | } | |
| 137 | }, | |
| 138 | else => return null, | |
| 139 | } | |
| 140 | } | |
| 141 | ||
| 142 | 5 | pub fn getDarwinArchString(self: Target) [:0]const u8 { |
| 143 | 6 | const arch = self.getArch(); |
| 144 | 7 | switch (arch) { |
src/codegen.cpp+12-40| ... | ... | @@ -8624,7 +8624,7 @@ Buf *codegen_generate_builtin_source(CodeGen *g) { |
| 8624 | 8624 | break; |
| 8625 | 8625 | } |
| 8626 | 8626 | buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type); |
| 8627 | const char *link_type = g->is_dynamic ? "Dynamic" : "Static"; | |
| 8627 | const char *link_type = g->have_dynamic_link ? "Dynamic" : "Static"; | |
| 8628 | 8628 | buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type); |
| 8629 | 8629 | buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build)); |
| 8630 | 8630 | buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded)); |
| ... | ... | @@ -8731,7 +8731,7 @@ static Error define_builtin_compile_vars(CodeGen *g) { |
| 8731 | 8731 | cache_int(&cache_hash, g->build_mode); |
| 8732 | 8732 | cache_bool(&cache_hash, g->strip_debug_symbols); |
| 8733 | 8733 | cache_int(&cache_hash, g->out_type); |
| 8734 | cache_bool(&cache_hash, g->is_dynamic); | |
| 8734 | cache_bool(&cache_hash, detect_dynamic_link(g)); | |
| 8735 | 8735 | cache_bool(&cache_hash, g->is_test_build); |
| 8736 | 8736 | cache_bool(&cache_hash, g->is_single_threaded); |
| 8737 | 8737 | cache_bool(&cache_hash, g->test_is_evented); |
| ... | ... | @@ -8957,6 +8957,8 @@ static void init(CodeGen *g) { |
| 8957 | 8957 | } |
| 8958 | 8958 | |
| 8959 | 8959 | static void detect_dynamic_linker(CodeGen *g) { |
| 8960 | Error err; | |
| 8961 | ||
| 8960 | 8962 | if (g->dynamic_linker_path != nullptr) |
| 8961 | 8963 | return; |
| 8962 | 8964 | if (!g->have_dynamic_link) |
| ... | ... | @@ -8964,45 +8966,15 @@ static void detect_dynamic_linker(CodeGen *g) { |
| 8964 | 8966 | if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic)) |
| 8965 | 8967 | return; |
| 8966 | 8968 | |
| 8967 | const char *standard_ld_path = target_dynamic_linker(g->zig_target); | |
| 8968 | if (standard_ld_path == nullptr) | |
| 8969 | return; | |
| 8970 | ||
| 8971 | if (g->zig_target->is_native) { | |
| 8972 | // target_dynamic_linker is usually correct. However on some systems, such as NixOS | |
| 8973 | // it will be incorrect. See if we can do better by looking at what zig's own | |
| 8974 | // dynamic linker path is. | |
| 8975 | g->dynamic_linker_path = get_self_dynamic_linker_path(); | |
| 8976 | if (g->dynamic_linker_path != nullptr) | |
| 8977 | return; | |
| 8978 | ||
| 8979 | // If Zig is statically linked, such as via distributed binary static builds, the above | |
| 8980 | // trick won't work. What are we left with? Try to run the system C compiler and get | |
| 8981 | // it to tell us the dynamic linker path | |
| 8982 | #if defined(ZIG_OS_LINUX) | |
| 8983 | { | |
| 8984 | Error err; | |
| 8985 | for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) { | |
| 8986 | const char *lib_name = possible_ld_names[i]; | |
| 8987 | char *result_ptr; | |
| 8988 | size_t result_len; | |
| 8989 | if ((err = stage2_libc_cc_print_file_name(&result_ptr, &result_len, lib_name, false))) { | |
| 8990 | if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) { | |
| 8991 | fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err)); | |
| 8992 | exit(1); | |
| 8993 | } | |
| 8994 | continue; | |
| 8995 | } | |
| 8996 | g->dynamic_linker_path = buf_create_from_mem(result_ptr, result_len); | |
| 8997 | // Skips heap::c_allocator because the memory is allocated by stage2 library. | |
| 8998 | free(result_ptr); | |
| 8999 | return; | |
| 9000 | } | |
| 9001 | } | |
| 9002 | #endif | |
| 8969 | char *dynamic_linker_ptr; | |
| 8970 | size_t dynamic_linker_len; | |
| 8971 | if ((err = stage2_detect_dynamic_linker(g->zig_target, &dynamic_linker_ptr, &dynamic_linker_len))) { | |
| 8972 | fprintf(stderr, "Unable to detect dynamic linker: %s\n", err_str(err)); | |
| 8973 | exit(1); | |
| 9003 | 8974 | } |
| 9004 | ||
| 9005 | g->dynamic_linker_path = buf_create_from_str(standard_ld_path); | |
| 8975 | g->dynamic_linker_path = buf_create_from_mem(dynamic_linker_ptr, dynamic_linker_len); | |
| 8976 | // Skips heap::c_allocator because the memory is allocated by stage2 library. | |
| 8977 | free(dynamic_linker_ptr); | |
| 9006 | 8978 | } |
| 9007 | 8979 | |
| 9008 | 8980 | static void detect_libc(CodeGen *g) { |
src/compiler.cpp-34| ... | ... | @@ -4,20 +4,6 @@ |
| 4 | 4 | |
| 5 | 5 | #include <stdio.h> |
| 6 | 6 | |
| 7 | static Buf saved_dynamic_linker_path = BUF_INIT; | |
| 8 | static bool searched_for_dyn_linker = false; | |
| 9 | ||
| 10 | static void detect_dynamic_linker(Buf *lib_path) { | |
| 11 | #if defined(ZIG_OS_LINUX) | |
| 12 | for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) { | |
| 13 | if (buf_ends_with_str(lib_path, possible_ld_names[i])) { | |
| 14 | buf_init_from_buf(&saved_dynamic_linker_path, lib_path); | |
| 15 | break; | |
| 16 | } | |
| 17 | } | |
| 18 | #endif | |
| 19 | } | |
| 20 | ||
| 21 | 7 | Buf *get_self_libc_path(void) { |
| 22 | 8 | static Buf saved_libc_path = BUF_INIT; |
| 23 | 9 | static bool searched_for_libc = false; |
| ... | ... | @@ -43,25 +29,6 @@ Buf *get_self_libc_path(void) { |
| 43 | 29 | } |
| 44 | 30 | } |
| 45 | 31 | |
| 46 | Buf *get_self_dynamic_linker_path(void) { | |
| 47 | for (;;) { | |
| 48 | if (saved_dynamic_linker_path.list.length != 0) { | |
| 49 | return &saved_dynamic_linker_path; | |
| 50 | } | |
| 51 | if (searched_for_dyn_linker) | |
| 52 | return nullptr; | |
| 53 | ZigList<Buf *> lib_paths = {}; | |
| 54 | Error err; | |
| 55 | if ((err = os_self_exe_shared_libs(lib_paths))) | |
| 56 | return nullptr; | |
| 57 | for (size_t i = 0; i < lib_paths.length; i += 1) { | |
| 58 | Buf *lib_path = lib_paths.at(i); | |
| 59 | detect_dynamic_linker(lib_path); | |
| 60 | } | |
| 61 | searched_for_dyn_linker = true; | |
| 62 | } | |
| 63 | } | |
| 64 | ||
| 65 | 32 | Error get_compiler_id(Buf **result) { |
| 66 | 33 | static Buf saved_compiler_id = BUF_INIT; |
| 67 | 34 | |
| ... | ... | @@ -98,7 +65,6 @@ Error get_compiler_id(Buf **result) { |
| 98 | 65 | return err; |
| 99 | 66 | for (size_t i = 0; i < lib_paths.length; i += 1) { |
| 100 | 67 | Buf *lib_path = lib_paths.at(i); |
| 101 | detect_dynamic_linker(lib_path); | |
| 102 | 68 | if ((err = cache_add_file(ch, lib_path))) |
| 103 | 69 | return err; |
| 104 | 70 | } |
src/compiler.hpp-1| ... | ... | @@ -12,7 +12,6 @@ |
| 12 | 12 | #include "error.hpp" |
| 13 | 13 | |
| 14 | 14 | Error get_compiler_id(Buf **result); |
| 15 | Buf *get_self_dynamic_linker_path(void); | |
| 16 | 15 | Buf *get_self_libc_path(void); |
| 17 | 16 | |
| 18 | 17 | Buf *get_zig_lib_dir(void); |
src/error.cpp+1| ... | ... | @@ -80,6 +80,7 @@ const char *err_str(Error err) { |
| 80 | 80 | case ErrorLibCKernel32LibNotFound: return "kernel32 library not found"; |
| 81 | 81 | case ErrorUnsupportedArchitecture: return "unsupported architecture"; |
| 82 | 82 | case ErrorWindowsSdkNotFound: return "Windows SDK not found"; |
| 83 | case ErrorUnknownDynamicLinkerPath: return "Windows SDK not found"; | |
| 83 | 84 | } |
| 84 | 85 | return "(invalid error)"; |
| 85 | 86 | } |
src/os.cpp-18| ... | ... | @@ -2129,21 +2129,3 @@ void os_file_close(OsFile *file) { |
| 2129 | 2129 | *file = -1; |
| 2130 | 2130 | #endif |
| 2131 | 2131 | } |
| 2132 | ||
| 2133 | #ifdef ZIG_OS_LINUX | |
| 2134 | const char *possible_ld_names[] = { | |
| 2135 | #if defined(ZIG_ARCH_X86_64) | |
| 2136 | "ld-linux-x86-64.so.2", | |
| 2137 | "ld-musl-x86_64.so.1", | |
| 2138 | #elif defined(ZIG_ARCH_ARM64) | |
| 2139 | "ld-linux-aarch64.so.1", | |
| 2140 | "ld-musl-aarch64.so.1", | |
| 2141 | #elif defined(ZIG_ARCH_ARM) | |
| 2142 | "ld-linux-armhf.so.3", | |
| 2143 | "ld-musl-armhf.so.1", | |
| 2144 | "ld-linux.so.3", | |
| 2145 | "ld-musl-arm.so.1", | |
| 2146 | #endif | |
| 2147 | NULL, | |
| 2148 | }; | |
| 2149 | #endif |
src/os.hpp-4| ... | ... | @@ -43,10 +43,6 @@ |
| 43 | 43 | #define ZIG_ARCH_UNKNOWN |
| 44 | 44 | #endif |
| 45 | 45 | |
| 46 | #ifdef ZIG_OS_LINUX | |
| 47 | extern const char *possible_ld_names[]; | |
| 48 | #endif | |
| 49 | ||
| 50 | 46 | #if defined(ZIG_OS_WINDOWS) |
| 51 | 47 | #define ZIG_PRI_usize "I64u" |
| 52 | 48 | #define ZIG_PRI_i64 "I64d" |
src/stage2.cpp+2-4| ... | ... | @@ -171,9 +171,7 @@ enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) { |
| 171 | 171 | stage2_panic(msg, strlen(msg)); |
| 172 | 172 | } |
| 173 | 173 | |
| 174 | enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len, | |
| 175 | const char *o_file, bool want_dirname) | |
| 176 | { | |
| 177 | const char *msg = "stage0 called stage2_libc_cc_print_file_name"; | |
| 174 | enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, char **out_ptr, size_t *out_len) { | |
| 175 | const char *msg = "stage0 called stage2_detect_dynamic_linker"; | |
| 178 | 176 | stage2_panic(msg, strlen(msg)); |
| 179 | 177 | } |
src/stage2.h+67-2| ... | ... | @@ -12,6 +12,8 @@ |
| 12 | 12 | #include <stdint.h> |
| 13 | 13 | #include <stdio.h> |
| 14 | 14 | |
| 15 | #include "zig_llvm.h" | |
| 16 | ||
| 15 | 17 | #ifdef __cplusplus |
| 16 | 18 | #define ZIG_EXTERN_C extern "C" |
| 17 | 19 | #else |
| ... | ... | @@ -100,6 +102,7 @@ enum Error { |
| 100 | 102 | ErrorLibCKernel32LibNotFound, |
| 101 | 103 | ErrorUnsupportedArchitecture, |
| 102 | 104 | ErrorWindowsSdkNotFound, |
| 105 | ErrorUnknownDynamicLinkerPath, | |
| 103 | 106 | }; |
| 104 | 107 | |
| 105 | 108 | // ABI warning |
| ... | ... | @@ -242,8 +245,70 @@ ZIG_EXTERN_C enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, c |
| 242 | 245 | ZIG_EXTERN_C enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file); |
| 243 | 246 | // ABI warning |
| 244 | 247 | ZIG_EXTERN_C enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc); |
| 248 | ||
| 249 | // ABI warning | |
| 250 | // Synchronize with target.cpp::os_list | |
| 251 | enum Os { | |
| 252 | OsFreestanding, | |
| 253 | OsAnanas, | |
| 254 | OsCloudABI, | |
| 255 | OsDragonFly, | |
| 256 | OsFreeBSD, | |
| 257 | OsFuchsia, | |
| 258 | OsIOS, | |
| 259 | OsKFreeBSD, | |
| 260 | OsLinux, | |
| 261 | OsLv2, // PS3 | |
| 262 | OsMacOSX, | |
| 263 | OsNetBSD, | |
| 264 | OsOpenBSD, | |
| 265 | OsSolaris, | |
| 266 | OsWindows, | |
| 267 | OsHaiku, | |
| 268 | OsMinix, | |
| 269 | OsRTEMS, | |
| 270 | OsNaCl, // Native Client | |
| 271 | OsCNK, // BG/P Compute-Node Kernel | |
| 272 | OsAIX, | |
| 273 | OsCUDA, // NVIDIA CUDA | |
| 274 | OsNVCL, // NVIDIA OpenCL | |
| 275 | OsAMDHSA, // AMD HSA Runtime | |
| 276 | OsPS4, | |
| 277 | OsELFIAMCU, | |
| 278 | OsTvOS, // Apple tvOS | |
| 279 | OsWatchOS, // Apple watchOS | |
| 280 | OsMesa3D, | |
| 281 | OsContiki, | |
| 282 | OsAMDPAL, | |
| 283 | OsHermitCore, | |
| 284 | OsHurd, | |
| 285 | OsWASI, | |
| 286 | OsEmscripten, | |
| 287 | OsUefi, | |
| 288 | OsOther, | |
| 289 | }; | |
| 290 | ||
| 291 | // ABI warning | |
| 292 | struct ZigGLibCVersion { | |
| 293 | uint32_t major; // always 2 | |
| 294 | uint32_t minor; | |
| 295 | uint32_t patch; | |
| 296 | }; | |
| 297 | ||
| 298 | // ABI warning | |
| 299 | struct ZigTarget { | |
| 300 | enum ZigLLVM_ArchType arch; | |
| 301 | enum ZigLLVM_SubArchType sub_arch; | |
| 302 | enum ZigLLVM_VendorType vendor; | |
| 303 | Os os; | |
| 304 | enum ZigLLVM_EnvironmentType abi; | |
| 305 | struct ZigGLibCVersion *glibc_version; // null means default | |
| 306 | struct Stage2CpuFeatures *cpu_features; | |
| 307 | bool is_native; | |
| 308 | }; | |
| 309 | ||
| 245 | 310 | // ABI warning |
| 246 | ZIG_EXTERN_C enum Error stage2_libc_cc_print_file_name(char **out_ptr, size_t *out_len, | |
| 247 | const char *o_file, bool want_dirname); | |
| 311 | ZIG_EXTERN_C enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, | |
| 312 | char **out_ptr, size_t *out_len); | |
| 248 | 313 | |
| 249 | 314 | #endif |
src/target.cpp-203| ... | ... | @@ -1204,213 +1204,10 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static, |
| 1204 | 1204 | } |
| 1205 | 1205 | } |
| 1206 | 1206 | |
| 1207 | enum FloatAbi { | |
| 1208 | FloatAbiHard, | |
| 1209 | FloatAbiSoft, | |
| 1210 | FloatAbiSoftFp, | |
| 1211 | }; | |
| 1212 | ||
| 1213 | static FloatAbi get_float_abi(const ZigTarget *target) { | |
| 1214 | const ZigLLVM_EnvironmentType env = target->abi; | |
| 1215 | if (env == ZigLLVM_GNUEABIHF || | |
| 1216 | env == ZigLLVM_EABIHF || | |
| 1217 | env == ZigLLVM_MuslEABIHF) | |
| 1218 | { | |
| 1219 | return FloatAbiHard; | |
| 1220 | } else { | |
| 1221 | return FloatAbiSoft; | |
| 1222 | } | |
| 1223 | } | |
| 1224 | ||
| 1225 | static bool is_64_bit(ZigLLVM_ArchType arch) { | |
| 1226 | return target_arch_pointer_bit_width(arch) == 64; | |
| 1227 | } | |
| 1228 | ||
| 1229 | 1207 | bool target_is_android(const ZigTarget *target) { |
| 1230 | 1208 | return target->abi == ZigLLVM_Android; |
| 1231 | 1209 | } |
| 1232 | 1210 | |
| 1233 | const char *target_dynamic_linker(const ZigTarget *target) { | |
| 1234 | if (target_is_android(target)) { | |
| 1235 | return is_64_bit(target->arch) ? "/system/bin/linker64" : "/system/bin/linker"; | |
| 1236 | } | |
| 1237 | ||
| 1238 | if (target_is_musl(target)) { | |
| 1239 | Buf buf = BUF_INIT; | |
| 1240 | buf_init_from_str(&buf, "/lib/ld-musl-"); | |
| 1241 | bool is_arm = false; | |
| 1242 | switch (target->arch) { | |
| 1243 | case ZigLLVM_arm: | |
| 1244 | case ZigLLVM_thumb: | |
| 1245 | buf_append_str(&buf, "arm"); | |
| 1246 | is_arm = true; | |
| 1247 | break; | |
| 1248 | case ZigLLVM_armeb: | |
| 1249 | case ZigLLVM_thumbeb: | |
| 1250 | buf_append_str(&buf, "armeb"); | |
| 1251 | is_arm = true; | |
| 1252 | break; | |
| 1253 | default: | |
| 1254 | buf_append_str(&buf, target_arch_name(target->arch)); | |
| 1255 | } | |
| 1256 | if (is_arm && get_float_abi(target) == FloatAbiHard) { | |
| 1257 | buf_append_str(&buf, "hf"); | |
| 1258 | } | |
| 1259 | buf_append_str(&buf, ".so.1"); | |
| 1260 | return buf_ptr(&buf); | |
| 1261 | } | |
| 1262 | ||
| 1263 | switch (target->os) { | |
| 1264 | case OsFreeBSD: | |
| 1265 | return "/libexec/ld-elf.so.1"; | |
| 1266 | case OsNetBSD: | |
| 1267 | return "/libexec/ld.elf_so"; | |
| 1268 | case OsDragonFly: | |
| 1269 | return "/libexec/ld-elf.so.2"; | |
| 1270 | case OsLinux: { | |
| 1271 | const ZigLLVM_EnvironmentType abi = target->abi; | |
| 1272 | switch (target->arch) { | |
| 1273 | case ZigLLVM_UnknownArch: | |
| 1274 | zig_unreachable(); | |
| 1275 | case ZigLLVM_x86: | |
| 1276 | case ZigLLVM_sparc: | |
| 1277 | case ZigLLVM_sparcel: | |
| 1278 | return "/lib/ld-linux.so.2"; | |
| 1279 | ||
| 1280 | case ZigLLVM_aarch64: | |
| 1281 | return "/lib/ld-linux-aarch64.so.1"; | |
| 1282 | ||
| 1283 | case ZigLLVM_aarch64_be: | |
| 1284 | return "/lib/ld-linux-aarch64_be.so.1"; | |
| 1285 | ||
| 1286 | case ZigLLVM_aarch64_32: | |
| 1287 | return "/lib/ld-linux-aarch64_32.so.1"; | |
| 1288 | ||
| 1289 | case ZigLLVM_arm: | |
| 1290 | case ZigLLVM_thumb: | |
| 1291 | if (get_float_abi(target) == FloatAbiHard) { | |
| 1292 | return "/lib/ld-linux-armhf.so.3"; | |
| 1293 | } else { | |
| 1294 | return "/lib/ld-linux.so.3"; | |
| 1295 | } | |
| 1296 | ||
| 1297 | case ZigLLVM_armeb: | |
| 1298 | case ZigLLVM_thumbeb: | |
| 1299 | if (get_float_abi(target) == FloatAbiHard) { | |
| 1300 | return "/lib/ld-linux-armhf.so.3"; | |
| 1301 | } else { | |
| 1302 | return "/lib/ld-linux.so.3"; | |
| 1303 | } | |
| 1304 | ||
| 1305 | case ZigLLVM_mips: | |
| 1306 | case ZigLLVM_mipsel: | |
| 1307 | case ZigLLVM_mips64: | |
| 1308 | case ZigLLVM_mips64el: | |
| 1309 | zig_panic("TODO implement target_dynamic_linker for mips"); | |
| 1310 | ||
| 1311 | case ZigLLVM_ppc: | |
| 1312 | return "/lib/ld.so.1"; | |
| 1313 | ||
| 1314 | case ZigLLVM_ppc64: | |
| 1315 | return "/lib64/ld64.so.2"; | |
| 1316 | ||
| 1317 | case ZigLLVM_ppc64le: | |
| 1318 | return "/lib64/ld64.so.2"; | |
| 1319 | ||
| 1320 | case ZigLLVM_systemz: | |
| 1321 | return "/lib64/ld64.so.1"; | |
| 1322 | ||
| 1323 | case ZigLLVM_sparcv9: | |
| 1324 | return "/lib64/ld-linux.so.2"; | |
| 1325 | ||
| 1326 | case ZigLLVM_x86_64: | |
| 1327 | if (abi == ZigLLVM_GNUX32) { | |
| 1328 | return "/libx32/ld-linux-x32.so.2"; | |
| 1329 | } | |
| 1330 | if (abi == ZigLLVM_Musl || abi == ZigLLVM_MuslEABI || abi == ZigLLVM_MuslEABIHF) { | |
| 1331 | return "/lib/ld-musl-x86_64.so.1"; | |
| 1332 | } | |
| 1333 | return "/lib64/ld-linux-x86-64.so.2"; | |
| 1334 | ||
| 1335 | case ZigLLVM_wasm32: | |
| 1336 | case ZigLLVM_wasm64: | |
| 1337 | return nullptr; | |
| 1338 | ||
| 1339 | case ZigLLVM_riscv32: | |
| 1340 | return "/lib/ld-linux-riscv32-ilp32.so.1"; | |
| 1341 | case ZigLLVM_riscv64: | |
| 1342 | return "/lib/ld-linux-riscv64-lp64.so.1"; | |
| 1343 | ||
| 1344 | case ZigLLVM_arc: | |
| 1345 | case ZigLLVM_avr: | |
| 1346 | case ZigLLVM_bpfel: | |
| 1347 | case ZigLLVM_bpfeb: | |
| 1348 | case ZigLLVM_hexagon: | |
| 1349 | case ZigLLVM_msp430: | |
| 1350 | case ZigLLVM_r600: | |
| 1351 | case ZigLLVM_amdgcn: | |
| 1352 | case ZigLLVM_tce: | |
| 1353 | case ZigLLVM_tcele: | |
| 1354 | case ZigLLVM_xcore: | |
| 1355 | case ZigLLVM_nvptx: | |
| 1356 | case ZigLLVM_nvptx64: | |
| 1357 | case ZigLLVM_le32: | |
| 1358 | case ZigLLVM_le64: | |
| 1359 | case ZigLLVM_amdil: | |
| 1360 | case ZigLLVM_amdil64: | |
| 1361 | case ZigLLVM_hsail: | |
| 1362 | case ZigLLVM_hsail64: | |
| 1363 | case ZigLLVM_spir: | |
| 1364 | case ZigLLVM_spir64: | |
| 1365 | case ZigLLVM_kalimba: | |
| 1366 | case ZigLLVM_shave: | |
| 1367 | case ZigLLVM_lanai: | |
| 1368 | case ZigLLVM_renderscript32: | |
| 1369 | case ZigLLVM_renderscript64: | |
| 1370 | zig_panic("TODO implement target_dynamic_linker for this arch"); | |
| 1371 | } | |
| 1372 | zig_unreachable(); | |
| 1373 | } | |
| 1374 | case OsFreestanding: | |
| 1375 | case OsIOS: | |
| 1376 | case OsTvOS: | |
| 1377 | case OsWatchOS: | |
| 1378 | case OsMacOSX: | |
| 1379 | case OsUefi: | |
| 1380 | case OsWindows: | |
| 1381 | case OsEmscripten: | |
| 1382 | case OsOther: | |
| 1383 | return nullptr; | |
| 1384 | ||
| 1385 | case OsAnanas: | |
| 1386 | case OsCloudABI: | |
| 1387 | case OsFuchsia: | |
| 1388 | case OsKFreeBSD: | |
| 1389 | case OsLv2: | |
| 1390 | case OsOpenBSD: | |
| 1391 | case OsSolaris: | |
| 1392 | case OsHaiku: | |
| 1393 | case OsMinix: | |
| 1394 | case OsRTEMS: | |
| 1395 | case OsNaCl: | |
| 1396 | case OsCNK: | |
| 1397 | case OsAIX: | |
| 1398 | case OsCUDA: | |
| 1399 | case OsNVCL: | |
| 1400 | case OsAMDHSA: | |
| 1401 | case OsPS4: | |
| 1402 | case OsELFIAMCU: | |
| 1403 | case OsMesa3D: | |
| 1404 | case OsContiki: | |
| 1405 | case OsAMDPAL: | |
| 1406 | case OsHermitCore: | |
| 1407 | case OsHurd: | |
| 1408 | case OsWASI: | |
| 1409 | zig_panic("TODO implement target_dynamic_linker for this OS"); | |
| 1410 | } | |
| 1411 | zig_unreachable(); | |
| 1412 | } | |
| 1413 | ||
| 1414 | 1211 | bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) { |
| 1415 | 1212 | assert(host_target != nullptr); |
| 1416 | 1213 |
src/target.hpp+1-61| ... | ... | @@ -8,51 +8,10 @@ |
| 8 | 8 | #ifndef ZIG_TARGET_HPP |
| 9 | 9 | #define ZIG_TARGET_HPP |
| 10 | 10 | |
| 11 | #include <zig_llvm.h> | |
| 11 | #include "stage2.h" | |
| 12 | 12 | |
| 13 | 13 | struct Buf; |
| 14 | 14 | |
| 15 | // Synchronize with target.cpp::os_list | |
| 16 | enum Os { | |
| 17 | OsFreestanding, | |
| 18 | OsAnanas, | |
| 19 | OsCloudABI, | |
| 20 | OsDragonFly, | |
| 21 | OsFreeBSD, | |
| 22 | OsFuchsia, | |
| 23 | OsIOS, | |
| 24 | OsKFreeBSD, | |
| 25 | OsLinux, | |
| 26 | OsLv2, // PS3 | |
| 27 | OsMacOSX, | |
| 28 | OsNetBSD, | |
| 29 | OsOpenBSD, | |
| 30 | OsSolaris, | |
| 31 | OsWindows, | |
| 32 | OsHaiku, | |
| 33 | OsMinix, | |
| 34 | OsRTEMS, | |
| 35 | OsNaCl, // Native Client | |
| 36 | OsCNK, // BG/P Compute-Node Kernel | |
| 37 | OsAIX, | |
| 38 | OsCUDA, // NVIDIA CUDA | |
| 39 | OsNVCL, // NVIDIA OpenCL | |
| 40 | OsAMDHSA, // AMD HSA Runtime | |
| 41 | OsPS4, | |
| 42 | OsELFIAMCU, | |
| 43 | OsTvOS, // Apple tvOS | |
| 44 | OsWatchOS, // Apple watchOS | |
| 45 | OsMesa3D, | |
| 46 | OsContiki, | |
| 47 | OsAMDPAL, | |
| 48 | OsHermitCore, | |
| 49 | OsHurd, | |
| 50 | OsWASI, | |
| 51 | OsEmscripten, | |
| 52 | OsUefi, | |
| 53 | OsOther, | |
| 54 | }; | |
| 55 | ||
| 56 | 15 | // Synchronize with target.cpp::subarch_list_list |
| 57 | 16 | enum SubArchList { |
| 58 | 17 | SubArchListNone, |
| ... | ... | @@ -78,23 +37,6 @@ enum TargetSubsystem { |
| 78 | 37 | TargetSubsystemAuto |
| 79 | 38 | }; |
| 80 | 39 | |
| 81 | struct ZigGLibCVersion { | |
| 82 | uint32_t major; // always 2 | |
| 83 | uint32_t minor; | |
| 84 | uint32_t patch; | |
| 85 | }; | |
| 86 | ||
| 87 | struct ZigTarget { | |
| 88 | ZigLLVM_ArchType arch; | |
| 89 | ZigLLVM_SubArchType sub_arch; | |
| 90 | ZigLLVM_VendorType vendor; | |
| 91 | Os os; | |
| 92 | ZigLLVM_EnvironmentType abi; | |
| 93 | ZigGLibCVersion *glibc_version; // null means default | |
| 94 | Stage2CpuFeatures *cpu_features; | |
| 95 | bool is_native; | |
| 96 | }; | |
| 97 | ||
| 98 | 40 | enum CIntType { |
| 99 | 41 | CIntTypeShort, |
| 100 | 42 | CIntTypeUShort, |
| ... | ... | @@ -168,8 +110,6 @@ const char *target_lib_file_prefix(const ZigTarget *target); |
| 168 | 110 | const char *target_lib_file_ext(const ZigTarget *target, bool is_static, |
| 169 | 111 | size_t version_major, size_t version_minor, size_t version_patch); |
| 170 | 112 | |
| 171 | const char *target_dynamic_linker(const ZigTarget *target); | |
| 172 | ||
| 173 | 113 | bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target); |
| 174 | 114 | ZigLLVM_OSType get_llvm_os_type(Os os_type); |
| 175 | 115 |