| author | |
| committer | |
| log | 148b963a606c2a7b71dced22d1d5b42cce4d9c04 |
| tree | b13ecc2a299ece729ad92b4e4a35185494a2896d |
| parent | b713ce0249e68edd5db6fea79df4fffadbdc7ef9 |
zld: a couple of fixes which result in better rustc support9 files changed, 146 insertions(+), 31 deletions(-)
src/Compilation.zig+8-3| ... | @@ -636,6 +636,11 @@ pub const ClangPreprocessorMode = enum { | ... | @@ -636,6 +636,11 @@ pub const ClangPreprocessorMode = enum { |
| 636 | 636 | ||
| 637 | pub const SystemLib = link.SystemLib; | 637 | pub const SystemLib = link.SystemLib; |
| 638 | 638 | ||
| 639 | pub const LinkObject = struct { | ||
| 640 | path: []const u8, | ||
| 641 | must_link: bool = false, | ||
| 642 | }; | ||
| 643 | |||
| 639 | pub const InitOptions = struct { | 644 | pub const InitOptions = struct { |
| 640 | zig_lib_directory: Directory, | 645 | zig_lib_directory: Directory, |
| 641 | local_cache_directory: Directory, | 646 | local_cache_directory: Directory, |
| ... | @@ -679,7 +684,7 @@ pub const InitOptions = struct { | ... | @@ -679,7 +684,7 @@ pub const InitOptions = struct { |
| 679 | lib_dirs: []const []const u8 = &[0][]const u8{}, | 684 | lib_dirs: []const []const u8 = &[0][]const u8{}, |
| 680 | rpath_list: []const []const u8 = &[0][]const u8{}, | 685 | rpath_list: []const []const u8 = &[0][]const u8{}, |
| 681 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, | 686 | c_source_files: []const CSourceFile = &[0]CSourceFile{}, |
| 682 | link_objects: []const []const u8 = &[0][]const u8{}, | 687 | link_objects: []LinkObject = &[0]LinkObject{}, |
| 683 | framework_dirs: []const []const u8 = &[0][]const u8{}, | 688 | framework_dirs: []const []const u8 = &[0][]const u8{}, |
| 684 | frameworks: []const []const u8 = &[0][]const u8{}, | 689 | frameworks: []const []const u8 = &[0][]const u8{}, |
| 685 | system_lib_names: []const []const u8 = &.{}, | 690 | system_lib_names: []const []const u8 = &.{}, |
| ... | @@ -1027,7 +1032,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1027,7 +1032,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1027 | if (options.system_lib_names.len != 0) | 1032 | if (options.system_lib_names.len != 0) |
| 1028 | break :x true; | 1033 | break :x true; |
| 1029 | for (options.link_objects) |obj| { | 1034 | for (options.link_objects) |obj| { |
| 1030 | switch (classifyFileExt(obj)) { | 1035 | switch (classifyFileExt(obj.path)) { |
| 1031 | .shared_library => break :x true, | 1036 | .shared_library => break :x true, |
| 1032 | else => continue, | 1037 | else => continue, |
| 1033 | } | 1038 | } |
| ... | @@ -1389,7 +1394,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { | ... | @@ -1389,7 +1394,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation { |
| 1389 | if (options.c_source_files.len >= 1) { | 1394 | if (options.c_source_files.len >= 1) { |
| 1390 | hash.addBytes(options.c_source_files[0].src_path); | 1395 | hash.addBytes(options.c_source_files[0].src_path); |
| 1391 | } else if (options.link_objects.len >= 1) { | 1396 | } else if (options.link_objects.len >= 1) { |
| 1392 | hash.addBytes(options.link_objects[0]); | 1397 | hash.addBytes(options.link_objects[0].path); |
| 1393 | } | 1398 | } |
| 1394 | 1399 | ||
| 1395 | const digest = hash.final(); | 1400 | const digest = hash.final(); |
src/link.zig+7-4| ... | @@ -137,7 +137,7 @@ pub const Options = struct { | ... | @@ -137,7 +137,7 @@ pub const Options = struct { |
| 137 | soname: ?[]const u8, | 137 | soname: ?[]const u8, |
| 138 | llvm_cpu_features: ?[*:0]const u8, | 138 | llvm_cpu_features: ?[*:0]const u8, |
| 139 | 139 | ||
| 140 | objects: []const []const u8, | 140 | objects: []Compilation.LinkObject, |
| 141 | framework_dirs: []const []const u8, | 141 | framework_dirs: []const []const u8, |
| 142 | frameworks: []const []const u8, | 142 | frameworks: []const []const u8, |
| 143 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), | 143 | system_libs: std.StringArrayHashMapUnmanaged(SystemLib), |
| ... | @@ -683,7 +683,10 @@ pub const File = struct { | ... | @@ -683,7 +683,10 @@ pub const File = struct { |
| 683 | // We are about to obtain this lock, so here we give other processes a chance first. | 683 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 684 | base.releaseLock(); | 684 | base.releaseLock(); |
| 685 | 685 | ||
| 686 | try man.addListOfFiles(base.options.objects); | 686 | for (base.options.objects) |obj| { |
| 687 | _ = try man.addFile(obj.path, null); | ||
| 688 | man.hash.add(obj.must_link); | ||
| 689 | } | ||
| 687 | for (comp.c_object_table.keys()) |key| { | 690 | for (comp.c_object_table.keys()) |key| { |
| 688 | _ = try man.addFile(key.status.success.object_path, null); | 691 | _ = try man.addFile(key.status.success.object_path, null); |
| 689 | } | 692 | } |
| ... | @@ -720,8 +723,8 @@ pub const File = struct { | ... | @@ -720,8 +723,8 @@ pub const File = struct { |
| 720 | var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files); | 723 | var object_files = try std.ArrayList([*:0]const u8).initCapacity(base.allocator, num_object_files); |
| 721 | defer object_files.deinit(); | 724 | defer object_files.deinit(); |
| 722 | 725 | ||
| 723 | for (base.options.objects) |obj_path| { | 726 | for (base.options.objects) |obj| { |
| 724 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj_path)); | 727 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, obj.path)); |
| 725 | } | 728 | } |
| 726 | for (comp.c_object_table.keys()) |key| { | 729 | for (comp.c_object_table.keys()) |key| { |
| 727 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.object_path)); | 730 | object_files.appendAssumeCapacity(try arena.dupeZ(u8, key.status.success.object_path)); |
src/link/Coff.zig+9-3| ... | @@ -920,7 +920,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -920,7 +920,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 920 | man = comp.cache_parent.obtain(); | 920 | man = comp.cache_parent.obtain(); |
| 921 | self.base.releaseLock(); | 921 | self.base.releaseLock(); |
| 922 | 922 | ||
| 923 | try man.addListOfFiles(self.base.options.objects); | 923 | for (self.base.options.objects) |obj| { |
| 924 | _ = try man.addFile(obj.path, null); | ||
| 925 | man.hash.add(obj.must_link); | ||
| 926 | } | ||
| 924 | for (comp.c_object_table.keys()) |key| { | 927 | for (comp.c_object_table.keys()) |key| { |
| 925 | _ = try man.addFile(key.status.success.object_path, null); | 928 | _ = try man.addFile(key.status.success.object_path, null); |
| 926 | } | 929 | } |
| ... | @@ -984,7 +987,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -984,7 +987,7 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 984 | // build-obj. See also the corresponding TODO in linkAsArchive. | 987 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 985 | const the_object_path = blk: { | 988 | const the_object_path = blk: { |
| 986 | if (self.base.options.objects.len != 0) | 989 | if (self.base.options.objects.len != 0) |
| 987 | break :blk self.base.options.objects[0]; | 990 | break :blk self.base.options.objects[0].path; |
| 988 | 991 | ||
| 989 | if (comp.c_object_table.count() != 0) | 992 | if (comp.c_object_table.count() != 0) |
| 990 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 993 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -1093,7 +1096,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { | ... | @@ -1093,7 +1096,10 @@ fn linkWithLLD(self: *Coff, comp: *Compilation) !void { |
| 1093 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); | 1096 | try argv.append(try allocPrint(arena, "-LIBPATH:{s}", .{lib_dir})); |
| 1094 | } | 1097 | } |
| 1095 | 1098 | ||
| 1096 | try argv.appendSlice(self.base.options.objects); | 1099 | try argv.ensureUnusedCapacity(self.base.options.objects.len); |
| 1100 | for (self.base.options.objects) |obj| { | ||
| 1101 | argv.appendAssumeCapacity(obj.path); | ||
| 1102 | } | ||
| 1097 | 1103 | ||
| 1098 | for (comp.c_object_table.keys()) |key| { | 1104 | for (comp.c_object_table.keys()) |key| { |
| 1099 | try argv.append(key.status.success.object_path); | 1105 | try argv.append(key.status.success.object_path); |
src/link/Elf.zig+9-3| ... | @@ -1307,7 +1307,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1307,7 +1307,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1307 | 1307 | ||
| 1308 | try man.addOptionalFile(self.base.options.linker_script); | 1308 | try man.addOptionalFile(self.base.options.linker_script); |
| 1309 | try man.addOptionalFile(self.base.options.version_script); | 1309 | try man.addOptionalFile(self.base.options.version_script); |
| 1310 | try man.addListOfFiles(self.base.options.objects); | 1310 | for (self.base.options.objects) |obj| { |
| 1311 | _ = try man.addFile(obj.path, null); | ||
| 1312 | man.hash.add(obj.must_link); | ||
| 1313 | } | ||
| 1311 | for (comp.c_object_table.keys()) |key| { | 1314 | for (comp.c_object_table.keys()) |key| { |
| 1312 | _ = try man.addFile(key.status.success.object_path, null); | 1315 | _ = try man.addFile(key.status.success.object_path, null); |
| 1313 | } | 1316 | } |
| ... | @@ -1392,7 +1395,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1392,7 +1395,7 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1392 | // build-obj. See also the corresponding TODO in linkAsArchive. | 1395 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1393 | const the_object_path = blk: { | 1396 | const the_object_path = blk: { |
| 1394 | if (self.base.options.objects.len != 0) | 1397 | if (self.base.options.objects.len != 0) |
| 1395 | break :blk self.base.options.objects[0]; | 1398 | break :blk self.base.options.objects[0].path; |
| 1396 | 1399 | ||
| 1397 | if (comp.c_object_table.count() != 0) | 1400 | if (comp.c_object_table.count() != 0) |
| 1398 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 1401 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -1607,7 +1610,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { | ... | @@ -1607,7 +1610,10 @@ fn linkWithLLD(self: *Elf, comp: *Compilation) !void { |
| 1607 | } | 1610 | } |
| 1608 | 1611 | ||
| 1609 | // Positional arguments to the linker such as object files. | 1612 | // Positional arguments to the linker such as object files. |
| 1610 | try argv.appendSlice(self.base.options.objects); | 1613 | try argv.ensureUnusedCapacity(self.base.options.objects.len); |
| 1614 | for (self.base.options.objects) |obj| { | ||
| 1615 | argv.appendAssumeCapacity(obj.path); | ||
| 1616 | } | ||
| 1611 | 1617 | ||
| 1612 | for (comp.c_object_table.keys()) |key| { | 1618 | for (comp.c_object_table.keys()) |key| { |
| 1613 | try argv.append(key.status.success.object_path); | 1619 | try argv.append(key.status.success.object_path); |
src/link/MachO.zig+87-8| ... | @@ -140,6 +140,9 @@ objc_selrefs_section_index: ?u16 = null, | ... | @@ -140,6 +140,9 @@ objc_selrefs_section_index: ?u16 = null, |
| 140 | objc_classrefs_section_index: ?u16 = null, | 140 | objc_classrefs_section_index: ?u16 = null, |
| 141 | objc_data_section_index: ?u16 = null, | 141 | objc_data_section_index: ?u16 = null, |
| 142 | 142 | ||
| 143 | rustc_section_index: ?u16 = null, | ||
| 144 | rustc_section_size: u64 = 0, | ||
| 145 | |||
| 143 | bss_file_offset: u32 = 0, | 146 | bss_file_offset: u32 = 0, |
| 144 | tlv_bss_file_offset: u32 = 0, | 147 | tlv_bss_file_offset: u32 = 0, |
| 145 | 148 | ||
| ... | @@ -466,7 +469,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -466,7 +469,10 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 466 | // We are about to obtain this lock, so here we give other processes a chance first. | 469 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 467 | self.base.releaseLock(); | 470 | self.base.releaseLock(); |
| 468 | 471 | ||
| 469 | try man.addListOfFiles(self.base.options.objects); | 472 | for (self.base.options.objects) |obj| { |
| 473 | _ = try man.addFile(obj.path, null); | ||
| 474 | man.hash.add(obj.must_link); | ||
| 475 | } | ||
| 470 | for (comp.c_object_table.keys()) |key| { | 476 | for (comp.c_object_table.keys()) |key| { |
| 471 | _ = try man.addFile(key.status.success.object_path, null); | 477 | _ = try man.addFile(key.status.success.object_path, null); |
| 472 | } | 478 | } |
| ... | @@ -539,8 +545,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -539,8 +545,9 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 539 | // here. TODO: think carefully about how we can avoid this redundant operation when doing | 545 | // here. TODO: think carefully about how we can avoid this redundant operation when doing |
| 540 | // build-obj. See also the corresponding TODO in linkAsArchive. | 546 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 541 | const the_object_path = blk: { | 547 | const the_object_path = blk: { |
| 542 | if (self.base.options.objects.len != 0) | 548 | if (self.base.options.objects.len != 0) { |
| 543 | break :blk self.base.options.objects[0]; | 549 | break :blk self.base.options.objects[0].path; |
| 550 | } | ||
| 544 | 551 | ||
| 545 | if (comp.c_object_table.count() != 0) | 552 | if (comp.c_object_table.count() != 0) |
| 546 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 553 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -649,8 +656,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -649,8 +656,19 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 649 | 656 | ||
| 650 | // Positional arguments to the linker such as object files and static archives. | 657 | // Positional arguments to the linker such as object files and static archives. |
| 651 | var positionals = std.ArrayList([]const u8).init(arena); | 658 | var positionals = std.ArrayList([]const u8).init(arena); |
| 659 | try positionals.ensureUnusedCapacity(self.base.options.objects.len); | ||
| 652 | 660 | ||
| 653 | try positionals.appendSlice(self.base.options.objects); | 661 | var must_link_archives = std.StringArrayHashMap(void).init(arena); |
| 662 | try must_link_archives.ensureUnusedCapacity(self.base.options.objects.len); | ||
| 663 | |||
| 664 | for (self.base.options.objects) |obj| { | ||
| 665 | if (must_link_archives.contains(obj.path)) continue; | ||
| 666 | if (obj.must_link) { | ||
| 667 | _ = must_link_archives.getOrPutAssumeCapacity(obj.path); | ||
| 668 | } else { | ||
| 669 | _ = positionals.appendAssumeCapacity(obj.path); | ||
| 670 | } | ||
| 671 | } | ||
| 654 | 672 | ||
| 655 | for (comp.c_object_table.keys()) |key| { | 673 | for (comp.c_object_table.keys()) |key| { |
| 656 | try positionals.append(key.status.success.object_path); | 674 | try positionals.append(key.status.success.object_path); |
| ... | @@ -857,12 +875,17 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -857,12 +875,17 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 857 | try argv.append("dynamic_lookup"); | 875 | try argv.append("dynamic_lookup"); |
| 858 | } | 876 | } |
| 859 | 877 | ||
| 878 | for (must_link_archives.keys()) |lib| { | ||
| 879 | try argv.append(try std.fmt.allocPrint(arena, "-force_load {s}", .{lib})); | ||
| 880 | } | ||
| 881 | |||
| 860 | Compilation.dump_argv(argv.items); | 882 | Compilation.dump_argv(argv.items); |
| 861 | } | 883 | } |
| 862 | 884 | ||
| 863 | var dependent_libs = std.fifo.LinearFifo(Dylib.Id, .Dynamic).init(self.base.allocator); | 885 | var dependent_libs = std.fifo.LinearFifo(Dylib.Id, .Dynamic).init(self.base.allocator); |
| 864 | defer dependent_libs.deinit(); | 886 | defer dependent_libs.deinit(); |
| 865 | try self.parseInputFiles(positionals.items, self.base.options.sysroot, &dependent_libs); | 887 | try self.parseInputFiles(positionals.items, self.base.options.sysroot, &dependent_libs); |
| 888 | try self.parseAndForceLoadStaticArchives(must_link_archives.keys()); | ||
| 866 | try self.parseLibs(libs.items, self.base.options.sysroot, &dependent_libs); | 889 | try self.parseLibs(libs.items, self.base.options.sysroot, &dependent_libs); |
| 867 | try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); | 890 | try self.parseDependentLibs(self.base.options.sysroot, &dependent_libs); |
| 868 | } | 891 | } |
| ... | @@ -953,6 +976,12 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { | ... | @@ -953,6 +976,12 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void { |
| 953 | try self.writeAtoms(); | 976 | try self.writeAtoms(); |
| 954 | } | 977 | } |
| 955 | 978 | ||
| 979 | if (self.rustc_section_index) |id| { | ||
| 980 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment; | ||
| 981 | const sect = &seg.sections.items[id]; | ||
| 982 | sect.size = self.rustc_section_size; | ||
| 983 | } | ||
| 984 | |||
| 956 | try self.setEntryPoint(); | 985 | try self.setEntryPoint(); |
| 957 | try self.updateSectionOrdinals(); | 986 | try self.updateSectionOrdinals(); |
| 958 | try self.writeLinkeditSegment(); | 987 | try self.writeLinkeditSegment(); |
| ... | @@ -1142,7 +1171,7 @@ fn parseObject(self: *MachO, path: []const u8) !bool { | ... | @@ -1142,7 +1171,7 @@ fn parseObject(self: *MachO, path: []const u8) !bool { |
| 1142 | return true; | 1171 | return true; |
| 1143 | } | 1172 | } |
| 1144 | 1173 | ||
| 1145 | fn parseArchive(self: *MachO, path: []const u8) !bool { | 1174 | fn parseArchive(self: *MachO, path: []const u8, force_load: bool) !bool { |
| 1146 | const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) { | 1175 | const file = fs.cwd().openFile(path, .{}) catch |err| switch (err) { |
| 1147 | error.FileNotFound => return false, | 1176 | error.FileNotFound => return false, |
| 1148 | else => |e| return e, | 1177 | else => |e| return e, |
| ... | @@ -1165,7 +1194,23 @@ fn parseArchive(self: *MachO, path: []const u8) !bool { | ... | @@ -1165,7 +1194,23 @@ fn parseArchive(self: *MachO, path: []const u8) !bool { |
| 1165 | else => |e| return e, | 1194 | else => |e| return e, |
| 1166 | }; | 1195 | }; |
| 1167 | 1196 | ||
| 1168 | try self.archives.append(self.base.allocator, archive); | 1197 | if (force_load) { |
| 1198 | defer archive.deinit(self.base.allocator); | ||
| 1199 | // Get all offsets from the ToC | ||
| 1200 | var offsets = std.AutoArrayHashMap(u32, void).init(self.base.allocator); | ||
| 1201 | defer offsets.deinit(); | ||
| 1202 | for (archive.toc.values()) |offs| { | ||
| 1203 | for (offs.items) |off| { | ||
| 1204 | _ = try offsets.getOrPut(off); | ||
| 1205 | } | ||
| 1206 | } | ||
| 1207 | for (offsets.keys()) |off| { | ||
| 1208 | const object = try self.objects.addOne(self.base.allocator); | ||
| 1209 | object.* = try archive.parseObject(self.base.allocator, self.base.options.target, off); | ||
| 1210 | } | ||
| 1211 | } else { | ||
| 1212 | try self.archives.append(self.base.allocator, archive); | ||
| 1213 | } | ||
| 1169 | 1214 | ||
| 1170 | return true; | 1215 | return true; |
| 1171 | } | 1216 | } |
| ... | @@ -1250,7 +1295,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const | ... | @@ -1250,7 +1295,7 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const |
| 1250 | log.debug("parsing input file path '{s}'", .{full_path}); | 1295 | log.debug("parsing input file path '{s}'", .{full_path}); |
| 1251 | 1296 | ||
| 1252 | if (try self.parseObject(full_path)) continue; | 1297 | if (try self.parseObject(full_path)) continue; |
| 1253 | if (try self.parseArchive(full_path)) continue; | 1298 | if (try self.parseArchive(full_path, false)) continue; |
| 1254 | if (try self.parseDylib(full_path, .{ | 1299 | if (try self.parseDylib(full_path, .{ |
| 1255 | .syslibroot = syslibroot, | 1300 | .syslibroot = syslibroot, |
| 1256 | .dependent_libs = dependent_libs, | 1301 | .dependent_libs = dependent_libs, |
| ... | @@ -1260,6 +1305,21 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const | ... | @@ -1260,6 +1305,21 @@ fn parseInputFiles(self: *MachO, files: []const []const u8, syslibroot: ?[]const |
| 1260 | } | 1305 | } |
| 1261 | } | 1306 | } |
| 1262 | 1307 | ||
| 1308 | fn parseAndForceLoadStaticArchives(self: *MachO, files: []const []const u8) !void { | ||
| 1309 | for (files) |file_name| { | ||
| 1310 | const full_path = full_path: { | ||
| 1311 | var buffer: [fs.MAX_PATH_BYTES]u8 = undefined; | ||
| 1312 | const path = try fs.realpath(file_name, &buffer); | ||
| 1313 | break :full_path try self.base.allocator.dupe(u8, path); | ||
| 1314 | }; | ||
| 1315 | defer self.base.allocator.free(full_path); | ||
| 1316 | log.debug("parsing and force loading static archive '{s}'", .{full_path}); | ||
| 1317 | |||
| 1318 | if (try self.parseArchive(full_path, true)) continue; | ||
| 1319 | log.warn("unknown filetype: expected static archive: '{s}'", .{file_name}); | ||
| 1320 | } | ||
| 1321 | } | ||
| 1322 | |||
| 1263 | fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, dependent_libs: anytype) !void { | 1323 | fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, dependent_libs: anytype) !void { |
| 1264 | for (libs) |lib| { | 1324 | for (libs) |lib| { |
| 1265 | log.debug("parsing lib path '{s}'", .{lib}); | 1325 | log.debug("parsing lib path '{s}'", .{lib}); |
| ... | @@ -1267,7 +1327,7 @@ fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, de | ... | @@ -1267,7 +1327,7 @@ fn parseLibs(self: *MachO, libs: []const []const u8, syslibroot: ?[]const u8, de |
| 1267 | .syslibroot = syslibroot, | 1327 | .syslibroot = syslibroot, |
| 1268 | .dependent_libs = dependent_libs, | 1328 | .dependent_libs = dependent_libs, |
| 1269 | })) continue; | 1329 | })) continue; |
| 1270 | if (try self.parseArchive(lib)) continue; | 1330 | if (try self.parseArchive(lib, false)) continue; |
| 1271 | 1331 | ||
| 1272 | log.warn("unknown filetype for a library: '{s}'", .{lib}); | 1332 | log.warn("unknown filetype for a library: '{s}'", .{lib}); |
| 1273 | } | 1333 | } |
| ... | @@ -1833,6 +1893,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1833,6 +1893,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1833 | .seg = self.data_segment_cmd_index.?, | 1893 | .seg = self.data_segment_cmd_index.?, |
| 1834 | .sect = self.objc_data_section_index.?, | 1894 | .sect = self.objc_data_section_index.?, |
| 1835 | }; | 1895 | }; |
| 1896 | } else if (mem.eql(u8, sectname, ".rustc")) { | ||
| 1897 | if (self.rustc_section_index == null) { | ||
| 1898 | self.rustc_section_index = try self.initSection( | ||
| 1899 | self.data_segment_cmd_index.?, | ||
| 1900 | ".rustc", | ||
| 1901 | sect.size, | ||
| 1902 | sect.@"align", | ||
| 1903 | .{}, | ||
| 1904 | ); | ||
| 1905 | // We need to preserve the section size for rustc to properly | ||
| 1906 | // decompress the metadata. | ||
| 1907 | self.rustc_section_size = sect.size; | ||
| 1908 | } | ||
| 1909 | |||
| 1910 | break :blk .{ | ||
| 1911 | .seg = self.data_segment_cmd_index.?, | ||
| 1912 | .sect = self.rustc_section_index.?, | ||
| 1913 | }; | ||
| 1836 | } else { | 1914 | } else { |
| 1837 | if (self.data_section_index == null) { | 1915 | if (self.data_section_index == null) { |
| 1838 | self.data_section_index = try self.initSection( | 1916 | self.data_section_index = try self.initSection( |
| ... | @@ -5003,6 +5081,7 @@ fn sortSections(self: *MachO) !void { | ... | @@ -5003,6 +5081,7 @@ fn sortSections(self: *MachO) !void { |
| 5003 | 5081 | ||
| 5004 | // __DATA segment | 5082 | // __DATA segment |
| 5005 | const indices = &[_]*?u16{ | 5083 | const indices = &[_]*?u16{ |
| 5084 | &self.rustc_section_index, | ||
| 5006 | &self.la_symbol_ptr_section_index, | 5085 | &self.la_symbol_ptr_section_index, |
| 5007 | &self.objc_const_section_index, | 5086 | &self.objc_const_section_index, |
| 5008 | &self.objc_selrefs_section_index, | 5087 | &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| ... | @@ -1012,7 +1012,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -1012,7 +1012,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1012 | // We are about to obtain this lock, so here we give other processes a chance first. | 1012 | // We are about to obtain this lock, so here we give other processes a chance first. |
| 1013 | self.base.releaseLock(); | 1013 | self.base.releaseLock(); |
| 1014 | 1014 | ||
| 1015 | try man.addListOfFiles(self.base.options.objects); | 1015 | for (self.base.options.objects) |obj| { |
| 1016 | _ = try man.addFile(obj.path, null); | ||
| 1017 | man.hash.add(obj.must_link); | ||
| 1018 | } | ||
| 1016 | for (comp.c_object_table.keys()) |key| { | 1019 | for (comp.c_object_table.keys()) |key| { |
| 1017 | _ = try man.addFile(key.status.success.object_path, null); | 1020 | _ = try man.addFile(key.status.success.object_path, null); |
| 1018 | } | 1021 | } |
| ... | @@ -1065,7 +1068,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -1065,7 +1068,7 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1065 | // build-obj. See also the corresponding TODO in linkAsArchive. | 1068 | // build-obj. See also the corresponding TODO in linkAsArchive. |
| 1066 | const the_object_path = blk: { | 1069 | const the_object_path = blk: { |
| 1067 | if (self.base.options.objects.len != 0) | 1070 | if (self.base.options.objects.len != 0) |
| 1068 | break :blk self.base.options.objects[0]; | 1071 | break :blk self.base.options.objects[0].path; |
| 1069 | 1072 | ||
| 1070 | if (comp.c_object_table.count() != 0) | 1073 | if (comp.c_object_table.count() != 0) |
| 1071 | break :blk comp.c_object_table.keys()[0].status.success.object_path; | 1074 | break :blk comp.c_object_table.keys()[0].status.success.object_path; |
| ... | @@ -1225,7 +1228,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { | ... | @@ -1225,7 +1228,10 @@ fn linkWithLLD(self: *Wasm, comp: *Compilation) !void { |
| 1225 | } | 1228 | } |
| 1226 | 1229 | ||
| 1227 | // Positional arguments to the linker such as object files. | 1230 | // Positional arguments to the linker such as object files. |
| 1228 | try argv.appendSlice(self.base.options.objects); | 1231 | try argv.ensureUnusedCapacity(self.base.options.objects.len); |
| 1232 | for (self.base.options.objects) |obj| { | ||
| 1233 | argv.appendAssumeCapacity(obj.path); | ||
| 1234 | } | ||
| 1229 | 1235 | ||
| 1230 | for (comp.c_object_table.keys()) |key| { | 1236 | for (comp.c_object_table.keys()) |key| { |
| 1231 | try argv.append(key.status.success.object_path); | 1237 | try argv.append(key.status.success.object_path); |
src/main.zig+14-5| ... | @@ -703,7 +703,7 @@ fn buildOutputType( | ... | @@ -703,7 +703,7 @@ fn buildOutputType( |
| 703 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); | 703 | var c_source_files = std.ArrayList(Compilation.CSourceFile).init(gpa); |
| 704 | defer c_source_files.deinit(); | 704 | defer c_source_files.deinit(); |
| 705 | 705 | ||
| 706 | var link_objects = std.ArrayList([]const u8).init(gpa); | 706 | var link_objects = std.ArrayList(Compilation.LinkObject).init(gpa); |
| 707 | defer link_objects.deinit(); | 707 | defer link_objects.deinit(); |
| 708 | 708 | ||
| 709 | var framework_dirs = std.ArrayList([]const u8).init(gpa); | 709 | var framework_dirs = std.ArrayList([]const u8).init(gpa); |
| ... | @@ -1236,7 +1236,7 @@ fn buildOutputType( | ... | @@ -1236,7 +1236,7 @@ fn buildOutputType( |
| 1236 | } | 1236 | } |
| 1237 | } else switch (Compilation.classifyFileExt(arg)) { | 1237 | } else switch (Compilation.classifyFileExt(arg)) { |
| 1238 | .object, .static_library, .shared_library => { | 1238 | .object, .static_library, .shared_library => { |
| 1239 | try link_objects.append(arg); | 1239 | try link_objects.append(.{ .path = arg }); |
| 1240 | }, | 1240 | }, |
| 1241 | .assembly, .c, .cpp, .h, .ll, .bc, .m, .mm => { | 1241 | .assembly, .c, .cpp, .h, .ll, .bc, .m, .mm => { |
| 1242 | try c_source_files.append(.{ | 1242 | try c_source_files.append(.{ |
| ... | @@ -1307,7 +1307,7 @@ fn buildOutputType( | ... | @@ -1307,7 +1307,7 @@ fn buildOutputType( |
| 1307 | switch (file_ext) { | 1307 | switch (file_ext) { |
| 1308 | .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm => try c_source_files.append(.{ .src_path = it.only_arg }), | 1308 | .assembly, .c, .cpp, .ll, .bc, .h, .m, .mm => try c_source_files.append(.{ .src_path = it.only_arg }), |
| 1309 | .unknown, .shared_library, .object, .static_library => { | 1309 | .unknown, .shared_library, .object, .static_library => { |
| 1310 | try link_objects.append(it.only_arg); | 1310 | try link_objects.append(.{ .path = it.only_arg }); |
| 1311 | }, | 1311 | }, |
| 1312 | .zig => { | 1312 | .zig => { |
| 1313 | if (root_src_file) |other| { | 1313 | if (root_src_file) |other| { |
| ... | @@ -1751,6 +1751,15 @@ fn buildOutputType( | ... | @@ -1751,6 +1751,15 @@ fn buildOutputType( |
| 1751 | fatal("expected linker arg after '{s}'", .{arg}); | 1751 | fatal("expected linker arg after '{s}'", .{arg}); |
| 1752 | } | 1752 | } |
| 1753 | install_name = linker_args.items[i]; | 1753 | install_name = linker_args.items[i]; |
| 1754 | } else if (mem.eql(u8, arg, "-force_load")) { | ||
| 1755 | i += 1; | ||
| 1756 | if (i >= linker_args.items.len) { | ||
| 1757 | fatal("expected linker arg after '{s}'", .{arg}); | ||
| 1758 | } | ||
| 1759 | try link_objects.append(.{ | ||
| 1760 | .path = linker_args.items[i], | ||
| 1761 | .must_link = true, | ||
| 1762 | }); | ||
| 1754 | } else { | 1763 | } else { |
| 1755 | warn("unsupported linker arg: {s}", .{arg}); | 1764 | warn("unsupported linker arg: {s}", .{arg}); |
| 1756 | } | 1765 | } |
| ... | @@ -1845,7 +1854,7 @@ fn buildOutputType( | ... | @@ -1845,7 +1854,7 @@ fn buildOutputType( |
| 1845 | const basename = fs.path.basename(c_source_files.items[0].src_path); | 1854 | const basename = fs.path.basename(c_source_files.items[0].src_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 (link_objects.items.len >= 1) { | 1856 | } else if (link_objects.items.len >= 1) { |
| 1848 | const basename = fs.path.basename(link_objects.items[0]); | 1857 | const basename = fs.path.basename(link_objects.items[0].path); |
| 1849 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; | 1858 | break :blk basename[0 .. basename.len - fs.path.extension(basename).len]; |
| 1850 | } else if (emit_bin == .yes) { | 1859 | } else if (emit_bin == .yes) { |
| 1851 | const basename = fs.path.basename(emit_bin.yes); | 1860 | const basename = fs.path.basename(emit_bin.yes); |
| ... | @@ -2048,7 +2057,7 @@ fn buildOutputType( | ... | @@ -2048,7 +2057,7 @@ fn buildOutputType( |
| 2048 | test_path.items, @errorName(e), | 2057 | test_path.items, @errorName(e), |
| 2049 | }), | 2058 | }), |
| 2050 | }; | 2059 | }; |
| 2051 | try link_objects.append(try arena.dupe(u8, test_path.items)); | 2060 | try link_objects.append(.{ .path = try arena.dupe(u8, test_path.items) }); |
| 2052 | break; | 2061 | break; |
| 2053 | } else { | 2062 | } else { |
| 2054 | var search_paths = std.ArrayList(u8).init(arena); | 2063 | var search_paths = std.ArrayList(u8).init(arena); |