authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-12 16:14:27+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-01-13 20:02:11+01:00
logf9f792ab701a8aa3e3fb7b7b47b2b7c50b1bc9a2
tree41fb0d36c5add8c70fa6a818b0575e9db8526dba
parentc5ee73f65b4c77fe08aa44b8611bf084ae700f24

zld: fix num nlist calc when there's no dynsymtab

Handle `__DATA,.rustc` section containing `rustc` metadata - this is required to get crates like `serde_derive` link properly. Note to self: this special section has to be copied __verbatim__ from the relocatable object file - this includes preserving its size even though unpadded according the section's required alignment.

2 files changed, 28 insertions(+), 1 deletions(-)

src/link/MachO.zig+27
...@@ -141,6 +141,9 @@ objc_selrefs_section_index: ?u16 = null,...@@ -141,6 +141,9 @@ objc_selrefs_section_index: ?u16 = null,
141objc_classrefs_section_index: ?u16 = null,141objc_classrefs_section_index: ?u16 = null,
142objc_data_section_index: ?u16 = null,142objc_data_section_index: ?u16 = null,
143143
144rustc_section_index: ?u16 = null,
145rustc_section_size: u64 = 0,
146
144bss_file_offset: u32 = 0,147bss_file_offset: u32 = 0,
145tlv_bss_file_offset: u32 = 0,148tlv_bss_file_offset: u32 = 0,
146149
...@@ -993,6 +996,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {...@@ -993,6 +996,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
993 try self.writeAtoms();996 try self.writeAtoms();
994 }997 }
995998
999 if (self.rustc_section_index) |id| {
1000 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
1001 const sect = &seg.sections.items[id];
1002 sect.size = self.rustc_section_size;
1003 }
996 if (self.bss_section_index) |idx| {1004 if (self.bss_section_index) |idx| {
997 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;1005 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
998 const sect = &seg.sections.items[idx];1006 const sect = &seg.sections.items[idx];
...@@ -1886,6 +1894,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio...@@ -1886,6 +1894,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
1886 .seg = self.data_segment_cmd_index.?,1894 .seg = self.data_segment_cmd_index.?,
1887 .sect = self.objc_data_section_index.?,1895 .sect = self.objc_data_section_index.?,
1888 };1896 };
1897 } else if (mem.eql(u8, sectname, ".rustc")) {
1898 if (self.rustc_section_index == null) {
1899 self.rustc_section_index = try self.initSection(
1900 self.data_segment_cmd_index.?,
1901 ".rustc",
1902 sect.size,
1903 sect.@"align",
1904 .{},
1905 );
1906 // We need to preserve the section size for rustc to properly
1907 // decompress the metadata.
1908 self.rustc_section_size = sect.size;
1909 }
1910
1911 break :blk .{
1912 .seg = self.data_segment_cmd_index.?,
1913 .sect = self.rustc_section_index.?,
1914 };
1889 } else {1915 } else {
1890 if (self.data_section_index == null) {1916 if (self.data_section_index == null) {
1891 self.data_section_index = try self.initSection(1917 self.data_section_index = try self.initSection(
...@@ -5212,6 +5238,7 @@ fn sortSections(self: *MachO) !void {...@@ -5212,6 +5238,7 @@ fn sortSections(self: *MachO) !void {
52125238
5213 // __DATA segment5239 // __DATA segment
5214 const indices = &[_]*?u16{5240 const indices = &[_]*?u16{
5241 &self.rustc_section_index,
5215 &self.la_symbol_ptr_section_index,5242 &self.la_symbol_ptr_section_index,
5216 &self.objc_const_section_index,5243 &self.objc_const_section_index,
5217 &self.objc_selrefs_section_index,5244 &self.objc_selrefs_section_index,
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;