| ... | ... | @@ -60,13 +60,17 @@ stub_helper_section_index: ?u16 = null, |
| 60 | 60 | text_const_section_index: ?u16 = null, |
| 61 | 61 | cstring_section_index: ?u16 = null, |
| 62 | 62 | |
| 63 | | // __DATA segment sections |
| 63 | // __DATA_CONST segment sections |
| 64 | 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 | 70 | tlv_section_index: ?u16 = null, |
| 66 | 71 | tlv_data_section_index: ?u16 = null, |
| 67 | 72 | tlv_bss_section_index: ?u16 = null, |
| 68 | 73 | la_symbol_ptr_section_index: ?u16 = null, |
| 69 | | data_const_section_index: ?u16 = null, |
| 70 | 74 | data_section_index: ?u16 = null, |
| 71 | 75 | bss_section_index: ?u16 = null, |
| 72 | 76 | |
| ... | ... | @@ -448,6 +452,46 @@ fn updateMetadata(self: *Zld, object_id: u16) !void { |
| 448 | 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 | 495 | macho.S_ZEROFILL => { |
| 452 | 496 | if (!mem.eql(u8, segname, "__DATA")) continue; |
| 453 | 497 | if (self.bss_section_index != null) continue; |
| ... | ... | @@ -583,6 +627,18 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { |
| 583 | 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 | 642 | macho.S_ZEROFILL => { |
| 587 | 643 | break :blk .{ |
| 588 | 644 | .seg = self.data_segment_cmd_index.?, |
| ... | ... | @@ -684,6 +740,8 @@ fn sortSections(self: *Zld) !void { |
| 684 | 740 | |
| 685 | 741 | const indices = &[_]*?u16{ |
| 686 | 742 | &self.got_section_index, |
| 743 | &self.mod_init_func_section_index, |
| 744 | &self.mod_term_func_section_index, |
| 687 | 745 | &self.data_const_section_index, |
| 688 | 746 | }; |
| 689 | 747 | for (indices) |maybe_index| { |
| ... | ... | @@ -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 | 2568 | if (self.la_symbol_ptr_section_index) |idx| { |
| 2475 | 2569 | try pointers.ensureCapacity(pointers.items.len + self.lazy_imports.items().len); |
| 2476 | 2570 | const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |