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,
141141objc_classrefs_section_index: ?u16 = null,
142142objc_data_section_index: ?u16 = null,
143143
144rustc_section_index: ?u16 = null,
145rustc_section_size: u64 = 0,
146
144147bss_file_offset: u32 = 0,
145148tlv_bss_file_offset: u32 = 0,
146149
......@@ -993,6 +996,11 @@ pub fn flushModule(self: *MachO, comp: *Compilation) !void {
993996 try self.writeAtoms();
994997 }
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 }
9961004 if (self.bss_section_index) |idx| {
9971005 const seg = &self.load_commands.items[self.data_segment_cmd_index.?].segment;
9981006 const sect = &seg.sections.items[idx];
......@@ -1886,6 +1894,24 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio
18861894 .seg = self.data_segment_cmd_index.?,
18871895 .sect = self.objc_data_section_index.?,
18881896 };
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 };
18891915 } else {
18901916 if (self.data_section_index == null) {
18911917 self.data_section_index = try self.initSection(
......@@ -5212,6 +5238,7 @@ fn sortSections(self: *MachO) !void {
52125238
52135239 // __DATA segment
52145240 const indices = &[_]*?u16{
5241 &self.rustc_section_index,
52155242 &self.la_symbol_ptr_section_index,
52165243 &self.objc_const_section_index,
52175244 &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) !
409409 } else blk: {
410410 var iundefsym: usize = sorted_all_nlists.items.len;
411411 while (iundefsym > 0) : (iundefsym -= 1) {
412 const nlist = sorted_all_nlists.items[iundefsym];
412 const nlist = sorted_all_nlists.items[iundefsym - 1];
413413 if (nlist.nlist.sect()) break;
414414 }
415415 break :blk iundefsym;