| ... | ... | @@ -782,7 +782,6 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 782 | 782 | } |
| 783 | 783 | |
| 784 | 784 | try self.parseTextBlocks(); |
| 785 | | // try self.sortSections(); |
| 786 | 785 | try self.allocateTextSegment(); |
| 787 | 786 | try self.allocateDataConstSegment(); |
| 788 | 787 | try self.allocateDataSegment(); |
| ... | ... | @@ -1500,158 +1499,6 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1500 | 1499 | return res; |
| 1501 | 1500 | } |
| 1502 | 1501 | |
| 1503 | | fn sortSections(self: *MachO) !void { |
| 1504 | | var text_index_mapping = std.AutoHashMap(u16, u16).init(self.base.allocator); |
| 1505 | | defer text_index_mapping.deinit(); |
| 1506 | | var data_const_index_mapping = std.AutoHashMap(u16, u16).init(self.base.allocator); |
| 1507 | | defer data_const_index_mapping.deinit(); |
| 1508 | | var data_index_mapping = std.AutoHashMap(u16, u16).init(self.base.allocator); |
| 1509 | | defer data_index_mapping.deinit(); |
| 1510 | | |
| 1511 | | { |
| 1512 | | // __TEXT segment |
| 1513 | | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1514 | | var sections = seg.sections.toOwnedSlice(self.base.allocator); |
| 1515 | | defer self.base.allocator.free(sections); |
| 1516 | | try seg.sections.ensureCapacity(self.base.allocator, sections.len); |
| 1517 | | |
| 1518 | | const indices = &[_]*?u16{ |
| 1519 | | &self.text_section_index, |
| 1520 | | &self.stubs_section_index, |
| 1521 | | &self.stub_helper_section_index, |
| 1522 | | &self.gcc_except_tab_section_index, |
| 1523 | | &self.cstring_section_index, |
| 1524 | | &self.ustring_section_index, |
| 1525 | | &self.text_const_section_index, |
| 1526 | | &self.objc_methlist_section_index, |
| 1527 | | &self.objc_methname_section_index, |
| 1528 | | &self.objc_methtype_section_index, |
| 1529 | | &self.objc_classname_section_index, |
| 1530 | | &self.eh_frame_section_index, |
| 1531 | | }; |
| 1532 | | for (indices) |maybe_index| { |
| 1533 | | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| 1534 | | const idx = @intCast(u16, seg.sections.items.len); |
| 1535 | | seg.sections.appendAssumeCapacity(sections[index]); |
| 1536 | | try text_index_mapping.putNoClobber(index, idx); |
| 1537 | | break :blk idx; |
| 1538 | | } else continue; |
| 1539 | | maybe_index.* = new_index; |
| 1540 | | } |
| 1541 | | } |
| 1542 | | |
| 1543 | | { |
| 1544 | | // __DATA_CONST segment |
| 1545 | | const seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1546 | | var sections = seg.sections.toOwnedSlice(self.base.allocator); |
| 1547 | | defer self.base.allocator.free(sections); |
| 1548 | | try seg.sections.ensureCapacity(self.base.allocator, sections.len); |
| 1549 | | |
| 1550 | | const indices = &[_]*?u16{ |
| 1551 | | &self.got_section_index, |
| 1552 | | &self.mod_init_func_section_index, |
| 1553 | | &self.mod_term_func_section_index, |
| 1554 | | &self.data_const_section_index, |
| 1555 | | &self.objc_cfstring_section_index, |
| 1556 | | &self.objc_classlist_section_index, |
| 1557 | | &self.objc_imageinfo_section_index, |
| 1558 | | }; |
| 1559 | | for (indices) |maybe_index| { |
| 1560 | | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| 1561 | | const idx = @intCast(u16, seg.sections.items.len); |
| 1562 | | seg.sections.appendAssumeCapacity(sections[index]); |
| 1563 | | try data_const_index_mapping.putNoClobber(index, idx); |
| 1564 | | break :blk idx; |
| 1565 | | } else continue; |
| 1566 | | maybe_index.* = new_index; |
| 1567 | | } |
| 1568 | | } |
| 1569 | | |
| 1570 | | { |
| 1571 | | // __DATA segment |
| 1572 | | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1573 | | var sections = seg.sections.toOwnedSlice(self.base.allocator); |
| 1574 | | defer self.base.allocator.free(sections); |
| 1575 | | try seg.sections.ensureCapacity(self.base.allocator, sections.len); |
| 1576 | | |
| 1577 | | // __DATA segment |
| 1578 | | const indices = &[_]*?u16{ |
| 1579 | | &self.la_symbol_ptr_section_index, |
| 1580 | | &self.objc_const_section_index, |
| 1581 | | &self.objc_selrefs_section_index, |
| 1582 | | &self.objc_classrefs_section_index, |
| 1583 | | &self.objc_data_section_index, |
| 1584 | | &self.data_section_index, |
| 1585 | | &self.tlv_section_index, |
| 1586 | | &self.tlv_data_section_index, |
| 1587 | | &self.tlv_bss_section_index, |
| 1588 | | &self.bss_section_index, |
| 1589 | | }; |
| 1590 | | for (indices) |maybe_index| { |
| 1591 | | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| 1592 | | const idx = @intCast(u16, seg.sections.items.len); |
| 1593 | | seg.sections.appendAssumeCapacity(sections[index]); |
| 1594 | | try data_index_mapping.putNoClobber(index, idx); |
| 1595 | | break :blk idx; |
| 1596 | | } else continue; |
| 1597 | | maybe_index.* = new_index; |
| 1598 | | } |
| 1599 | | } |
| 1600 | | |
| 1601 | | { |
| 1602 | | var transient: std.AutoHashMapUnmanaged(MatchingSection, *TextBlock) = .{}; |
| 1603 | | try transient.ensureCapacity(self.base.allocator, self.blocks.count()); |
| 1604 | | |
| 1605 | | var it = self.blocks.iterator(); |
| 1606 | | while (it.next()) |entry| { |
| 1607 | | const old = entry.key_ptr.*; |
| 1608 | | const sect = if (old.seg == self.text_segment_cmd_index.?) |
| 1609 | | text_index_mapping.get(old.sect).? |
| 1610 | | else if (old.seg == self.data_const_segment_cmd_index.?) |
| 1611 | | data_const_index_mapping.get(old.sect).? |
| 1612 | | else |
| 1613 | | data_index_mapping.get(old.sect).?; |
| 1614 | | transient.putAssumeCapacityNoClobber(.{ |
| 1615 | | .seg = old.seg, |
| 1616 | | .sect = sect, |
| 1617 | | }, entry.value_ptr.*); |
| 1618 | | } |
| 1619 | | |
| 1620 | | self.blocks.clearAndFree(self.base.allocator); |
| 1621 | | self.blocks.deinit(self.base.allocator); |
| 1622 | | self.blocks = transient; |
| 1623 | | } |
| 1624 | | |
| 1625 | | { |
| 1626 | | // Create new section ordinals. |
| 1627 | | self.section_ordinals.clearRetainingCapacity(); |
| 1628 | | const text_seg = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1629 | | for (text_seg.sections.items) |_, sect_id| { |
| 1630 | | const res = self.section_ordinals.getOrPutAssumeCapacity(.{ |
| 1631 | | .seg = self.text_segment_cmd_index.?, |
| 1632 | | .sect = @intCast(u16, sect_id), |
| 1633 | | }); |
| 1634 | | assert(!res.found_existing); |
| 1635 | | } |
| 1636 | | const data_const_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1637 | | for (data_const_seg.sections.items) |_, sect_id| { |
| 1638 | | const res = self.section_ordinals.getOrPutAssumeCapacity(.{ |
| 1639 | | .seg = self.data_const_segment_cmd_index.?, |
| 1640 | | .sect = @intCast(u16, sect_id), |
| 1641 | | }); |
| 1642 | | assert(!res.found_existing); |
| 1643 | | } |
| 1644 | | const data_seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1645 | | for (data_seg.sections.items) |_, sect_id| { |
| 1646 | | const res = self.section_ordinals.getOrPutAssumeCapacity(.{ |
| 1647 | | .seg = self.data_segment_cmd_index.?, |
| 1648 | | .sect = @intCast(u16, sect_id), |
| 1649 | | }); |
| 1650 | | assert(!res.found_existing); |
| 1651 | | } |
| 1652 | | } |
| 1653 | | } |
| 1654 | | |
| 1655 | 1502 | fn allocateTextSegment(self: *MachO) !void { |
| 1656 | 1503 | const seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1657 | 1504 | const base_vmaddr = self.load_commands.items[self.pagezero_segment_cmd_index.?].Segment.inner.vmsize; |
| ... | ... | @@ -1894,7 +1741,7 @@ fn writeTextBlocks(self: *MachO) !void { |
| 1894 | 1741 | } |
| 1895 | 1742 | } |
| 1896 | 1743 | |
| 1897 | | fn createEmptyAtom(self: *MachO, local_sym_index: u32, size: u64, alignment: u32) !*TextBlock { |
| 1744 | pub fn createEmptyAtom(self: *MachO, local_sym_index: u32, size: u64, alignment: u32) !*TextBlock { |
| 1898 | 1745 | const code = try self.base.allocator.alloc(u8, size); |
| 1899 | 1746 | defer self.base.allocator.free(code); |
| 1900 | 1747 | mem.set(u8, code, 0); |
| ... | ... | @@ -1924,8 +1771,12 @@ pub fn allocateAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !u64 |
| 1924 | 1771 | const vaddr = mem.alignForwardGeneric(u64, base_addr, atom_alignment); |
| 1925 | 1772 | log.debug("allocating atom for symbol {s} at address 0x{x}", .{ self.getString(sym.n_strx), vaddr }); |
| 1926 | 1773 | |
| 1927 | | // TODO we should check if we need to expand the section or not like we |
| 1928 | | // do in `allocateTextBlock`. |
| 1774 | const expand_section = true; |
| 1775 | if (expand_section) { |
| 1776 | // Expand the section, possibly shifting all the atoms for the sections following it. |
| 1777 | // It might also be needed to shift entire segments too if there is not enough |
| 1778 | // padding left. |
| 1779 | } |
| 1929 | 1780 | const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| 1930 | 1781 | sym.n_value = vaddr; |
| 1931 | 1782 | sym.n_sect = n_sect; |