| author | |
| committer | |
| log | 75b6637d6013b735d36da0ab6e5655002a1b59e9 |
| tree | 76d3d25d4307138e34450da7ca30310f12197941 |
| parent | 7e76aab98abe94e01cfd8b01ce288360ed67dbc7 |
| parent | 5cde5f947fa12440463f684d9417ac00c8b9790a |
| signature |
zld: a couple of fixes which result in better rustc support9 files changed, 150 insertions(+), 32 deletions(-)
src/Compilation.zig+13-4| ... | @@ -654,6 +654,11 @@ pub const ClangPreprocessorMode = enum { | ... | @@ -654,6 +654,11 @@ pub const ClangPreprocessorMode = enum { |
| 654 | pub const SystemLib = link.SystemLib; | 654 | pub const SystemLib = link.SystemLib; |
| 655 | pub const CacheMode = link.CacheMode; | 655 | pub const CacheMode = link.CacheMode; |
| 656 | 656 | ||
| 657 | pub const LinkObject = struct { | ||
| 658 | path: []const u8, | ||
| 659 | must_link: bool = false, | ||
| 660 | }; | ||
| 661 | |||
| 657 | pub const InitOptions = struct { | 662 | pub const InitOptions = struct { |
| 658 | zig_lib_directory: Directory, | 663 | zig_lib_directory: Directory, |
| 659 | local_cache_directory: Directory, | 664 | local_cache_directory: Directory, |
| ... | @@ -698,7 +703,7 @@ pub const InitOptions = struct { | ... | @@ -698,7 +703,7 @@ pub const InitOptions = struct { |
| 698 | lib_dirs: []const []const u8 = &[0][]const u8{}, | 703 | lib_dirs: []const []const u8 = &[0][]const u8{}, |
| 699 | rpath_list: []const []const u8 = &[0][]const u8{}, | 704 | rpath_list: []const []const u8 = &[0][]const u8{}, |
| 700 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, | 705 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, |
| 701 | link_objects: []const []const u8 = &[0][]const u8{}, | 706 | link_objects: []LinkObject = &[0]LinkObject{}, |
| 702 | framework_dirs: []const []const u8 = &[0][]const u8{}, | 707 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| 703 | frameworks: []const []const u8 = &[0][]const u8{}, | 708 | frameworks: []const []const u8 = &[0][]const u8{}, |
| 704 | system_lib_names: []const []const u8 = &.{}, | 709 | system_lib_names: []const []const u8 = &.{}, |
| ... | @@ -1056,7 +1061,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1056,7 +1061,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1056 | if (options.system_lib_names.len != 0) | 1061 | if (options.system_lib_names.len != 0) |
| 1057 | break :x true; | 1062 | break :x true; |
| 1058 | for (options.link_objects) |obj| { | 1063 | for (options.link_objects) |obj| { |
| 1059 | switch (classifyFileExt(obj)) { | 1064 | switch (classifyFileExt(obj.path)) { |
| 1060 | .shared_library => break :x true, | 1065 | .shared_library => break :x true, |
| 1061 | else => continue, | 1066 | else => continue, |
| 1062 | } | 1067 | } |
| ... | @@ -1459,7 +1464,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1459,7 +1464,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1459 | if (options.c_source_files.len >= 1) { | 1464 | if (options.c_source_files.len >= 1) { |
| 1460 | hash.addBytes(options.c_source_files[0].src_path); | 1465 | hash.addBytes(options.c_source_files[0].src_path); |
| 1461 | } else if (options.link_objects.len >= 1) { | 1466 | } else if (options.link_objects.len >= 1) { |
| 1462 | hash.addBytes(options.link_objects[0]); | 1467 | hash.addBytes(options.link_objects[0].path); |
| 1463 | } | 1468 | } |
| 1464 | 1469 | ||
| 1465 | const digest = hash.final(); | 1470 | const digest = hash.final(); |
| ... | @@ -2265,7 +2270,11 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes | ... | @@ -2265,7 +2270,11 @@ fn addNonIncrementalStuffToCacheManifest(comp: *Compilation, man: *Cache.Manifes |
| 2265 | 2270 | ||
| 2266 | try man.addOptionalFile(comp.bin_file.options.linker_script); | 2271 | try man.addOptionalFile(comp.bin_file.options.linker_script); |
| 2267 | try man.addOptionalFile(comp.bin_file.options.version_script); | 2272 | try man.addOptionalFile(comp.bin_file.options.version_script); |
| 2268 | try man.addListOfFiles(comp.bin_file.options.objects); | 2273 | |
| 2274 | for (comp.bin_file.options.objects) |obj| { | ||
| 2275 | _ = try man.addFile(obj.path, null); | ||
| 2276 | man.hash.add(obj.must_link); | ||
| 2277 | } | ||
| 2269 | 2278 | ||
| 2270 | for (comp.c_object_table.keys()) |key| { | 2279 | for (comp.c_object_table.keys()) |key| { |
| 2271 | _ = try man.addFile(key.src.src_path, null); | 2280 | _ = try man.addFile(key.src.src_path, null); |
src/link.zig+7-4| ... | @@ -155,7 +155,7 @@ pub const Options = struct { | ... | @@ -155,7 +155,7 @@ pub const Options = struct { |
| 155 | soname: ?[]const u8, | 155 | soname: ?[]const u8, |
| 156 | llvm_cpu_features: ?[*:0]const u8, | 156 | llvm_cpu_features: ?[*:0]const u8, |
| 157 | 157 | ||
| 158 | objects: []const []const u8, | 158 | objects: []Compilation.LinkObject, |
| 159 | framework_dirs: []const []const u8, | 159 | framework_dirs: []const []const u8, |
| 160 | frameworks: []const []const u8, | 160 | frameworks: []const []const u8, |
| 161 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), | 161 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| ... | @@ -755,7 +755,10 @@ pub const File = struct { | ... | @@ -755,7 +755,10 @@ pub const File = struct { |
| 755 | // We are about to obtain this lock, so here we give other processes a chance first. | 755 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 756 | base.releaseLock(); | 756 | base.releaseLock(); |
| 757 | 757 | ||
| 758 | try man.addListOfFiles(base.options.objects); | 758 | for (base.options.objects) |obj| { |
| 759 | _ = try man.addFile(obj.path, null); | ||
| 760 | man.hash.add(obj.must_link); | ||
| 761 | } | ||
| 759 | for (comp.c_object_table.keys()) |key| { | 762 | for (comp.c_object_table.keys()) |key| { |
| 760 | _ = try man.addFile(key.status.success.object_path, null); | 763 | _ = try man.addFile(key.status.success.object_path, null); |
| 761 | } | 764 | } |
| ... | @@ -792,8 +795,8 @@ pub const File = struct { | ... | @@ -792,8 +795,8 @@ pub const File = struct { |
| 792 | var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files); | 795 | var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files); |
| 793 | defer object_files.deinit(); | 796 | defer object_files.deinit(); |
| 794 | 797 | ||
| 795 | for (base.options.objects) |obj_path| { | 798 | for (base.options.objects) |obj| { |
| 796 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj_path)); | 799 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj.path)); |
| 797 | } | 800 | } |
| 798 | for (comp.c_object_table.keys()) |key| { | 801 | for (comp.c_object_table.keys()) |key| { |
| 799 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.object_path)); | 802 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.object_path)); |
src/link/Coff.zig+9-3| ... | @@ -943,7 +943,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -943,7 +943,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 943 | 943 | ||
| 944 | comptime assert(Compilation.link_hash_implementation_version == 1); | 944 | comptime assert(Compilation.link_hash_implementation_version == 1); |
| 945 | 945 | ||
| 946 | try man.addListOfFiles(self.base.options.objects); | 946 | for (self.base.options.objects) |obj| { |
| 947 | _ = try man.addFile(obj.path, null); | ||
| 948 | man.hash.add(obj.must_link); | ||
| 949 | } | ||
| 947 | for (comp.c_object_table.keys()) |key| { | 950 | for (comp.c_object_table.keys()) |key| { |
| 948 | _ = try man.addFile(key.status.success.object_path, null); | 951 | _ = try man.addFile(key.status.success.object_path, null); |
| 949 | } | 952 | } |
| ... | @@ -1005,7 +1008,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -1005,7 +1008,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1005 | // build-obj. See also the corresponding TODO in linkAsArchive. | 1008 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1006 | const the_object_path = blk: { | 1009 | const the_object_path = blk: { |
| 1007 | if (self.base.options.objects.len != 0) | 1010 | if (self.base.options.objects.len != 0) |
| 1008 | break :blk self.base.options.objects[0]; | 1011 | break :blk self.base.options.objects[0].path; |
| 1009 | 1012 | ||
| 1010 | if (comp.c_object_table.count() != 0) | 1013 | if (comp.c_object_table.count() != 0) |
| 1011 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 1014 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -1110,7 +1113,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -1110,7 +1113,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1110 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); | 1113 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); |
| 1111 | } | 1114 | } |
| 1112 | 1115 | ||
| 1113 | try argv.appendSlice(self.base.options.objects); | 1116 | try argv.ensureUnusedCapacity(self.base.options.objects.len); |
| 1117 | for (self.base.options.objects) |obj| { | ||
| 1118 | argv.appendAssumeCapacity(obj.path); | ||
| 1119 | } | ||
| 1114 | 1120 | ||
| 1115 | for (comp.c_object_table.keys()) |key| { | 1121 | for (comp.c_object_table.keys()) |key| { |
| 1116 | try argv.append(key.status.success.object_path); | 1122 | try argv.append(key.status.success.object_path); |
src/link/Elf.zig+9-3| ... | @@ -1384,7 +1384,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1384,7 +1384,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1384 | 1384 | ||
| 1385 | try man.addOptionalFile(self.base.options.linker_script); | 1385 | try man.addOptionalFile(self.base.options.linker_script); |
| 1386 | try man.addOptionalFile(self.base.options.version_script); | 1386 | try man.addOptionalFile(self.base.options.version_script); |
| 1387 | try man.addListOfFiles(self.base.options.objects); | 1387 | for (self.base.options.objects) |obj| { |
| 1388 | _ = try man.addFile(obj.path, null); | ||
| 1389 | man.hash.add(obj.must_link); | ||
| 1390 | } | ||
| 1388 | for (comp.c_object_table.keys()) |key| { | 1391 | for (comp.c_object_table.keys()) |key| { |
| 1389 | _ = try man.addFile(key.status.success.object_path, null); | 1392 | _ = try man.addFile(key.status.success.object_path, null); |
| 1390 | } | 1393 | } |
| ... | @@ -1469,7 +1472,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1469,7 +1472,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1469 | // build-obj. See also the corresponding TODO in linkAsArchive. | 1472 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1470 | const the_object_path = blk: { | 1473 | const the_object_path = blk: { |
| 1471 | if (self.base.options.objects.len != 0) | 1474 | if (self.base.options.objects.len != 0) |
| 1472 | break :blk self.base.options.objects[0]; | 1475 | break :blk self.base.options.objects[0].path; |
| 1473 | 1476 | ||
| 1474 | if (comp.c_object_table.count() != 0) | 1477 | if (comp.c_object_table.count() != 0) |
| 1475 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 1478 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -1678,7 +1681,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1678,7 +1681,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1678 | } | 1681 | } |
| 1679 | 1682 | ||
| 1680 | // Positional arguments to the linker such as object files. | 1683 | // Positional arguments to the linker such as object files. |
| 1681 | try argv.appendSlice(self.base.options.objects); | 1684 | try argv.ensureUnusedCapacity(self.base.options.objects.len); |
| 1685 | for (self.base.options.objects) |obj| { | ||
| 1686 | argv.appendAssumeCapacity(obj.path); | ||
| 1687 | } | ||
| 1682 | 1688 | ||
| 1683 | for (comp.c_object_table.keys()) |key| { | 1689 | for (comp.c_object_table.keys()) |key| { |
| 1684 | try argv.append(key.status.success.object_path); | 1690 | try argv.append(key.status.success.object_path); |
src/link/MachO.zig+86-8| ... | @@ -141,6 +141,9 @@ objc_selrefs_section_index: ?u16 = null, | ... | @@ -141,6 +141,9 @@ objc_selrefs_section_index: ?u16 = null, |
| 141 | objc_classrefs_section_index: ?u16 = null, | 141 | objc_classrefs_section_index: ?u16 = null, |
| 142 | objc_data_section_index: ?u16 = null, | 142 | objc_data_section_index: ?u16 = null, |
| 143 | 143 | ||
| 144 | rustc_section_index: ?u16 = null, | ||
| 145 | rustc_section_size: u64 = 0, | ||
| 146 | |||
| 144 | bss_file_offset: u32 = 0, | 147 | bss_file_offset: u32 = 0, |
| 145 | tlv_bss_file_offset: u32 = 0, | 148 | tlv_bss_file_offset: u32 = 0, |
| 146 | 149 | ||
| ... | @@ -496,7 +499,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -496,7 +499,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 496 | 499 | ||
| 497 | comptime assert(Compilation.link_hash_implementation_version == 1); | 500 | comptime assert(Compilation.link_hash_implementation_version == 1); |
| 498 | 501 | ||
| 499 | try man.addListOfFiles(self.base.options.objects); | 502 | for (self.base.options.objects) |obj| { |
| 503 | _ = try man.addFile(obj.path, null); | ||
| 504 | man.hash.add(obj.must_link); | ||
| 505 | } | ||
| 500 | for (comp.c_object_table.keys()) |key| { | 506 | for (comp.c_object_table.keys()) |key| { |
| 501 | _ = try man.addFile(key.status.success.object_path, null); | 507 | _ = try man.addFile(key.status.success.object_path, null); |
| 502 | } | 508 | } |
| ... | @@ -568,8 +574,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -568,8 +574,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 568 | // here. TODO: think carefully about how we can avoid this redundant operation when doing | 574 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 569 | // build-obj. See also the corresponding TODO in linkAsArchive. | 575 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 570 | const the_object_path = blk: { | 576 | const the_object_path = blk: { |
| 571 | if (self.base.options.objects.len != 0) | 577 | if (self.base.options.objects.len != 0) { |
| 572 | break :blk self.base.options.objects[0]; | 578 | break :blk self.base.options.objects[0].path; |
| 579 | } | ||
| 573 | 580 | ||
| 574 | if (comp.c_object_table.count() != 0) | 581 | if (comp.c_object_table.count() != 0) |
| 575 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 582 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -678,8 +685,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -678,8 +685,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 678 | 685 | ||
| 679 | // Positional arguments to the linker such as object files and static archives. | 686 | // Positional arguments to the linker such as object files and static archives. |
| 680 | var positionals = std.ArrayList([]const u8).init(arena); | 687 | var positionals = std.ArrayList([]const u8).init(arena); |
| 688 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); | ||
| 681 | 689 | ||
| 682 | try positionals.appendSlice(self.base.options.objects); | 690 | var must_link_archives = std.StringArrayHashMap(void).init(arena); |
| 691 | try must_link_archives.ensureUnusedCapacity(self.base.options.objects.len); | ||
| 692 | |||
| 693 | for (self.base.options.objects) |obj| { | ||
| 694 | if (must_link_archives.contains(obj.path)) continue; | ||
| 695 | if (obj.must_link) { | ||
| 696 | _ = must_link_archives.getOrPutAssumeCapacity(obj.path); | ||
| 697 | } else { | ||
| 698 | _ = positionals.appendAssumeCapacity(obj.path); | ||
| 699 | } | ||
| 700 | } | ||
| 683 | 701 | ||
| 684 | for (comp.c_object_table.keys()) |key| { | 702 | for (comp.c_object_table.keys()) |key| { |
| 685 | try positionals.append(key.status.success.object_path); | 703 | try positionals.append(key.status.success.object_path); |
| ... | @@ -886,12 +904,17 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -886,12 +904,17 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 886 | try argv.append("dynamic_lookup"); | 904 | try argv.append("dynamic_lookup"); |
| 887 | } | 905 | } |
| 888 | 906 | ||
| 907 | for (must_link_archives.keys()) |lib| { | ||
| 908 | try argv.append(try std.fmt.allocPrint(arena, "-force_load {s}", .{lib})); | ||
| 909 | } | ||
| 910 | |||
| 889 | Compilation.dump_argv(argv.items); | 911 | Compilation.dump_argv(argv.items); |
| 890 | } | 912 | } |
| 891 | 913 | ||
| 892 | var dependent_libs = std.fifo.LinearFifo(Dylib.Id, .Dynamic).init(self.base.allocator); | 914 | var dependent_libs = std.fifo.LinearFifo(Dylib.Id, .Dynamic).init(self.base.allocator); |
| 893 | defer dependent_libs.deinit(); | 915 | defer dependent_libs.deinit(); |
| 894 | try self.parseInputFiles(positionals.items, self.base.options.sysroot, &dependent_libs); | 916 | try self.parseInputFiles(positionals.items, self.base.options.sysroot, &dependent_libs); |
| 917 | try self.parseAndForceLoadStaticArchives(must_link_archives.keys()); | ||
| 895 | try self.parseLibs(libs.items, self.base.options.sysroot, &dependent_libs); | 918 | try self.parseLibs(libs.items, self.base.options.sysroot, &dependent_libs); |
| 896 | try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); | 919 | try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); |
| 897 | } | 920 | } |
| ... | @@ -993,6 +1016,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -993,6 +1016,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 993 | try self.writeAtoms(); | 1016 | try self.writeAtoms(); |
| 994 | } | 1017 | } |
| 995 | 1018 | ||
| 1019 | if (self.rustc_section_index) |id| { | ||
| 1020 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment; | ||
| 1021 | const sect = &seg.sections.items[id]; | ||
| 1022 | sect.size = self.rustc_section_size; | ||
| 1023 | } | ||
| 996 | if (self.bss_section_index) |idx| { | 1024 | if (self.bss_section_index) |idx| { |
| 997 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment; | 1025 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment; |
| 998 | const sect = &seg.sections.items[idx]; | 1026 | const sect = &seg.sections.items[idx]; |
| ... | @@ -1195,7 +1223,7 @@ fn parseObject(self: *MachO, path: []const u8) !bool { | ... | @@ -1195,7 +1223,7 @@ fn parseObject(self: *MachO, path: []const u8) !bool { |
| 1195 | return true; | 1223 | return true; |
| 1196 | } | 1224 | } |
| 1197 | 1225 | ||
| 1198 | fn parseArchive(self: *MachO, path: []const u8) !bool { | 1226 | fn parseArchive(self: *MachO, path: []const u8, force_load: bool) !bool { |
| 1199 | const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) { | 1227 | const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) { |
| 1200 | error.FileNotFound => return false, | 1228 | error.FileNotFound => return false, |
| 1201 | else => |e| return e, | 1229 | else => |e| return e, |
| ... | @@ -1218,7 +1246,23 @@ fn parseArchive(self: *MachO, path: []const u8) !bool { | ... | @@ -1218,7 +1246,23 @@ fn parseArchive(self: *MachO, path: []const u8) !bool { |
| 1218 | else => |e| return e, | 1246 | else => |e| return e, |
| 1219 | }; | 1247 | }; |
| 1220 | 1248 | ||
| 1221 | try self.archives.append(self.base.allocator, archive); | 1249 | if (force_load) { |
| 1250 | defer archive.deinit(self.base.allocator); | ||
| 1251 | // Get all offsets from the ToC | ||
| 1252 | var offsets = std.AutoArrayHashMap(u32, void).init(self.base.allocator); | ||
| 1253 | defer offsets.deinit(); | ||
| 1254 | for (archive.toc.values()) |offs| { | ||
| 1255 | for (offs.items) |off| { | ||
| 1256 | _ = try offsets.getOrPut(off); | ||
| 1257 | } | ||
| 1258 | } | ||
| 1259 | for (offsets.keys()) |off| { | ||
| 1260 | const object = try self.objects.addOne(self.base.allocator); | ||
| 1261 | object.* = try archive.parseObject(self.base.allocator, self.base.options.target, off); | ||
| 1262 | } | ||
| 1263 | } else { | ||
| 1264 | try self.archives.append(self.base.allocator, archive); | ||
| 1265 | } | ||
| 1222 | 1266 | ||
| 1223 | return true; | 1267 | return true; |
| 1224 | } | 1268 | } |
| ... | @@ -1303,7 +1347,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const | ... | @@ -1303,7 +1347,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const |
| 1303 | log.debug("parsing input file path '{s}'", .{full_path}); | 1347 | log.debug("parsing input file path '{s}'", .{full_path}); |
| 1304 | 1348 | ||
| 1305 | if (try self.parseObject(full_path)) continue; | 1349 | if (try self.parseObject(full_path)) continue; |
| 1306 | if (try self.parseArchive(full_path)) continue; | 1350 | if (try self.parseArchive(full_path, false)) continue; |
| 1307 | if (try self.parseDylib(full_path, .{ | 1351 | if (try self.parseDylib(full_path, .{ |
| 1308 | .syslibroot = syslibroot, | 1352 | .syslibroot = syslibroot, |
| 1309 | .dependent_libs = dependent_libs, | 1353 | .dependent_libs = dependent_libs, |
| ... | @@ -1313,6 +1357,21 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const | ... | @@ -1313,6 +1357,21 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const |
| 1313 | } | 1357 | } |
| 1314 | } | 1358 | } |
| 1315 | 1359 | ||
| 1360 | fn parseAndForceLoadStaticArchives(self: *MachO, files: []const []const u8) !void { | ||
| 1361 | for (files) |file_name| { | ||
| 1362 | const full_path = full_path: { | ||
| 1363 | var buffer: [fs.MAX_PATH_BYTES]u8 = undefined; | ||
| 1364 | const path = try fs.realpath(file_name, &buffer); | ||
| 1365 | break :full_path try self.base.allocator.dupe(u8, path); | ||
| 1366 | }; | ||
| 1367 | defer self.base.allocator.free(full_path); | ||
| 1368 | log.debug("parsing and force loading static archive '{s}'", .{full_path}); | ||
| 1369 | |||
| 1370 | if (try self.parseArchive(full_path, true)) continue; | ||
| 1371 | log.warn("unknown filetype: expected static archive: '{s}'", .{file_name}); | ||
| 1372 | } | ||
| 1373 | } | ||
| 1374 | |||
| 1316 | fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, dependent_libs: anytype) !void { | 1375 | fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, dependent_libs: anytype) !void { |
| 1317 | for (libs) |lib| { | 1376 | for (libs) |lib| { |
| 1318 | log.debug("parsing lib path '{s}'", .{lib}); | 1377 | log.debug("parsing lib path '{s}'", .{lib}); |
| ... | @@ -1320,7 +1379,7 @@ fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, de | ... | @@ -1320,7 +1379,7 @@ fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, de |
| 1320 | .syslibroot = syslibroot, | 1379 | .syslibroot = syslibroot, |
| 1321 | .dependent_libs = dependent_libs, | 1380 | .dependent_libs = dependent_libs, |
| 1322 | })) continue; | 1381 | })) continue; |
| 1323 | if (try self.parseArchive(lib)) continue; | 1382 | if (try self.parseArchive(lib, false)) continue; |
| 1324 | 1383 | ||
| 1325 | log.warn("unknown filetype for a library: '{s}'", .{lib}); | 1384 | log.warn("unknown filetype for a library: '{s}'", .{lib}); |
| 1326 | } | 1385 | } |
| ... | @@ -1886,6 +1945,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1886,6 +1945,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1886 | .seg = self.data_segment_cmd_index.?, | 1945 | .seg = self.data_segment_cmd_index.?, |
| 1887 | .sect = self.objc_data_section_index.?, | 1946 | .sect = self.objc_data_section_index.?, |
| 1888 | }; | 1947 | }; |
| 1948 | } else if (mem.eql(u8, sectname, ".rustc")) { | ||
| 1949 | if (self.rustc_section_index == null) { | ||
| 1950 | self.rustc_section_index = try self.initSection( | ||
| 1951 | self.data_segment_cmd_index.?, | ||
| 1952 | ".rustc", | ||
| 1953 | sect.size, | ||
| 1954 | sect.@"align", | ||
| 1955 | .{}, | ||
| 1956 | ); | ||
| 1957 | // We need to preserve the section size for rustc to properly | ||
| 1958 | // decompress the metadata. | ||
| 1959 | self.rustc_section_size = sect.size; | ||
| 1960 | } | ||
| 1961 | |||
| 1962 | break :blk .{ | ||
| 1963 | .seg = self.data_segment_cmd_index.?, | ||
| 1964 | .sect = self.rustc_section_index.?, | ||
| 1965 | }; | ||
| 1889 | } else { | 1966 | } else { |
| 1890 | if (self.data_section_index == null) { | 1967 | if (self.data_section_index == null) { |
| 1891 | self.data_section_index = try self.initSection( | 1968 | self.data_section_index = try self.initSection( |
| ... | @@ -5212,6 +5289,7 @@ fn sortSections(self: *MachO) !void { | ... | @@ -5212,6 +5289,7 @@ fn sortSections(self: *MachO) !void { |
| 5212 | 5289 | ||
| 5213 | // __DATA segment | 5290 | // __DATA segment |
| 5214 | const indices = &[_]*?u16{ | 5291 | const indices = &[_]*?u16{ |
| 5292 | &self.rustc_section_index, | ||
| 5215 | &self.la_symbol_ptr_section_index, | 5293 | &self.la_symbol_ptr_section_index, |
| 5216 | &self.objc_const_section_index, | 5294 | &self.objc_const_section_index, |
| 5217 | &self.objc_selrefs_section_index, | 5295 | &self.objc_selrefs_section_index, |
src/link/MachO/Atom.zig+2-1| ... | @@ -419,6 +419,7 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC | ... | @@ -419,6 +419,7 @@ pub fn parseRelocs(self: *Atom, relocs: []macho.relocation_info, context: RelocC |
| 419 | .X86_64_RELOC_BRANCH => { | 419 | .X86_64_RELOC_BRANCH => { |
| 420 | // TODO rewrite relocation | 420 | // TODO rewrite relocation |
| 421 | try addStub(target, context); | 421 | try addStub(target, context); |
| 422 | addend = mem.readIntLittle(i32, self.code.items[offset..][0..4]); | ||
| 422 | }, | 423 | }, |
| 423 | .X86_64_RELOC_GOT, .X86_64_RELOC_GOT_LOAD => { | 424 | .X86_64_RELOC_GOT, .X86_64_RELOC_GOT_LOAD => { |
| 424 | // TODO rewrite relocation | 425 | // TODO rewrite relocation |
| ... | @@ -1003,7 +1004,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { | ... | @@ -1003,7 +1004,7 @@ pub fn resolveRelocs(self: *Atom, macho_file: *MachO) !void { |
| 1003 | .X86_64_RELOC_BRANCH => { | 1004 | .X86_64_RELOC_BRANCH => { |
| 1004 | const displacement = try math.cast( | 1005 | const displacement = try math.cast( |
| 1005 | i32, | 1006 | i32, |
| 1006 | @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4, | 1007 | @intCast(i64, target_addr) - @intCast(i64, source_addr) - 4 + rel.addend, |
| 1007 | ); | 1008 | ); |
| 1008 | mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement)); | 1009 | mem.writeIntLittle(u32, self.code.items[rel.offset..][0..4], @bitCast(u32, displacement)); |
| 1009 | }, | 1010 | }, |
src/link/MachO/Object.zig+1-1| ... | @@ -409,7 +409,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! | ... | @@ -409,7 +409,7 @@ pub fn parseIntoAtoms(self: *Object, allocator: Allocator, macho_file: *MachO) ! |
| 409 | } else blk: { | 409 | } else blk: { |
| 410 | var iundefsym: usize = sorted_all_nlists.items.len; | 410 | var iundefsym: usize = sorted_all_nlists.items.len; |
| 411 | while (iundefsym > 0) : (iundefsym -= 1) { | 411 | while (iundefsym > 0) : (iundefsym -= 1) { |
| 412 | const nlist = sorted_all_nlists.items[iundefsym]; | 412 | const nlist = sorted_all_nlists.items[iundefsym - 1]; |
| 413 | if (nlist.nlist.sect()) break; | 413 | if (nlist.nlist.sect()) break; |
| 414 | } | 414 | } |
| 415 | break :blk iundefsym; | 415 | break :blk iundefsym; |
src/link/Wasm.zig+9-3| ... | @@ -1128,7 +1128,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -1128,7 +1128,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1128 | 1128 | ||
| 1129 | comptime assert(Compilation.link_hash_implementation_version == 1); | 1129 | comptime assert(Compilation.link_hash_implementation_version == 1); |
| 1130 | 1130 | ||
| 1131 | try man.addListOfFiles(self.base.options.objects); | 1131 | for (self.base.options.objects) |obj| { |
| 1132 | _ = try man.addFile(obj.path, null); | ||
| 1133 | man.hash.add(obj.must_link); | ||
| 1134 | } | ||
| 1132 | for (comp.c_object_table.keys()) |key| { | 1135 | for (comp.c_object_table.keys()) |key| { |
| 1133 | _ = try man.addFile(key.status.success.object_path, null); | 1136 | _ = try man.addFile(key.status.success.object_path, null); |
| 1134 | } | 1137 | } |
| ... | @@ -1181,7 +1184,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -1181,7 +1184,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1181 | // build-obj. See also the corresponding TODO in linkAsArchive. | 1184 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1182 | const the_object_path = blk: { | 1185 | const the_object_path = blk: { |
| 1183 | if (self.base.options.objects.len != 0) | 1186 | if (self.base.options.objects.len != 0) |
| 1184 | break :blk self.base.options.objects[0]; | 1187 | break :blk self.base.options.objects[0].path; |
| 1185 | 1188 | ||
| 1186 | if (comp.c_object_table.count() != 0) | 1189 | if (comp.c_object_table.count() != 0) |
| 1187 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 1190 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -1346,7 +1349,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -1346,7 +1349,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1346 | } | 1349 | } |
| 1347 | 1350 | ||
| 1348 | // Positional arguments to the linker such as object files. | 1351 | // Positional arguments to the linker such as object files. |
| 1349 | try argv.appendSlice(self.base.options.objects); | 1352 | try argv.ensureUnusedCapacity(self.base.options.objects.len); |
| 1353 | for (self.base.options.objects) |obj| { | ||
| 1354 | argv.appendAssumeCapacity(obj.path); | ||
| 1355 | } | ||
| 1350 | 1356 | ||
| 1351 | for (comp.c_object_table.keys()) |key| { | 1357 | for (comp.c_object_table.keys()) |key| { |
| 1352 | try argv.append(key.status.success.object_path); | 1358 | try argv.append(key.status.success.object_path); |
src/main.zig+14-5| ... | @@ -705,7 +705,7 @@ fn buildOutputType( | ... | @@ -705,7 +705,7 @@ fn buildOutputType( |
| 705 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); | 705 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); |
| 706 | defer c_source_files.deinit(); | 706 | defer c_source_files.deinit(); |
| 707 | 707 | ||
| 708 | var link_objects = std.ArrayList([]const u8).init(gpa); | 708 | var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 709 | defer link_objects.deinit(); | 709 | defer link_objects.deinit(); |
| 710 | 710 | ||
| 711 | var framework_dirs = std.ArrayList([]const u8).init(gpa); | 711 | var framework_dirs = std.ArrayList([]const u8).init(gpa); |
| ... | @@ -1238,7 +1238,7 @@ fn buildOutputType( | ... | @@ -1238,7 +1238,7 @@ fn buildOutputType( |
| 1238 | } | 1238 | } |
| 1239 | } else switch (Compilation.classifyFileExt(arg)) { | 1239 | } else switch (Compilation.classifyFileExt(arg)) { |
| 1240 | .object, .static_library, .shared_library => { | 1240 | .object, .static_library, .shared_library => { |
| 1241 | try link_objects.append(arg); | 1241 | try link_objects.append(.{ .path = arg }); |
| 1242 | }, | 1242 | }, |
| 1243 | .assembly, .c, .cpp, .h, .ll, .bc, .m, .mm => { | 1243 | .assembly, .c, .cpp, .h, .ll, .bc, .m, .mm => { |
| 1244 | try c_source_files.append(.{ | 1244 | try c_source_files.append(.{ |
| ... | @@ -1309,7 +1309,7 @@ fn buildOutputType( | ... | @@ -1309,7 +1309,7 @@ fn buildOutputType( |
| 1309 | switch (file_ext) { | 1309 | switch (file_ext) { |
| 1310 | .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm => try c_source_files.append(.{ .src_path = it.only_arg }), | 1310 | .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm => try c_source_files.append(.{ .src_path = it.only_arg }), |
| 1311 | .unknown, .shared_library, .object, .static_library => { | 1311 | .unknown, .shared_library, .object, .static_library => { |
| 1312 | try link_objects.append(it.only_arg); | 1312 | try link_objects.append(.{ .path = it.only_arg }); |
| 1313 | }, | 1313 | }, |
| 1314 | .zig => { | 1314 | .zig => { |
| 1315 | if (root_src_file) |other| { | 1315 | if (root_src_file) |other| { |
| ... | @@ -1748,6 +1748,15 @@ fn buildOutputType( | ... | @@ -1748,6 +1748,15 @@ fn buildOutputType( |
| 1748 | fatal("expected linker arg after '{s}'", .{arg}); | 1748 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1749 | } | 1749 | } |
| 1750 | install_name = linker_args.items[i]; | 1750 | install_name = linker_args.items[i]; |
| 1751 | } else if (mem.eql(u8, arg, "-force_load")) { | ||
| 1752 | i += 1; | ||
| 1753 | if (i >= linker_args.items.len) { | ||
| 1754 | fatal("expected linker arg after '{s}'", .{arg}); | ||
| 1755 | } | ||
| 1756 | try link_objects.append(.{ | ||
| 1757 | .path = linker_args.items[i], | ||
| 1758 | .must_link = true, | ||
| 1759 | }); | ||
| 1751 | } else { | 1760 | } else { |
| 1752 | warn("unsupported linker arg: {s}", .{arg}); | 1761 | warn("unsupported linker arg: {s}", .{arg}); |
| 1753 | } | 1762 | } |
| ... | @@ -1842,7 +1851,7 @@ fn buildOutputType( | ... | @@ -1842,7 +1851,7 @@ fn buildOutputType( |
| 1842 | const basename = fs.path.basename(c_source_files.items[0].src_path); | 1851 | const basename = fs.path.basename(c_source_files.items[0].src_path); |
| 1843 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; | 1852 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; |
| 1844 | } else if (link_objects.items.len >= 1) { | 1853 | } else if (link_objects.items.len >= 1) { |
| 1845 | const basename = fs.path.basename(link_objects.items[0]); | 1854 | const basename = fs.path.basename(link_objects.items[0].path); |
| 1846 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; | 1855 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; |
| 1847 | } else if (emit_bin == .yes) { | 1856 | } else if (emit_bin == .yes) { |
| 1848 | const basename = fs.path.basename(emit_bin.yes); | 1857 | const basename = fs.path.basename(emit_bin.yes); |
| ... | @@ -2045,7 +2054,7 @@ fn buildOutputType( | ... | @@ -2045,7 +2054,7 @@ fn buildOutputType( |
| 2045 | test_path.items, @errorName(e), | 2054 | test_path.items, @errorName(e), |
| 2046 | }), | 2055 | }), |
| 2047 | }; | 2056 | }; |
| 2048 | try link_objects.append(try arena.dupe(u8, test_path.items)); | 2057 | try link_objects.append(.{ .path = try arena.dupe(u8, test_path.items) }); |
| 2049 | break; | 2058 | break; |
| 2050 | } else { | 2059 | } else { |
| 2051 | var search_paths = std.ArrayList(u8).init(arena); | 2060 | var search_paths = std.ArrayList(u8).init(arena); |