authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-27 10:45:56+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-08-27 10:45:56+02:00
log705cd64080a5555425de7d13a9fbc6c19af65bde
treedee7b93baa24d557fa840cc3f87acccf26f17e62
parent8bd0687713855a41578605a3e1a6c9686a702bfe

macho: preactively add zerofill sections in correct order

The required order on macOS nowadays is: * __data * __thread_vars * __thread_data * __thread_bss * __bss

1 files changed, 105 insertions(+), 1 deletions(-)

src/link/MachO.zig+105-1
......@@ -780,7 +780,7 @@ pub fn flush(self: *MachO, comp: *Compilation) !void {
780780 }
781781
782782 try self.parseTextBlocks();
783 try self.sortSections();
783 // try self.sortSections();
784784 try self.allocateTextSegment();
785785 try self.allocateDataConstSegment();
786786 try self.allocateDataSegment();
......@@ -4163,6 +4163,110 @@ pub fn populateMissingMetadata(self: *MachO) !void {
41634163 self.load_commands_dirty = true;
41644164 }
41654165
4166 if (self.tlv_section_index == null) {
4167 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4168 self.tlv_section_index = @intCast(u16, data_segment.sections.items.len);
4169
4170 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4171 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
4172 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
4173
4174 log.debug("found __thread_vars section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4175
4176 try data_segment.addSection(self.base.allocator, "__thread_vars", .{
4177 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
4178 .size = needed_size,
4179 .offset = @intCast(u32, off),
4180 .@"align" = 3, // 2^3 = @sizeOf(u64)
4181 .flags = macho.S_THREAD_LOCAL_VARIABLES,
4182 });
4183 const match = MatchingSection{
4184 .seg = self.data_segment_cmd_index.?,
4185 .sect = self.tlv_section_index.?,
4186 };
4187 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
4188 try self.block_free_lists.putNoClobber(self.base.allocator, match, .{});
4189 self.load_commands_dirty = true;
4190 }
4191
4192 if (self.tlv_data_section_index == null) {
4193 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4194 self.tlv_data_section_index = @intCast(u16, data_segment.sections.items.len);
4195
4196 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4197 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
4198 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
4199
4200 log.debug("found __thread_data section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4201
4202 try data_segment.addSection(self.base.allocator, "__thread_data", .{
4203 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
4204 .size = needed_size,
4205 .offset = @intCast(u32, off),
4206 .@"align" = 3, // 2^3 = @sizeOf(u64)
4207 .flags = macho.S_THREAD_LOCAL_REGULAR,
4208 });
4209 const match = MatchingSection{
4210 .seg = self.data_segment_cmd_index.?,
4211 .sect = self.tlv_data_section_index.?,
4212 };
4213 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
4214 try self.block_free_lists.putNoClobber(self.base.allocator, match, .{});
4215 self.load_commands_dirty = true;
4216 }
4217
4218 if (self.tlv_bss_section_index == null) {
4219 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4220 self.tlv_bss_section_index = @intCast(u16, data_segment.sections.items.len);
4221
4222 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4223 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
4224 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
4225
4226 log.debug("found __thread_bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4227
4228 try data_segment.addSection(self.base.allocator, "__thread_bss", .{
4229 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
4230 .size = needed_size,
4231 .offset = @intCast(u32, off),
4232 .@"align" = 3, // 2^3 = @sizeOf(u64)
4233 .flags = macho.S_THREAD_LOCAL_ZEROFILL,
4234 });
4235 const match = MatchingSection{
4236 .seg = self.data_segment_cmd_index.?,
4237 .sect = self.tlv_bss_section_index.?,
4238 };
4239 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
4240 try self.block_free_lists.putNoClobber(self.base.allocator, match, .{});
4241 self.load_commands_dirty = true;
4242 }
4243
4244 if (self.bss_section_index == null) {
4245 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
4246 self.bss_section_index = @intCast(u16, data_segment.sections.items.len);
4247
4248 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
4249 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
4250 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
4251
4252 log.debug("found __bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
4253
4254 try data_segment.addSection(self.base.allocator, "__bss", .{
4255 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
4256 .size = 0,
4257 .offset = @intCast(u32, off),
4258 .@"align" = 3, // 2^3 = @sizeOf(u64)
4259 .flags = macho.S_ZEROFILL,
4260 });
4261 const match = MatchingSection{
4262 .seg = self.data_segment_cmd_index.?,
4263 .sect = self.bss_section_index.?,
4264 };
4265 _ = try self.section_ordinals.getOrPut(self.base.allocator, match);
4266 try self.block_free_lists.putNoClobber(self.base.allocator, match, .{});
4267 self.load_commands_dirty = true;
4268 }
4269
41664270 if (self.linkedit_segment_cmd_index == null) {
41674271 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
41684272 const address_and_offset = self.nextSegmentAddressAndOffset();