| ... | ... | @@ -64,6 +64,7 @@ got_section_index: ?u16 = null, |
| 64 | 64 | mod_init_func_section_index: ?u16 = null, |
| 65 | 65 | mod_term_func_section_index: ?u16 = null, |
| 66 | 66 | data_const_section_index: ?u16 = null, |
| 67 | common_section_index: ?u16 = null, |
| 67 | 68 | |
| 68 | 69 | // __DATA segment sections |
| 69 | 70 | tlv_section_index: ?u16 = null, |
| ... | ... | @@ -483,23 +484,43 @@ fn updateMetadata(self: *Zld) !void { |
| 483 | 484 | }, |
| 484 | 485 | macho.S_ZEROFILL => { |
| 485 | 486 | if (!mem.eql(u8, segname, "__DATA")) continue; |
| 486 | | if (self.bss_section_index != null) continue; |
| 487 | if (mem.eql(u8, sectname, "__common")) { |
| 488 | if (self.common_section_index != null) continue; |
| 487 | 489 | |
| 488 | | self.bss_section_index = @intCast(u16, data_seg.sections.items.len); |
| 489 | | try data_seg.addSection(self.allocator, .{ |
| 490 | | .sectname = makeStaticString("__bss"), |
| 491 | | .segname = makeStaticString("__DATA"), |
| 492 | | .addr = 0, |
| 493 | | .size = 0, |
| 494 | | .offset = 0, |
| 495 | | .@"align" = 0, |
| 496 | | .reloff = 0, |
| 497 | | .nreloc = 0, |
| 498 | | .flags = macho.S_ZEROFILL, |
| 499 | | .reserved1 = 0, |
| 500 | | .reserved2 = 0, |
| 501 | | .reserved3 = 0, |
| 502 | | }); |
| 490 | self.common_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 491 | try data_const_seg.addSection(self.allocator, .{ |
| 492 | .sectname = makeStaticString("__common"), |
| 493 | .segname = makeStaticString("__DATA_CONST"), |
| 494 | .addr = 0, |
| 495 | .size = 0, |
| 496 | .offset = 0, |
| 497 | .@"align" = 0, |
| 498 | .reloff = 0, |
| 499 | .nreloc = 0, |
| 500 | .flags = macho.S_ZEROFILL, |
| 501 | .reserved1 = 0, |
| 502 | .reserved2 = 0, |
| 503 | .reserved3 = 0, |
| 504 | }); |
| 505 | } else { |
| 506 | if (self.bss_section_index != null) continue; |
| 507 | |
| 508 | self.bss_section_index = @intCast(u16, data_seg.sections.items.len); |
| 509 | try data_seg.addSection(self.allocator, .{ |
| 510 | .sectname = makeStaticString("__bss"), |
| 511 | .segname = makeStaticString("__DATA"), |
| 512 | .addr = 0, |
| 513 | .size = 0, |
| 514 | .offset = 0, |
| 515 | .@"align" = 0, |
| 516 | .reloff = 0, |
| 517 | .nreloc = 0, |
| 518 | .flags = macho.S_ZEROFILL, |
| 519 | .reserved1 = 0, |
| 520 | .reserved2 = 0, |
| 521 | .reserved3 = 0, |
| 522 | }); |
| 523 | } |
| 503 | 524 | }, |
| 504 | 525 | macho.S_THREAD_LOCAL_VARIABLES => { |
| 505 | 526 | if (!mem.eql(u8, segname, "__DATA")) continue; |
| ... | ... | @@ -586,7 +607,9 @@ fn updateMetadata(self: *Zld) !void { |
| 586 | 607 | |
| 587 | 608 | const segname = parseName(&source_sect.segname); |
| 588 | 609 | const sectname = parseName(&source_sect.sectname); |
| 610 | |
| 589 | 611 | log.debug("section '{s}/{s}' will be unmapped", .{ segname, sectname }); |
| 612 | |
| 590 | 613 | try self.unhandled_sections.putNoClobber(self.allocator, .{ |
| 591 | 614 | .object_id = object_id, |
| 592 | 615 | .source_sect_id = source_sect_id, |
| ... | ... | @@ -603,6 +626,7 @@ const MatchingSection = struct { |
| 603 | 626 | fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 604 | 627 | const segname = parseName(&section.segname); |
| 605 | 628 | const sectname = parseName(&section.sectname); |
| 629 | |
| 606 | 630 | const res: ?MatchingSection = blk: { |
| 607 | 631 | switch (section.flags) { |
| 608 | 632 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| ... | ... | @@ -630,6 +654,12 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 630 | 654 | }; |
| 631 | 655 | }, |
| 632 | 656 | macho.S_ZEROFILL => { |
| 657 | if (mem.eql(u8, sectname, "__common")) { |
| 658 | break :blk .{ |
| 659 | .seg = self.data_const_segment_cmd_index.?, |
| 660 | .sect = self.common_section_index.?, |
| 661 | }; |
| 662 | } |
| 633 | 663 | break :blk .{ |
| 634 | 664 | .seg = self.data_segment_cmd_index.?, |
| 635 | 665 | .sect = self.bss_section_index.?, |
| ... | ... | @@ -685,6 +715,7 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 685 | 715 | }, |
| 686 | 716 | } |
| 687 | 717 | }; |
| 718 | |
| 688 | 719 | return res; |
| 689 | 720 | } |
| 690 | 721 | |
| ... | ... | @@ -733,6 +764,7 @@ fn sortSections(self: *Zld) !void { |
| 733 | 764 | &self.mod_init_func_section_index, |
| 734 | 765 | &self.mod_term_func_section_index, |
| 735 | 766 | &self.data_const_section_index, |
| 767 | &self.common_section_index, |
| 736 | 768 | }; |
| 737 | 769 | for (indices) |maybe_index| { |
| 738 | 770 | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| ... | ... | @@ -1634,6 +1666,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1634 | 1666 | target_sect_off, |
| 1635 | 1667 | target_sect_off + sect.code.len, |
| 1636 | 1668 | }); |
| 1669 | |
| 1637 | 1670 | // Zero-out the space |
| 1638 | 1671 | var zeroes = try self.allocator.alloc(u8, sect.code.len); |
| 1639 | 1672 | defer self.allocator.free(zeroes); |
| ... | ... | @@ -2118,6 +2151,12 @@ fn populateMetadata(self: *Zld) !void { |
| 2118 | 2151 | } |
| 2119 | 2152 | |
| 2120 | 2153 | fn flush(self: *Zld) !void { |
| 2154 | if (self.common_section_index) |index| { |
| 2155 | const seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 2156 | const sect = &seg.sections.items[index]; |
| 2157 | sect.offset = 0; |
| 2158 | } |
| 2159 | |
| 2121 | 2160 | if (self.bss_section_index) |index| { |
| 2122 | 2161 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2123 | 2162 | const sect = &seg.sections.items[index]; |