| author | |
| committer | |
| log | 90e326827062fc7899d02516cdaffa7da8366077 |
| tree | 8709238e09db8a89bad1e2414c7e833861f10bb7 |
| parent | 421d3e8d2822e979c1a2d5e7aaa5859499bc2146 |
This way, tracking segment-to-section mapping becomes a lot easier
since it's effectively just start index plus number of sections
defined within the segment. If a section becomes empty however
care needs to be taken to remove the header upon committing to the
final binary.3 files changed, 35 insertions(+), 13 deletions(-)
src/link/MachO.zig+18-5| ... | ... | @@ -4888,13 +4888,26 @@ fn getSegmentAllocBase(self: MachO, indices: []const ?u8) struct { vmaddr: u64, |
| 4888 | 4888 | |
| 4889 | 4889 | fn writeSegmentHeaders(self: *MachO, ncmds: *u32, writer: anytype) !void { |
| 4890 | 4890 | for (self.segments.items) |seg, i| { |
| 4891 | if (seg.nsects == 0 and | |
| 4892 | (mem.eql(u8, seg.segName(), "__DATA_CONST") or | |
| 4893 | mem.eql(u8, seg.segName(), "__DATA"))) continue; | |
| 4894 | try writer.writeStruct(seg); | |
| 4895 | ||
| 4896 | 4891 | const indexes = self.getSectionIndexes(@intCast(u8, i)); |
| 4892 | var out_seg = seg; | |
| 4893 | out_seg.cmdsize = @sizeOf(macho.segment_command_64); | |
| 4894 | out_seg.nsects = 0; | |
| 4895 | ||
| 4896 | // Update section headers count; any section with size of 0 is excluded | |
| 4897 | // since it doesn't have any data in the final binary file. | |
| 4898 | for (self.sections.items(.header)[indexes.start..indexes.end]) |header| { | |
| 4899 | if (header.size == 0) continue; | |
| 4900 | out_seg.cmdsize += @sizeOf(macho.section_64); | |
| 4901 | out_seg.nsects += 1; | |
| 4902 | } | |
| 4903 | ||
| 4904 | if (out_seg.nsects == 0 and | |
| 4905 | (mem.eql(u8, out_seg.segName(), "__DATA_CONST") or | |
| 4906 | mem.eql(u8, out_seg.segName(), "__DATA"))) continue; | |
| 4907 | ||
| 4908 | try writer.writeStruct(out_seg); | |
| 4897 | 4909 | for (self.sections.items(.header)[indexes.start..indexes.end]) |header| { |
| 4910 | if (header.size == 0) continue; | |
| 4898 | 4911 | try writer.writeStruct(header); |
| 4899 | 4912 | } |
| 4900 | 4913 |
src/link/MachO/DebugSymbols.zig+17-5| ... | ... | @@ -367,16 +367,28 @@ fn writeSegmentHeaders(self: *DebugSymbols, ncmds: *u32, writer: anytype) !void |
| 367 | 367 | // Write segment/section headers from the binary file first. |
| 368 | 368 | const end = self.base.linkedit_segment_cmd_index.?; |
| 369 | 369 | for (self.base.segments.items[0..end]) |seg, i| { |
| 370 | if (seg.nsects == 0 and | |
| 371 | (mem.eql(u8, seg.segName(), "__DATA_CONST") or | |
| 372 | mem.eql(u8, seg.segName(), "__DATA"))) continue; | |
| 370 | const indexes = self.base.getSectionIndexes(@intCast(u8, i)); | |
| 373 | 371 | var out_seg = seg; |
| 374 | 372 | out_seg.fileoff = 0; |
| 375 | 373 | out_seg.filesize = 0; |
| 376 | try writer.writeStruct(out_seg); | |
| 374 | out_seg.cmdsize = @sizeOf(macho.segment_command_64); | |
| 375 | out_seg.nsects = 0; | |
| 377 | 376 | |
| 378 | const indexes = self.base.getSectionIndexes(@intCast(u8, i)); | |
| 377 | // Update section headers count; any section with size of 0 is excluded | |
| 378 | // since it doesn't have any data in the final binary file. | |
| 379 | for (self.base.sections.items(.header)[indexes.start..indexes.end]) |header| { | |
| 380 | if (header.size == 0) continue; | |
| 381 | out_seg.cmdsize += @sizeOf(macho.section_64); | |
| 382 | out_seg.nsects += 1; | |
| 383 | } | |
| 384 | ||
| 385 | if (out_seg.nsects == 0 and | |
| 386 | (mem.eql(u8, out_seg.segName(), "__DATA_CONST") or | |
| 387 | mem.eql(u8, out_seg.segName(), "__DATA"))) continue; | |
| 388 | ||
| 389 | try writer.writeStruct(out_seg); | |
| 379 | 390 | for (self.base.sections.items(.header)[indexes.start..indexes.end]) |header| { |
| 391 | if (header.size == 0) continue; | |
| 380 | 392 | var out_header = header; |
| 381 | 393 | out_header.offset = 0; |
| 382 | 394 | try writer.writeStruct(out_header); |
src/link/MachO/dead_strip.zig-3| ... | ... | @@ -43,9 +43,6 @@ fn removeAtomFromSection(atom: *Atom, match: u8, macho_file: *MachO) void { |
| 43 | 43 | // The section will be GCed in the next step. |
| 44 | 44 | section.last_atom = null; |
| 45 | 45 | section.header.size = 0; |
| 46 | const segment = &macho_file.segments.items[section.segment_index]; | |
| 47 | segment.cmdsize -= @sizeOf(macho.section_64); | |
| 48 | segment.nsects -= 1; | |
| 49 | 46 | } |
| 50 | 47 | } |
| 51 | 48 |