authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-11 14:18:09+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-09-11 14:18:09+02:00
log7aa6064638322286b5aed940c17da1c8f8fad81a
treeda828045e36b329136c0c182bfffef65b29992b8
parent054fe96bcd84cc4f0536696636531b192224df48

macho: insert rpaths upon parsing

Also, insert empty data-in-code lc in populateMissingMetadata fn.

1 files changed, 30 insertions(+), 36 deletions(-)

src/link/MachO.zig+30-36
...@@ -688,7 +688,22 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {...@@ -688,7 +688,22 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {
688 var rpath_table = std.StringArrayHashMap(void).init(arena);688 var rpath_table = std.StringArrayHashMap(void).init(arena);
689 for (self.base.options.rpath_list) |rpath| {689 for (self.base.options.rpath_list) |rpath| {
690 if (rpath_table.contains(rpath)) continue;690 if (rpath_table.contains(rpath)) continue;
691 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
692 u64,
693 @sizeOf(macho.rpath_command) + rpath.len + 1,
694 @sizeOf(u64),
695 ));
696 var rpath_cmd = commands.emptyGenericCommandWithData(macho.rpath_command{
697 .cmd = macho.LC_RPATH,
698 .cmdsize = cmdsize,
699 .path = @sizeOf(macho.rpath_command),
700 });
701 rpath_cmd.data = try self.base.allocator.alloc(u8, cmdsize - rpath_cmd.inner.path);
702 mem.set(u8, rpath_cmd.data, 0);
703 mem.copy(u8, rpath_cmd.data, rpath);
704 try self.load_commands.append(self.base.allocator, .{ .Rpath = rpath_cmd });
691 try rpath_table.putNoClobber(rpath, {});705 try rpath_table.putNoClobber(rpath, {});
706 self.load_commands_dirty = true;
692 }707 }
693708
694 if (self.base.options.verbose_link) {709 if (self.base.options.verbose_link) {
...@@ -763,9 +778,7 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {...@@ -763,9 +778,7 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {
763 }778 }
764779
765 try self.resolveSymbols();780 try self.resolveSymbols();
766 try self.addRpathLCs(rpath_table.keys());
767 try self.addLoadDylibLCs();781 try self.addLoadDylibLCs();
768 try self.addDataInCodeLC();
769 try self.addCodeSignatureLC();782 try self.addCodeSignatureLC();
770783
771 try self.parseObjectsIntoAtoms();784 try self.parseObjectsIntoAtoms();
...@@ -2720,20 +2733,6 @@ fn parseObjectsIntoAtoms(self: *MachO) !void {...@@ -2720,20 +2733,6 @@ fn parseObjectsIntoAtoms(self: *MachO) !void {
2720 }2733 }
2721}2734}
27222735
2723fn addDataInCodeLC(self: *MachO) !void {
2724 if (self.data_in_code_cmd_index != null) return;
2725 self.data_in_code_cmd_index = @intCast(u16, self.load_commands.items.len);
2726 try self.load_commands.append(self.base.allocator, .{
2727 .LinkeditData = .{
2728 .cmd = macho.LC_DATA_IN_CODE,
2729 .cmdsize = @sizeOf(macho.linkedit_data_command),
2730 .dataoff = 0,
2731 .datasize = 0,
2732 },
2733 });
2734 self.load_commands_dirty = true;
2735}
2736
2737fn addCodeSignatureLC(self: *MachO) !void {2736fn addCodeSignatureLC(self: *MachO) !void {
2738 if (self.code_signature_cmd_index != null or !self.requires_adhoc_codesig) return;2737 if (self.code_signature_cmd_index != null or !self.requires_adhoc_codesig) return;
2739 self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);2738 self.code_signature_cmd_index = @intCast(u16, self.load_commands.items.len);
...@@ -2748,26 +2747,6 @@ fn addCodeSignatureLC(self: *MachO) !void {...@@ -2748,26 +2747,6 @@ fn addCodeSignatureLC(self: *MachO) !void {
2748 self.load_commands_dirty = true;2747 self.load_commands_dirty = true;
2749}2748}
27502749
2751fn addRpathLCs(self: *MachO, rpaths: []const []const u8) !void {
2752 for (rpaths) |rpath| {
2753 const cmdsize = @intCast(u32, mem.alignForwardGeneric(
2754 u64,
2755 @sizeOf(macho.rpath_command) + rpath.len + 1,
2756 @sizeOf(u64),
2757 ));
2758 var rpath_cmd = commands.emptyGenericCommandWithData(macho.rpath_command{
2759 .cmd = macho.LC_RPATH,
2760 .cmdsize = cmdsize,
2761 .path = @sizeOf(macho.rpath_command),
2762 });
2763 rpath_cmd.data = try self.base.allocator.alloc(u8, cmdsize - rpath_cmd.inner.path);
2764 mem.set(u8, rpath_cmd.data, 0);
2765 mem.copy(u8, rpath_cmd.data, rpath);
2766 try self.load_commands.append(self.base.allocator, .{ .Rpath = rpath_cmd });
2767 self.load_commands_dirty = true;
2768 }
2769}
2770
2771fn addLoadDylibLCs(self: *MachO) !void {2750fn addLoadDylibLCs(self: *MachO) !void {
2772 for (self.referenced_dylibs.keys()) |id| {2751 for (self.referenced_dylibs.keys()) |id| {
2773 const dylib = self.dylibs.items[id];2752 const dylib = self.dylibs.items[id];
...@@ -3270,6 +3249,8 @@ pub fn updateDeclExports(...@@ -3270,6 +3249,8 @@ pub fn updateDeclExports(
3270 decl: *Module.Decl,3249 decl: *Module.Decl,
3271 exports: []const *Module.Export,3250 exports: []const *Module.Export,
3272) !void {3251) !void {
3252 // TODO If we are exporting with global linkage, check for already defined globals and flag
3253 // symbol duplicate/collision!
3273 if (build_options.skip_non_native and builtin.object_format != .macho) {3254 if (build_options.skip_non_native and builtin.object_format != .macho) {
3274 @panic("Attempted to compile for object format that was disabled by build configuration");3255 @panic("Attempted to compile for object format that was disabled by build configuration");
3275 }3256 }
...@@ -3866,6 +3847,19 @@ pub fn populateMissingMetadata(self: *MachO) !void {...@@ -3866,6 +3847,19 @@ pub fn populateMissingMetadata(self: *MachO) !void {
3866 try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd });3847 try self.load_commands.append(self.base.allocator, .{ .Uuid = uuid_cmd });
3867 self.load_commands_dirty = true;3848 self.load_commands_dirty = true;
3868 }3849 }
3850
3851 if (self.data_in_code_cmd_index == null) {
3852 self.data_in_code_cmd_index = @intCast(u16, self.load_commands.items.len);
3853 try self.load_commands.append(self.base.allocator, .{
3854 .LinkeditData = .{
3855 .cmd = macho.LC_DATA_IN_CODE,
3856 .cmdsize = @sizeOf(macho.linkedit_data_command),
3857 .dataoff = 0,
3858 .datasize = 0,
3859 },
3860 });
3861 self.load_commands_dirty = true;
3862 }
3869}3863}
38703864
3871const AllocateSectionOpts = struct {3865const AllocateSectionOpts = struct {