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