authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-03-21 22:33:32+01:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-03-22 17:14:53+01:00
log3b48ea874ed4d0231a080ed583c7740478e58ed8
tree7cd939345973c3ae450df4c9a13212b3e54fea30
parentdce612ac2be5aa8a1aa0ee8dd670d7e875624216

zld: naively handle static initializers in C++


1 files changed, 96 insertions(+), 2 deletions(-)

src/link/MachO/Zld.zig+96-2
......@@ -60,13 +60,17 @@ stub_helper_section_index: ?u16 = null,
6060text_const_section_index: ?u16 = null,
6161cstring_section_index: ?u16 = null,
6262
63// __DATA segment sections
63// __DATA_CONST segment sections
6464got_section_index: ?u16 = null,
65mod_init_func_section_index: ?u16 = null,
66mod_term_func_section_index: ?u16 = null,
67data_const_section_index: ?u16 = null,
68
69// __DATA segment sections
6570tlv_section_index: ?u16 = null,
6671tlv_data_section_index: ?u16 = null,
6772tlv_bss_section_index: ?u16 = null,
6873la_symbol_ptr_section_index: ?u16 = null,
69data_const_section_index: ?u16 = null,
7074data_section_index: ?u16 = null,
7175bss_section_index: ?u16 = null,
7276
......@@ -448,6 +452,46 @@ fn updateMetadata(self: *Zld, object_id: u16) !void {
448452 .reserved3 = 0,
449453 });
450454 },
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 },
451495 macho.S_ZEROFILL => {
452496 if (!mem.eql(u8, segname, "__DATA")) continue;
453497 if (self.bss_section_index != null) continue;
......@@ -583,6 +627,18 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection {
583627 .sect = self.cstring_section_index.?,
584628 };
585629 },
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 },
586642 macho.S_ZEROFILL => {
587643 break :blk .{
588644 .seg = self.data_segment_cmd_index.?,
......@@ -684,6 +740,8 @@ fn sortSections(self: *Zld) !void {
684740
685741 const indices = &[_]*?u16{
686742 &self.got_section_index,
743 &self.mod_init_func_section_index,
744 &self.mod_term_func_section_index,
687745 &self.data_const_section_index,
688746 };
689747 for (indices) |maybe_index| {
......@@ -2471,6 +2529,42 @@ fn writeRebaseInfoTable(self: *Zld) !void {
24712529 }
24722530 }
24732531
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
24742568 if (self.la_symbol_ptr_section_index) |idx| {
24752569 try pointers.ensureCapacity(pointers.items.len + self.lazy_imports.items().len);
24762570 const seg = self.load_commands.items[self.data_segment_cmd_index.?].Segment;