| ... | @@ -60,13 +60,17 @@ stub_helper_section_index: ?u16 = null, | ... | @@ -60,13 +60,17 @@ stub_helper_section_index: ?u16 = null, |
| 60 | text_const_section_index: ?u16 = null, | 60 | text_const_section_index: ?u16 = null, |
| 61 | cstring_section_index: ?u16 = null, | 61 | cstring_section_index: ?u16 = null, |
| 62 | | 62 | |
| 63 | // __DATA segment sections | 63 | // __DATA_CONST segment sections |
| 64 | got_section_index: ?u16 = null, | 64 | got_section_index: ?u16 = null, |
| | 65 | mod_init_func_section_index: ?u16 = null, |
| | 66 | mod_term_func_section_index: ?u16 = null, |
| | 67 | data_const_section_index: ?u16 = null, |
| | 68 | |
| | 69 | // __DATA segment sections |
| 65 | tlv_section_index: ?u16 = null, | 70 | tlv_section_index: ?u16 = null, |
| 66 | tlv_data_section_index: ?u16 = null, | 71 | tlv_data_section_index: ?u16 = null, |
| 67 | tlv_bss_section_index: ?u16 = null, | 72 | tlv_bss_section_index: ?u16 = null, |
| 68 | la_symbol_ptr_section_index: ?u16 = null, | 73 | la_symbol_ptr_section_index: ?u16 = null, |
| 69 | data_const_section_index: ?u16 = null, | | |
| 70 | data_section_index: ?u16 = null, | 74 | data_section_index: ?u16 = null, |
| 71 | bss_section_index: ?u16 = null, | 75 | bss_section_index: ?u16 = null, |
| 72 | | 76 | |
| ... | @@ -448,6 +452,46 @@ fn updateMetadata(self: *Zld, object_id: u16) !void { | ... | @@ -448,6 +452,46 @@ fn updateMetadata(self: *Zld, object_id: u16) !void { |
| 448 | .reserved3 = 0, | 452 | .reserved3 = 0, |
| 449 | }); | 453 | }); |
| 450 | }, | 454 | }, |
| | 455 | macho.S_MOD_INIT_FUNC_POINTERS => { |
| | 456 | if (!mem.eql(u8, segname, "__DATA")) continue; |
| | 457 | if (self.mod_init_func_section_index != null) continue; |
| | 458 | |
| | 459 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 460 | try data_const_seg.addSection(self.allocator, .{ |
| | 461 | .sectname = makeStaticString("__mod_init_func"), |
| | 462 | .segname = makeStaticString("__DATA_CONST"), |
| | 463 | .addr = 0, |
| | 464 | .size = 0, |
| | 465 | .offset = 0, |
| | 466 | .@"align" = 0, |
| | 467 | .reloff = 0, |
| | 468 | .nreloc = 0, |
| | 469 | .flags = macho.S_MOD_INIT_FUNC_POINTERS, |
| | 470 | .reserved1 = 0, |
| | 471 | .reserved2 = 0, |
| | 472 | .reserved3 = 0, |
| | 473 | }); |
| | 474 | }, |
| | 475 | macho.S_MOD_TERM_FUNC_POINTERS => { |
| | 476 | if (!mem.eql(u8, segname, "__DATA")) continue; |
| | 477 | if (self.mod_term_func_section_index != null) continue; |
| | 478 | |
| | 479 | self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 480 | try data_const_seg.addSection(self.allocator, .{ |
| | 481 | .sectname = makeStaticString("__mod_term_func"), |
| | 482 | .segname = makeStaticString("__DATA_CONST"), |
| | 483 | .addr = 0, |
| | 484 | .size = 0, |
| | 485 | .offset = 0, |
| | 486 | .@"align" = 0, |
| | 487 | .reloff = 0, |
| | 488 | .nreloc = 0, |
| | 489 | .flags = macho.S_MOD_TERM_FUNC_POINTERS, |
| | 490 | .reserved1 = 0, |
| | 491 | .reserved2 = 0, |
| | 492 | .reserved3 = 0, |
| | 493 | }); |
| | 494 | }, |
| 451 | macho.S_ZEROFILL => { | 495 | macho.S_ZEROFILL => { |
| 452 | if (!mem.eql(u8, segname, "__DATA")) continue; | 496 | if (!mem.eql(u8, segname, "__DATA")) continue; |
| 453 | if (self.bss_section_index != null) continue; | 497 | if (self.bss_section_index != null) continue; |
| ... | @@ -583,6 +627,18 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { | ... | @@ -583,6 +627,18 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 583 | .sect = self.cstring_section_index.?, | 627 | .sect = self.cstring_section_index.?, |
| 584 | }; | 628 | }; |
| 585 | }, | 629 | }, |
| | 630 | macho.S_MOD_INIT_FUNC_POINTERS => { |
| | 631 | break :blk .{ |
| | 632 | .seg = self.data_const_segment_cmd_index.?, |
| | 633 | .sect = self.mod_init_func_section_index.?, |
| | 634 | }; |
| | 635 | }, |
| | 636 | macho.S_MOD_TERM_FUNC_POINTERS => { |
| | 637 | break :blk .{ |
| | 638 | .seg = self.data_const_segment_cmd_index.?, |
| | 639 | .sect = self.mod_term_func_section_index.?, |
| | 640 | }; |
| | 641 | }, |
| 586 | macho.S_ZEROFILL => { | 642 | macho.S_ZEROFILL => { |
| 587 | break :blk .{ | 643 | break :blk .{ |
| 588 | .seg = self.data_segment_cmd_index.?, | 644 | .seg = self.data_segment_cmd_index.?, |
| ... | @@ -684,6 +740,8 @@ fn sortSections(self: *Zld) !void { | ... | @@ -684,6 +740,8 @@ fn sortSections(self: *Zld) !void { |
| 684 | | 740 | |
| 685 | const indices = &[_]*?u16{ | 741 | const indices = &[_]*?u16{ |
| 686 | &self.got_section_index, | 742 | &self.got_section_index, |
| | 743 | &self.mod_init_func_section_index, |
| | 744 | &self.mod_term_func_section_index, |
| 687 | &self.data_const_section_index, | 745 | &self.data_const_section_index, |
| 688 | }; | 746 | }; |
| 689 | for (indices) |maybe_index| { | 747 | for (indices) |maybe_index| { |
| ... | @@ -2471,6 +2529,42 @@ fn writeRebaseInfoTable(self: *Zld) !void { | ... | @@ -2471,6 +2529,42 @@ fn writeRebaseInfoTable(self: *Zld) !void { |
| 2471 | } | 2529 | } |
| 2472 | } | 2530 | } |
| 2473 | | 2531 | |
| | 2532 | if (self.mod_init_func_section_index) |idx| { |
| | 2533 | // TODO audit and investigate this. |
| | 2534 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| | 2535 | const sect = seg.sections.items[idx]; |
| | 2536 | const npointers = sect.size * @sizeOf(u64); |
| | 2537 | const base_offset = sect.addr - seg.inner.vmaddr; |
| | 2538 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); |
| | 2539 | |
| | 2540 | try pointers.ensureCapacity(pointers.items.len + npointers); |
| | 2541 | var i: usize = 0; |
| | 2542 | while (i < npointers) : (i += 1) { |
| | 2543 | pointers.appendAssumeCapacity(.{ |
| | 2544 | .offset = base_offset + i * @sizeOf(u64), |
| | 2545 | .segment_id = segment_id, |
| | 2546 | }); |
| | 2547 | } |
| | 2548 | } |
| | 2549 | |
| | 2550 | if (self.mod_term_func_section_index) |idx| { |
| | 2551 | // TODO audit and investigate this. |
| | 2552 | const seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| | 2553 | const sect = seg.sections.items[idx]; |
| | 2554 | const npointers = sect.size * @sizeOf(u64); |
| | 2555 | const base_offset = sect.addr - seg.inner.vmaddr; |
| | 2556 | const segment_id = @intCast(u16, self.data_const_segment_cmd_index.?); |
| | 2557 | |
| | 2558 | try pointers.ensureCapacity(pointers.items.len + npointers); |
| | 2559 | var i: usize = 0; |
| | 2560 | while (i < npointers) : (i += 1) { |
| | 2561 | pointers.appendAssumeCapacity(.{ |
| | 2562 | .offset = base_offset + i * @sizeOf(u64), |
| | 2563 | .segment_id = segment_id, |
| | 2564 | }); |
| | 2565 | } |
| | 2566 | } |
| | 2567 | |
| 2474 | if (self.la_symbol_ptr_section_index) |idx| { | 2568 | if (self.la_symbol_ptr_section_index) |idx| { |
| 2475 | try pointers.ensureCapacity(pointers.items.len + self.lazy_imports.items().len); | 2569 | try pointers.ensureCapacity(pointers.items.len + self.lazy_imports.items().len); |
| 2476 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; | 2570 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |