authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-05 23:17:53+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-01-13 23:53:36+01:00
log51a13f8ea6f1596a3163ac656e0ddb1156d1399a
tree0c77270d675af8bcfe70c67416bb99b8096329b7
parent3d07f057b1ccbc20258114fde762969bcfddf1d3

macho: add missing data sections


1 files changed, 168 insertions(+), 4 deletions(-)

src/link/MachO.zig+168-4
......@@ -89,6 +89,16 @@ code_signature_cmd_index: ?u16 = null,
8989text_section_index: ?u16 = null,
9090/// Index into __TEXT,__ziggot section.
9191got_section_index: ?u16 = null,
92/// Index into __TEXT,__stubs section.
93stubs_section_index: ?u16 = null,
94/// Index into __TEXT,__stub_helper section.
95stub_helper_section_index: ?u16 = null,
96/// Index into __DATA_CONST,__got section.
97data_got_section_index: ?u16 = null,
98/// Index into __DATA,__la_symbol_ptr section.
99la_symbol_ptr_section_index: ?u16 = null,
100/// Index into __DATA,__data section.
101data_section_index: ?u16 = null,
92102/// The absolute address of the entry point.
93103entry_addr: ?u64 = null,
94104
......@@ -1437,7 +1447,7 @@ pub fn populateMissingMetadata(self: *MachO) !void {
14371447
14381448 const program_code_size_hint = self.base.options.program_code_size_hint;
14391449 const offset_table_size_hint = @sizeOf(u64) * self.base.options.symbol_count_hint;
1440 const ideal_size = self.header_pad + program_code_size_hint + offset_table_size_hint;
1450 const ideal_size = self.header_pad + program_code_size_hint + 3 * offset_table_size_hint;
14411451 const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, self.page_size);
14421452
14431453 log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size });
......@@ -1494,9 +1504,13 @@ pub fn populateMissingMetadata(self: *MachO) !void {
14941504 }
14951505 if (self.got_section_index == null) {
14961506 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1497 const text_section = &text_segment.sections.items[self.text_section_index.?];
14981507 self.got_section_index = @intCast(u16, text_segment.sections.items.len);
14991508
1509 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
1510 .x86_64 => 0,
1511 .aarch64 => 2,
1512 else => unreachable, // unhandled architecture type
1513 };
15001514 const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS;
15011515 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
15021516 const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad);
......@@ -1510,7 +1524,73 @@ pub fn populateMissingMetadata(self: *MachO) !void {
15101524 .addr = text_segment.inner.vmaddr + off,
15111525 .size = needed_size,
15121526 .offset = @intCast(u32, off),
1513 .@"align" = 3, // 2^@sizeOf(u64)
1527 .@"align" = alignment,
1528 .reloff = 0,
1529 .nreloc = 0,
1530 .flags = flags,
1531 .reserved1 = 0,
1532 .reserved2 = 0,
1533 .reserved3 = 0,
1534 });
1535 self.header_dirty = true;
1536 self.load_commands_dirty = true;
1537 }
1538 if (self.stubs_section_index == null) {
1539 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1540 self.stubs_section_index = @intCast(u16, text_segment.sections.items.len);
1541
1542 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
1543 .x86_64 => 0,
1544 .aarch64 => 2,
1545 else => unreachable, // unhandled architecture type
1546 };
1547 const flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS;
1548 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
1549 const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad);
1550 assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment.
1551
1552 log.debug("found __stubs section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
1553
1554 try text_segment.addSection(self.base.allocator, .{
1555 .sectname = makeStaticString("__stubs"),
1556 .segname = makeStaticString("__TEXT"),
1557 .addr = text_segment.inner.vmaddr + off,
1558 .size = 0, // This will be populated later in tandem with .reserved2 field.
1559 .offset = @intCast(u32, off),
1560 .@"align" = alignment,
1561 .reloff = 0,
1562 .nreloc = 0,
1563 .flags = flags,
1564 .reserved1 = 0,
1565 .reserved2 = 0,
1566 .reserved3 = 0,
1567 });
1568 self.header_dirty = true;
1569 self.load_commands_dirty = true;
1570 }
1571 if (self.stub_helper_section_index == null) {
1572 const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment;
1573 self.stub_helper_section_index = @intCast(u16, text_segment.sections.items.len);
1574
1575 const alignment: u2 = switch (self.base.options.target.cpu.arch) {
1576 .x86_64 => 0,
1577 .aarch64 => 2,
1578 else => unreachable, // unhandled architecture type
1579 };
1580 const flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS;
1581 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
1582 const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad);
1583 assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment.
1584
1585 log.debug("found __stubs section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
1586
1587 try text_segment.addSection(self.base.allocator, .{
1588 .sectname = makeStaticString("__stub_helper"),
1589 .segname = makeStaticString("__TEXT"),
1590 .addr = text_segment.inner.vmaddr + off,
1591 .size = needed_size,
1592 .offset = @intCast(u32, off),
1593 .@"align" = alignment,
15141594 .reloff = 0,
15151595 .nreloc = 0,
15161596 .flags = flags,
......@@ -1550,13 +1630,41 @@ pub fn populateMissingMetadata(self: *MachO) !void {
15501630 self.header_dirty = true;
15511631 self.load_commands_dirty = true;
15521632 }
1633 if (self.data_got_section_index == null) {
1634 const dc_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment;
1635 self.data_got_section_index = @intCast(u16, dc_segment.sections.items.len);
1636
1637 const flags = macho.S_NON_LAZY_SYMBOL_POINTERS;
1638 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
1639 const off = dc_segment.findFreeSpace(needed_size, @alignOf(u64), null);
1640 assert(off + needed_size <= dc_segment.inner.fileoff + dc_segment.inner.filesize); // TODO Must expand __DATA_CONST segment.
1641
1642 log.debug("found __got section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
1643
1644 try dc_segment.addSection(self.base.allocator, .{
1645 .sectname = makeStaticString("__got"),
1646 .segname = makeStaticString("__DATA_CONST"),
1647 .addr = dc_segment.inner.vmaddr + off - dc_segment.inner.fileoff,
1648 .size = needed_size,
1649 .offset = @intCast(u32, off),
1650 .@"align" = 3, // 2^3 = @sizeOf(u64)
1651 .reloff = 0,
1652 .nreloc = 0,
1653 .flags = flags,
1654 .reserved1 = 0,
1655 .reserved2 = 0,
1656 .reserved3 = 0,
1657 });
1658 self.header_dirty = true;
1659 self.load_commands_dirty = true;
1660 }
15531661 if (self.data_segment_cmd_index == null) {
15541662 self.data_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
15551663 const maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE | macho.VM_PROT_EXECUTE;
15561664 const initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE;
15571665 const address_and_offset = self.nextSegmentAddressAndOffset();
15581666
1559 const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
1667 const ideal_size = 2 * @sizeOf(u64) * self.base.options.symbol_count_hint;
15601668 const needed_size = mem.alignForwardGeneric(u64, satMul(ideal_size, alloc_num) / alloc_den, self.page_size);
15611669
15621670 log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size });
......@@ -1579,6 +1687,62 @@ pub fn populateMissingMetadata(self: *MachO) !void {
15791687 self.header_dirty = true;
15801688 self.load_commands_dirty = true;
15811689 }
1690 if (self.la_symbol_ptr_section_index == null) {
1691 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1692 self.la_symbol_ptr_section_index = @intCast(u16, data_segment.sections.items.len);
1693
1694 const flags = macho.S_LAZY_SYMBOL_POINTERS;
1695 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
1696 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
1697 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
1698
1699 log.debug("found __la_symbol_ptr section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
1700
1701 try data_segment.addSection(self.base.allocator, .{
1702 .sectname = makeStaticString("__la_symbol_ptr"),
1703 .segname = makeStaticString("__DATA"),
1704 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
1705 .size = needed_size,
1706 .offset = @intCast(u32, off),
1707 .@"align" = 3, // 2^3 = @sizeOf(u64)
1708 .reloff = 0,
1709 .nreloc = 0,
1710 .flags = flags,
1711 .reserved1 = 0,
1712 .reserved2 = 0,
1713 .reserved3 = 0,
1714 });
1715 self.header_dirty = true;
1716 self.load_commands_dirty = true;
1717 }
1718 if (self.data_section_index == null) {
1719 const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment;
1720 self.data_section_index = @intCast(u16, data_segment.sections.items.len);
1721
1722 const flags = macho.S_REGULAR;
1723 const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint;
1724 const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null);
1725 assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment.
1726
1727 log.debug("found __data section free space 0x{x} to 0x{x}", .{ off, off + needed_size });
1728
1729 try data_segment.addSection(self.base.allocator, .{
1730 .sectname = makeStaticString("__data"),
1731 .segname = makeStaticString("__DATA"),
1732 .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff,
1733 .size = needed_size,
1734 .offset = @intCast(u32, off),
1735 .@"align" = 3, // 2^3 = @sizeOf(u64)
1736 .reloff = 0,
1737 .nreloc = 0,
1738 .flags = flags,
1739 .reserved1 = 0,
1740 .reserved2 = 0,
1741 .reserved3 = 0,
1742 });
1743 self.header_dirty = true;
1744 self.load_commands_dirty = true;
1745 }
15821746 if (self.linkedit_segment_cmd_index == null) {
15831747 self.linkedit_segment_cmd_index = @intCast(u16, self.load_commands.items.len);
15841748