| ... | @@ -965,6 +965,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -965,6 +965,7 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 965 | defer arena_allocator.deinit(); | 965 | defer arena_allocator.deinit(); |
| 966 | const arena = arena_allocator.allocator(); | 966 | const arena = arena_allocator.allocator(); |
| 967 | | 967 | |
| | 968 | const target = self.base.options.target; |
| 968 | const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type. | 969 | const directory = self.base.options.emit.?.directory; // Just an alias to make it shorter to type. |
| 969 | const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path}); | 970 | const full_out_path = try directory.join(arena, &[_][]const u8{self.base.options.emit.?.sub_path}); |
| 970 | | 971 | |
| ... | @@ -993,22 +994,63 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node | ... | @@ -993,22 +994,63 @@ pub fn flushModule(self: *Elf, comp: *Compilation, prog_node: *std.Progress.Node |
| 993 | try positionals.append(.{ .path = key.status.success.object_path }); | 994 | try positionals.append(.{ .path = key.status.success.object_path }); |
| 994 | } | 995 | } |
| 995 | | 996 | |
| | 997 | for (positionals.items) |obj| { |
| | 998 | const in_file = try std.fs.cwd().openFile(obj.path, .{}); |
| | 999 | defer in_file.close(); |
| | 1000 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| | 1001 | self.parsePositional(in_file, obj.path, obj.must_link, &parse_ctx) catch |err| |
| | 1002 | try self.handleAndReportParseError(obj.path, err, &parse_ctx); |
| | 1003 | } |
| | 1004 | |
| | 1005 | var system_libs = std.ArrayList(SystemLib).init(arena); |
| | 1006 | |
| | 1007 | // libc dep |
| | 1008 | self.error_flags.missing_libc = false; |
| | 1009 | if (self.base.options.link_libc) { |
| | 1010 | if (self.base.options.libc_installation != null) { |
| | 1011 | @panic("TODO explicit libc_installation"); |
| | 1012 | } else if (target.isGnuLibC()) { |
| | 1013 | try system_libs.ensureUnusedCapacity(glibc.libs.len + 1); |
| | 1014 | for (glibc.libs) |lib| { |
| | 1015 | const lib_path = try std.fmt.allocPrint(arena, "{s}{c}lib{s}.so.{d}", .{ |
| | 1016 | comp.glibc_so_files.?.dir_path, fs.path.sep, lib.name, lib.sover, |
| | 1017 | }); |
| | 1018 | system_libs.appendAssumeCapacity(.{ .path = lib_path }); |
| | 1019 | } |
| | 1020 | system_libs.appendAssumeCapacity(.{ |
| | 1021 | .path = try comp.get_libc_crt_file(arena, "libc_nonshared.a"), |
| | 1022 | }); |
| | 1023 | } else if (target.isMusl()) { |
| | 1024 | const path = try comp.get_libc_crt_file(arena, switch (self.base.options.link_mode) { |
| | 1025 | .Static => "libc.a", |
| | 1026 | .Dynamic => "libc.so", |
| | 1027 | }); |
| | 1028 | try system_libs.append(.{ .path = path }); |
| | 1029 | } else { |
| | 1030 | self.error_flags.missing_libc = true; |
| | 1031 | } |
| | 1032 | } |
| | 1033 | |
| | 1034 | for (system_libs.items) |lib| { |
| | 1035 | const in_file = try std.fs.cwd().openFile(lib.path, .{}); |
| | 1036 | defer in_file.close(); |
| | 1037 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| | 1038 | self.parseLibrary(in_file, lib, false, &parse_ctx) catch |err| |
| | 1039 | try self.handleAndReportParseError(lib.path, err, &parse_ctx); |
| | 1040 | } |
| | 1041 | |
| | 1042 | // Finally, as the last input object add compiler_rt if any. |
| 996 | const compiler_rt_path: ?[]const u8 = blk: { | 1043 | const compiler_rt_path: ?[]const u8 = blk: { |
| 997 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; | 1044 | if (comp.compiler_rt_lib) |x| break :blk x.full_object_path; |
| 998 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; | 1045 | if (comp.compiler_rt_obj) |x| break :blk x.full_object_path; |
| 999 | break :blk null; | 1046 | break :blk null; |
| 1000 | }; | 1047 | }; |
| 1001 | if (compiler_rt_path) |path| { | 1048 | if (compiler_rt_path) |path| { |
| 1002 | try positionals.append(.{ .path = path }); | 1049 | const in_file = try std.fs.cwd().openFile(path, .{}); |
| 1003 | } | | |
| 1004 | | | |
| 1005 | for (positionals.items) |obj| { | | |
| 1006 | const in_file = try std.fs.cwd().openFile(obj.path, .{}); | | |
| 1007 | defer in_file.close(); | 1050 | defer in_file.close(); |
| 1008 | | | |
| 1009 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; | 1051 | var parse_ctx: ParseErrorCtx = .{ .detected_cpu_arch = undefined }; |
| 1010 | self.parsePositional(in_file, obj.path, obj.must_link, &parse_ctx) catch |err| | 1052 | self.parsePositional(in_file, path, false, &parse_ctx) catch |err| |
| 1011 | try self.handleAndReportParseError(obj.path, err, &parse_ctx); | 1053 | try self.handleAndReportParseError(path, err, &parse_ctx); |
| 1012 | } | 1054 | } |
| 1013 | | 1055 | |
| 1014 | // Handle any lazy symbols that were emitted by incremental compilation. | 1056 | // Handle any lazy symbols that were emitted by incremental compilation. |
| ... | @@ -1347,28 +1389,22 @@ fn parsePositional( | ... | @@ -1347,28 +1389,22 @@ fn parsePositional( |
| 1347 | if (Object.isObject(in_file)) { | 1389 | if (Object.isObject(in_file)) { |
| 1348 | try self.parseObject(in_file, path, ctx); | 1390 | try self.parseObject(in_file, path, ctx); |
| 1349 | } else { | 1391 | } else { |
| 1350 | try self.parseLibrary(in_file, path, .{ | 1392 | try self.parseLibrary(in_file, .{ .path = path }, must_link, ctx); |
| 1351 | .path = null, | | |
| 1352 | .needed = false, | | |
| 1353 | .weak = false, | | |
| 1354 | }, must_link, ctx); | | |
| 1355 | } | 1393 | } |
| 1356 | } | 1394 | } |
| 1357 | | 1395 | |
| 1358 | fn parseLibrary( | 1396 | fn parseLibrary( |
| 1359 | self: *Elf, | 1397 | self: *Elf, |
| 1360 | in_file: std.fs.File, | 1398 | in_file: std.fs.File, |
| 1361 | path: []const u8, | 1399 | lib: SystemLib, |
| 1362 | lib: link.SystemLib, | | |
| 1363 | must_link: bool, | 1400 | must_link: bool, |
| 1364 | ctx: *ParseErrorCtx, | 1401 | ctx: *ParseErrorCtx, |
| 1365 | ) ParseError!void { | 1402 | ) ParseError!void { |
| 1366 | const tracy = trace(@src()); | 1403 | const tracy = trace(@src()); |
| 1367 | defer tracy.end(); | 1404 | defer tracy.end(); |
| 1368 | _ = lib; | | |
| 1369 | | 1405 | |
| 1370 | if (Archive.isArchive(in_file)) { | 1406 | if (Archive.isArchive(in_file)) { |
| 1371 | try self.parseArchive(in_file, path, must_link, ctx); | 1407 | try self.parseArchive(in_file, lib.path, must_link, ctx); |
| 1372 | } else return error.UnknownFileType; | 1408 | } else return error.UnknownFileType; |
| 1373 | } | 1409 | } |
| 1374 | | 1410 | |
| ... | @@ -4149,6 +4185,11 @@ pub const null_sym = elf.Elf64_Sym{ | ... | @@ -4149,6 +4185,11 @@ pub const null_sym = elf.Elf64_Sym{ |
| 4149 | .st_size = 0, | 4185 | .st_size = 0, |
| 4150 | }; | 4186 | }; |
| 4151 | | 4187 | |
| | 4188 | const SystemLib = struct { |
| | 4189 | needed: bool = false, |
| | 4190 | path: []const u8, |
| | 4191 | }; |
| | 4192 | |
| 4152 | const std = @import("std"); | 4193 | const std = @import("std"); |
| 4153 | const build_options = @import("build_options"); | 4194 | const build_options = @import("build_options"); |
| 4154 | const builtin = @import("builtin"); | 4195 | const builtin = @import("builtin"); |