| ... | @@ -503,217 +503,22 @@ fn mapAndUpdateSections( | ... | @@ -503,217 +503,22 @@ fn mapAndUpdateSections( |
| 503 | | 503 | |
| 504 | fn updateMetadata(self: *Zld) !void { | 504 | fn updateMetadata(self: *Zld) !void { |
| 505 | for (self.objects.items) |object| { | 505 | for (self.objects.items) |object| { |
| 506 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 506 | // Find ideal section alignment and update section mappings |
| 507 | const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | | |
| 508 | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 509 | | | |
| 510 | // Create missing metadata | | |
| 511 | for (object.sections.items) |sect| { | | |
| 512 | const segname = sect.segname(); | | |
| 513 | const sectname = sect.sectname(); | | |
| 514 | | | |
| 515 | switch (sect.sectionType()) { | | |
| 516 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS, macho.S_LITERAL_POINTERS => { | | |
| 517 | if (self.text_const_section_index != null) continue; | | |
| 518 | | | |
| 519 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 520 | try text_seg.addSection(self.allocator, "__const", "__TEXT", .{}); | | |
| 521 | continue; | | |
| 522 | }, | | |
| 523 | macho.S_CSTRING_LITERALS => { | | |
| 524 | if (self.cstring_section_index != null) continue; | | |
| 525 | | | |
| 526 | self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 527 | try text_seg.addSection(self.allocator, "__cstring", "__TEXT", .{ | | |
| 528 | .flags = macho.S_CSTRING_LITERALS, | | |
| 529 | }); | | |
| 530 | continue; | | |
| 531 | }, | | |
| 532 | macho.S_MOD_INIT_FUNC_POINTERS => { | | |
| 533 | if (self.mod_init_func_section_index != null) continue; | | |
| 534 | | | |
| 535 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); | | |
| 536 | try data_const_seg.addSection(self.allocator, "__mod_init_func", "__DATA_CONST", .{ | | |
| 537 | .flags = macho.S_MOD_INIT_FUNC_POINTERS, | | |
| 538 | }); | | |
| 539 | continue; | | |
| 540 | }, | | |
| 541 | macho.S_MOD_TERM_FUNC_POINTERS => { | | |
| 542 | if (self.mod_term_func_section_index != null) continue; | | |
| 543 | | | |
| 544 | self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len); | | |
| 545 | try data_const_seg.addSection(self.allocator, "__mod_term_func", "__DATA_CONST", .{ | | |
| 546 | .flags = macho.S_MOD_TERM_FUNC_POINTERS, | | |
| 547 | }); | | |
| 548 | continue; | | |
| 549 | }, | | |
| 550 | macho.S_ZEROFILL => { | | |
| 551 | if (mem.eql(u8, sectname, "__common")) { | | |
| 552 | if (self.common_section_index != null) continue; | | |
| 553 | | | |
| 554 | self.common_section_index = @intCast(u16, data_seg.sections.items.len); | | |
| 555 | try data_seg.addSection(self.allocator, "__common", "__DATA", .{ | | |
| 556 | .flags = macho.S_ZEROFILL, | | |
| 557 | }); | | |
| 558 | } else { | | |
| 559 | if (self.bss_section_index != null) continue; | | |
| 560 | | | |
| 561 | self.bss_section_index = @intCast(u16, data_seg.sections.items.len); | | |
| 562 | try data_seg.addSection(self.allocator, "__bss", "__DATA", .{ | | |
| 563 | .flags = macho.S_ZEROFILL, | | |
| 564 | }); | | |
| 565 | } | | |
| 566 | continue; | | |
| 567 | }, | | |
| 568 | macho.S_THREAD_LOCAL_VARIABLES => { | | |
| 569 | if (self.tlv_section_index != null) continue; | | |
| 570 | | | |
| 571 | self.tlv_section_index = @intCast(u16, data_seg.sections.items.len); | | |
| 572 | try data_seg.addSection(self.allocator, "__thread_vars", "__DATA", .{ | | |
| 573 | .flags = macho.S_THREAD_LOCAL_VARIABLES, | | |
| 574 | }); | | |
| 575 | continue; | | |
| 576 | }, | | |
| 577 | macho.S_THREAD_LOCAL_REGULAR => { | | |
| 578 | if (self.tlv_data_section_index != null) continue; | | |
| 579 | | | |
| 580 | self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len); | | |
| 581 | try data_seg.addSection(self.allocator, "__thread_data", "__DATA", .{ | | |
| 582 | .flags = macho.S_THREAD_LOCAL_REGULAR, | | |
| 583 | }); | | |
| 584 | continue; | | |
| 585 | }, | | |
| 586 | macho.S_THREAD_LOCAL_ZEROFILL => { | | |
| 587 | if (self.tlv_bss_section_index != null) continue; | | |
| 588 | | | |
| 589 | self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len); | | |
| 590 | try data_seg.addSection(self.allocator, "__thread_bss", "__DATA", .{ | | |
| 591 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, | | |
| 592 | }); | | |
| 593 | continue; | | |
| 594 | }, | | |
| 595 | macho.S_COALESCED => { | | |
| 596 | if (mem.eql(u8, "__TEXT", segname) and mem.eql(u8, "__eh_frame", sectname)) { | | |
| 597 | // TODO I believe __eh_frame is currently part of __unwind_info section | | |
| 598 | // in the latest ld64 output. | | |
| 599 | if (self.eh_frame_section_index != null) continue; | | |
| 600 | | | |
| 601 | self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 602 | try text_seg.addSection(self.allocator, "__eh_frame", "__TEXT", .{}); | | |
| 603 | continue; | | |
| 604 | } | | |
| 605 | | | |
| 606 | // TODO audit this: is this the right mapping? | | |
| 607 | if (self.data_const_section_index != null) continue; | | |
| 608 | | | |
| 609 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | | |
| 610 | try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{}); | | |
| 611 | continue; | | |
| 612 | }, | | |
| 613 | macho.S_REGULAR => { | | |
| 614 | if (sect.isCode()) { | | |
| 615 | if (self.text_section_index != null) continue; | | |
| 616 | | | |
| 617 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 618 | try text_seg.addSection(self.allocator, "__text", "__TEXT", .{ | | |
| 619 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | | |
| 620 | }); | | |
| 621 | continue; | | |
| 622 | } | | |
| 623 | | | |
| 624 | if (sect.isDebug()) { | | |
| 625 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { | | |
| 626 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ | | |
| 627 | sect.flags(), segname, sectname, | | |
| 628 | }); | | |
| 629 | } | | |
| 630 | continue; | | |
| 631 | } | | |
| 632 | | | |
| 633 | if (mem.eql(u8, segname, "__TEXT")) { | | |
| 634 | if (mem.eql(u8, sectname, "__ustring")) { | | |
| 635 | if (self.ustring_section_index != null) continue; | | |
| 636 | | | |
| 637 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 638 | try text_seg.addSection(self.allocator, "__ustring", "__TEXT", .{}); | | |
| 639 | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { | | |
| 640 | if (self.gcc_except_tab_section_index != null) continue; | | |
| 641 | | | |
| 642 | self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 643 | try text_seg.addSection(self.allocator, "__gcc_except_tab", "__TEXT", .{}); | | |
| 644 | } else { | | |
| 645 | if (self.text_const_section_index != null) continue; | | |
| 646 | | | |
| 647 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | | |
| 648 | try text_seg.addSection(self.allocator, "__const", "__TEXT", .{}); | | |
| 649 | } | | |
| 650 | continue; | | |
| 651 | } | | |
| 652 | | | |
| 653 | if (mem.eql(u8, segname, "__DATA_CONST")) { | | |
| 654 | if (self.data_const_section_index != null) continue; | | |
| 655 | | | |
| 656 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | | |
| 657 | try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{}); | | |
| 658 | continue; | | |
| 659 | } | | |
| 660 | | | |
| 661 | if (mem.eql(u8, segname, "__DATA")) { | | |
| 662 | if (mem.eql(u8, sectname, "__const")) { | | |
| 663 | if (self.data_const_section_index != null) continue; | | |
| 664 | | | |
| 665 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | | |
| 666 | try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{}); | | |
| 667 | } else if (mem.eql(u8, sectname, "__cfstring")) { | | |
| 668 | if (self.objc_cfstring_section_index != null) continue; | | |
| 669 | | | |
| 670 | self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len); | | |
| 671 | try data_const_seg.addSection(self.allocator, "__cfstring", "__DATA_CONST", .{}); | | |
| 672 | } else { | | |
| 673 | if (self.data_section_index != null) continue; | | |
| 674 | | | |
| 675 | self.data_section_index = @intCast(u16, data_seg.sections.items.len); | | |
| 676 | try data_seg.addSection(self.allocator, "__data", "__DATA", .{}); | | |
| 677 | } | | |
| 678 | | | |
| 679 | continue; | | |
| 680 | } | | |
| 681 | | | |
| 682 | if (mem.eql(u8, "__LLVM", segname) and mem.eql(u8, "__asm", sectname)) { | | |
| 683 | log.debug("TODO LLVM asm section: type 0x{x}, name '{s},{s}'", .{ | | |
| 684 | sect.flags(), segname, sectname, | | |
| 685 | }); | | |
| 686 | continue; | | |
| 687 | } | | |
| 688 | }, | | |
| 689 | else => {}, | | |
| 690 | } | | |
| 691 | | | |
| 692 | log.err("{s}: unhandled section type 0x{x} for '{s},{s}'", .{ | | |
| 693 | object.name.?, | | |
| 694 | sect.flags(), | | |
| 695 | segname, | | |
| 696 | sectname, | | |
| 697 | }); | | |
| 698 | return error.UnhandledSection; | | |
| 699 | } | | |
| 700 | | | |
| 701 | // Find ideal section alignment. | | |
| 702 | for (object.sections.items) |sect| { | | |
| 703 | if (self.getMatchingSection(sect)) |res| { | | |
| 704 | const target_seg = &self.load_commands.items[res.seg].Segment; | | |
| 705 | const target_sect = &target_seg.sections.items[res.sect]; | | |
| 706 | target_sect.@"align" = math.max(target_sect.@"align", sect.inner.@"align"); | | |
| 707 | } | | |
| 708 | } | | |
| 709 | | | |
| 710 | // Update section mappings | | |
| 711 | for (object.sections.items) |sect, sect_id| { | 507 | for (object.sections.items) |sect, sect_id| { |
| 712 | if (self.getMatchingSection(sect)) |res| { | 508 | const match = (try self.getMatchingSection(sect)) orelse { |
| 713 | try self.mapAndUpdateSections(object, @intCast(u16, sect_id), res.seg, res.sect); | 509 | log.debug("{s}: unhandled section type 0x{x} for '{s},{s}'", .{ |
| | 510 | object.name.?, |
| | 511 | sect.flags(), |
| | 512 | sect.segname(), |
| | 513 | sect.sectname(), |
| | 514 | }); |
| 714 | continue; | 515 | continue; |
| 715 | } | 516 | }; |
| 716 | log.debug("section '{s},{s}' will be unmapped", .{ sect.segname(), sect.sectname() }); | 517 | const target_seg = &self.load_commands.items[match.seg].Segment; |
| | 518 | const target_sect = &target_seg.sections.items[match.sect]; |
| | 519 | target_sect.@"align" = math.max(target_sect.@"align", sect.inner.@"align"); |
| | 520 | |
| | 521 | try self.mapAndUpdateSections(object, @intCast(u16, sect_id), match.seg, match.sect); |
| 717 | } | 522 | } |
| 718 | } | 523 | } |
| 719 | | 524 | |
| ... | @@ -798,31 +603,60 @@ const MatchingSection = struct { | ... | @@ -798,31 +603,60 @@ const MatchingSection = struct { |
| 798 | sect: u16, | 603 | sect: u16, |
| 799 | }; | 604 | }; |
| 800 | | 605 | |
| 801 | fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | 606 | fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { |
| | 607 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| | 608 | const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| | 609 | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 802 | const segname = sect.segname(); | 610 | const segname = sect.segname(); |
| 803 | const sectname = sect.sectname(); | 611 | const sectname = sect.sectname(); |
| 804 | | 612 | |
| 805 | const res: ?MatchingSection = blk: { | 613 | const res: ?MatchingSection = blk: { |
| 806 | switch (sect.sectionType()) { | 614 | switch (sect.sectionType()) { |
| 807 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS, macho.S_LITERAL_POINTERS => { | 615 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS, macho.S_LITERAL_POINTERS => { |
| | 616 | if (self.text_const_section_index == null) { |
| | 617 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 618 | try text_seg.addSection(self.allocator, "__const", "__TEXT", .{}); |
| | 619 | } |
| | 620 | |
| 808 | break :blk .{ | 621 | break :blk .{ |
| 809 | .seg = self.text_segment_cmd_index.?, | 622 | .seg = self.text_segment_cmd_index.?, |
| 810 | .sect = self.text_const_section_index.?, | 623 | .sect = self.text_const_section_index.?, |
| 811 | }; | 624 | }; |
| 812 | }, | 625 | }, |
| 813 | macho.S_CSTRING_LITERALS => { | 626 | macho.S_CSTRING_LITERALS => { |
| | 627 | if (self.cstring_section_index == null) { |
| | 628 | self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 629 | try text_seg.addSection(self.allocator, "__cstring", "__TEXT", .{ |
| | 630 | .flags = macho.S_CSTRING_LITERALS, |
| | 631 | }); |
| | 632 | } |
| | 633 | |
| 814 | break :blk .{ | 634 | break :blk .{ |
| 815 | .seg = self.text_segment_cmd_index.?, | 635 | .seg = self.text_segment_cmd_index.?, |
| 816 | .sect = self.cstring_section_index.?, | 636 | .sect = self.cstring_section_index.?, |
| 817 | }; | 637 | }; |
| 818 | }, | 638 | }, |
| 819 | macho.S_MOD_INIT_FUNC_POINTERS => { | 639 | macho.S_MOD_INIT_FUNC_POINTERS => { |
| | 640 | if (self.mod_init_func_section_index == null) { |
| | 641 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 642 | try data_const_seg.addSection(self.allocator, "__mod_init_func", "__DATA_CONST", .{ |
| | 643 | .flags = macho.S_MOD_INIT_FUNC_POINTERS, |
| | 644 | }); |
| | 645 | } |
| | 646 | |
| 820 | break :blk .{ | 647 | break :blk .{ |
| 821 | .seg = self.data_const_segment_cmd_index.?, | 648 | .seg = self.data_const_segment_cmd_index.?, |
| 822 | .sect = self.mod_init_func_section_index.?, | 649 | .sect = self.mod_init_func_section_index.?, |
| 823 | }; | 650 | }; |
| 824 | }, | 651 | }, |
| 825 | macho.S_MOD_TERM_FUNC_POINTERS => { | 652 | macho.S_MOD_TERM_FUNC_POINTERS => { |
| | 653 | if (self.mod_term_func_section_index == null) { |
| | 654 | self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 655 | try data_const_seg.addSection(self.allocator, "__mod_term_func", "__DATA_CONST", .{ |
| | 656 | .flags = macho.S_MOD_TERM_FUNC_POINTERS, |
| | 657 | }); |
| | 658 | } |
| | 659 | |
| 826 | break :blk .{ | 660 | break :blk .{ |
| 827 | .seg = self.data_const_segment_cmd_index.?, | 661 | .seg = self.data_const_segment_cmd_index.?, |
| 828 | .sect = self.mod_term_func_section_index.?, | 662 | .sect = self.mod_term_func_section_index.?, |
| ... | @@ -830,11 +664,25 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | ... | @@ -830,11 +664,25 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 830 | }, | 664 | }, |
| 831 | macho.S_ZEROFILL => { | 665 | macho.S_ZEROFILL => { |
| 832 | if (mem.eql(u8, sectname, "__common")) { | 666 | if (mem.eql(u8, sectname, "__common")) { |
| | 667 | if (self.common_section_index == null) { |
| | 668 | self.common_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 669 | try data_seg.addSection(self.allocator, "__common", "__DATA", .{ |
| | 670 | .flags = macho.S_ZEROFILL, |
| | 671 | }); |
| | 672 | } |
| | 673 | |
| 833 | break :blk .{ | 674 | break :blk .{ |
| 834 | .seg = self.data_segment_cmd_index.?, | 675 | .seg = self.data_segment_cmd_index.?, |
| 835 | .sect = self.common_section_index.?, | 676 | .sect = self.common_section_index.?, |
| 836 | }; | 677 | }; |
| 837 | } else { | 678 | } else { |
| | 679 | if (self.bss_section_index == null) { |
| | 680 | self.bss_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 681 | try data_seg.addSection(self.allocator, "__bss", "__DATA", .{ |
| | 682 | .flags = macho.S_ZEROFILL, |
| | 683 | }); |
| | 684 | } |
| | 685 | |
| 838 | break :blk .{ | 686 | break :blk .{ |
| 839 | .seg = self.data_segment_cmd_index.?, | 687 | .seg = self.data_segment_cmd_index.?, |
| 840 | .sect = self.bss_section_index.?, | 688 | .sect = self.bss_section_index.?, |
| ... | @@ -842,18 +690,39 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | ... | @@ -842,18 +690,39 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 842 | } | 690 | } |
| 843 | }, | 691 | }, |
| 844 | macho.S_THREAD_LOCAL_VARIABLES => { | 692 | macho.S_THREAD_LOCAL_VARIABLES => { |
| | 693 | if (self.tlv_section_index == null) { |
| | 694 | self.tlv_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 695 | try data_seg.addSection(self.allocator, "__thread_vars", "__DATA", .{ |
| | 696 | .flags = macho.S_THREAD_LOCAL_VARIABLES, |
| | 697 | }); |
| | 698 | } |
| | 699 | |
| 845 | break :blk .{ | 700 | break :blk .{ |
| 846 | .seg = self.data_segment_cmd_index.?, | 701 | .seg = self.data_segment_cmd_index.?, |
| 847 | .sect = self.tlv_section_index.?, | 702 | .sect = self.tlv_section_index.?, |
| 848 | }; | 703 | }; |
| 849 | }, | 704 | }, |
| 850 | macho.S_THREAD_LOCAL_REGULAR => { | 705 | macho.S_THREAD_LOCAL_REGULAR => { |
| | 706 | if (self.tlv_data_section_index == null) { |
| | 707 | self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 708 | try data_seg.addSection(self.allocator, "__thread_data", "__DATA", .{ |
| | 709 | .flags = macho.S_THREAD_LOCAL_REGULAR, |
| | 710 | }); |
| | 711 | } |
| | 712 | |
| 851 | break :blk .{ | 713 | break :blk .{ |
| 852 | .seg = self.data_segment_cmd_index.?, | 714 | .seg = self.data_segment_cmd_index.?, |
| 853 | .sect = self.tlv_data_section_index.?, | 715 | .sect = self.tlv_data_section_index.?, |
| 854 | }; | 716 | }; |
| 855 | }, | 717 | }, |
| 856 | macho.S_THREAD_LOCAL_ZEROFILL => { | 718 | macho.S_THREAD_LOCAL_ZEROFILL => { |
| | 719 | if (self.tlv_bss_section_index == null) { |
| | 720 | self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 721 | try data_seg.addSection(self.allocator, "__thread_bss", "__DATA", .{ |
| | 722 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| | 723 | }); |
| | 724 | } |
| | 725 | |
| 857 | break :blk .{ | 726 | break :blk .{ |
| 858 | .seg = self.data_segment_cmd_index.?, | 727 | .seg = self.data_segment_cmd_index.?, |
| 859 | .sect = self.tlv_bss_section_index.?, | 728 | .sect = self.tlv_bss_section_index.?, |
| ... | @@ -861,12 +730,25 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | ... | @@ -861,12 +730,25 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 861 | }, | 730 | }, |
| 862 | macho.S_COALESCED => { | 731 | macho.S_COALESCED => { |
| 863 | if (mem.eql(u8, "__TEXT", segname) and mem.eql(u8, "__eh_frame", sectname)) { | 732 | if (mem.eql(u8, "__TEXT", segname) and mem.eql(u8, "__eh_frame", sectname)) { |
| | 733 | // TODO I believe __eh_frame is currently part of __unwind_info section |
| | 734 | // in the latest ld64 output. |
| | 735 | if (self.eh_frame_section_index == null) { |
| | 736 | self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 737 | try text_seg.addSection(self.allocator, "__eh_frame", "__TEXT", .{}); |
| | 738 | } |
| | 739 | |
| 864 | break :blk .{ | 740 | break :blk .{ |
| 865 | .seg = self.text_segment_cmd_index.?, | 741 | .seg = self.text_segment_cmd_index.?, |
| 866 | .sect = self.eh_frame_section_index.?, | 742 | .sect = self.eh_frame_section_index.?, |
| 867 | }; | 743 | }; |
| 868 | } | 744 | } |
| 869 | | 745 | |
| | 746 | // TODO audit this: is this the right mapping? |
| | 747 | if (self.data_const_section_index == null) { |
| | 748 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 749 | try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{}); |
| | 750 | } |
| | 751 | |
| 870 | break :blk .{ | 752 | break :blk .{ |
| 871 | .seg = self.data_const_segment_cmd_index.?, | 753 | .seg = self.data_const_segment_cmd_index.?, |
| 872 | .sect = self.data_const_section_index.?, | 754 | .sect = self.data_const_section_index.?, |
| ... | @@ -874,6 +756,13 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | ... | @@ -874,6 +756,13 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 874 | }, | 756 | }, |
| 875 | macho.S_REGULAR => { | 757 | macho.S_REGULAR => { |
| 876 | if (sect.isCode()) { | 758 | if (sect.isCode()) { |
| | 759 | if (self.text_section_index == null) { |
| | 760 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 761 | try text_seg.addSection(self.allocator, "__text", "__TEXT", .{ |
| | 762 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| | 763 | }); |
| | 764 | } |
| | 765 | |
| 877 | break :blk .{ | 766 | break :blk .{ |
| 878 | .seg = self.text_segment_cmd_index.?, | 767 | .seg = self.text_segment_cmd_index.?, |
| 879 | .sect = self.text_section_index.?, | 768 | .sect = self.text_section_index.?, |
| ... | @@ -881,21 +770,41 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | ... | @@ -881,21 +770,41 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 881 | } | 770 | } |
| 882 | if (sect.isDebug()) { | 771 | if (sect.isDebug()) { |
| 883 | // TODO debug attributes | 772 | // TODO debug attributes |
| | 773 | if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { |
| | 774 | log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ |
| | 775 | sect.flags(), segname, sectname, |
| | 776 | }); |
| | 777 | } |
| 884 | break :blk null; | 778 | break :blk null; |
| 885 | } | 779 | } |
| 886 | | 780 | |
| 887 | if (mem.eql(u8, segname, "__TEXT")) { | 781 | if (mem.eql(u8, segname, "__TEXT")) { |
| 888 | if (mem.eql(u8, sectname, "__ustring")) { | 782 | if (mem.eql(u8, sectname, "__ustring")) { |
| | 783 | if (self.ustring_section_index == null) { |
| | 784 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 785 | try text_seg.addSection(self.allocator, "__ustring", "__TEXT", .{}); |
| | 786 | } |
| | 787 | |
| 889 | break :blk .{ | 788 | break :blk .{ |
| 890 | .seg = self.text_segment_cmd_index.?, | 789 | .seg = self.text_segment_cmd_index.?, |
| 891 | .sect = self.ustring_section_index.?, | 790 | .sect = self.ustring_section_index.?, |
| 892 | }; | 791 | }; |
| 893 | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { | 792 | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { |
| | 793 | if (self.gcc_except_tab_section_index == null) { |
| | 794 | self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 795 | try text_seg.addSection(self.allocator, "__gcc_except_tab", "__TEXT", .{}); |
| | 796 | } |
| | 797 | |
| 894 | break :blk .{ | 798 | break :blk .{ |
| 895 | .seg = self.text_segment_cmd_index.?, | 799 | .seg = self.text_segment_cmd_index.?, |
| 896 | .sect = self.gcc_except_tab_section_index.?, | 800 | .sect = self.gcc_except_tab_section_index.?, |
| 897 | }; | 801 | }; |
| 898 | } else { | 802 | } else { |
| | 803 | if (self.text_const_section_index == null) { |
| | 804 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 805 | try text_seg.addSection(self.allocator, "__const", "__TEXT", .{}); |
| | 806 | } |
| | 807 | |
| 899 | break :blk .{ | 808 | break :blk .{ |
| 900 | .seg = self.text_segment_cmd_index.?, | 809 | .seg = self.text_segment_cmd_index.?, |
| 901 | .sect = self.text_const_section_index.?, | 810 | .sect = self.text_const_section_index.?, |
| ... | @@ -904,6 +813,11 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | ... | @@ -904,6 +813,11 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 904 | } | 813 | } |
| 905 | | 814 | |
| 906 | if (mem.eql(u8, segname, "__DATA_CONST")) { | 815 | if (mem.eql(u8, segname, "__DATA_CONST")) { |
| | 816 | if (self.data_const_section_index == null) { |
| | 817 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 818 | try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{}); |
| | 819 | } |
| | 820 | |
| 907 | break :blk .{ | 821 | break :blk .{ |
| 908 | .seg = self.data_const_segment_cmd_index.?, | 822 | .seg = self.data_const_segment_cmd_index.?, |
| 909 | .sect = self.data_const_section_index.?, | 823 | .sect = self.data_const_section_index.?, |
| ... | @@ -912,20 +826,42 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { | ... | @@ -912,20 +826,42 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) ?MatchingSection { |
| 912 | | 826 | |
| 913 | if (mem.eql(u8, segname, "__DATA")) { | 827 | if (mem.eql(u8, segname, "__DATA")) { |
| 914 | if (mem.eql(u8, sectname, "__const")) { | 828 | if (mem.eql(u8, sectname, "__const")) { |
| | 829 | if (self.data_const_section_index == null) { |
| | 830 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 831 | try data_const_seg.addSection(self.allocator, "__const", "__DATA_CONST", .{}); |
| | 832 | } |
| | 833 | |
| 915 | break :blk .{ | 834 | break :blk .{ |
| 916 | .seg = self.data_const_segment_cmd_index.?, | 835 | .seg = self.data_const_segment_cmd_index.?, |
| 917 | .sect = self.data_const_section_index.?, | 836 | .sect = self.data_const_section_index.?, |
| 918 | }; | 837 | }; |
| 919 | } else if (mem.eql(u8, sectname, "__cfstring")) { | 838 | } else if (mem.eql(u8, sectname, "__cfstring")) { |
| | 839 | if (self.objc_cfstring_section_index == null) { |
| | 840 | self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 841 | try data_const_seg.addSection(self.allocator, "__cfstring", "__DATA_CONST", .{}); |
| | 842 | } |
| | 843 | |
| 920 | break :blk .{ | 844 | break :blk .{ |
| 921 | .seg = self.data_const_segment_cmd_index.?, | 845 | .seg = self.data_const_segment_cmd_index.?, |
| 922 | .sect = self.objc_cfstring_section_index.?, | 846 | .sect = self.objc_cfstring_section_index.?, |
| 923 | }; | 847 | }; |
| | 848 | } else { |
| | 849 | if (self.data_section_index == null) { |
| | 850 | self.data_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 851 | try data_seg.addSection(self.allocator, "__data", "__DATA", .{}); |
| | 852 | } |
| | 853 | |
| | 854 | break :blk .{ |
| | 855 | .seg = self.data_segment_cmd_index.?, |
| | 856 | .sect = self.data_section_index.?, |
| | 857 | }; |
| 924 | } | 858 | } |
| 925 | break :blk .{ | 859 | } |
| 926 | .seg = self.data_segment_cmd_index.?, | 860 | |
| 927 | .sect = self.data_section_index.?, | 861 | if (mem.eql(u8, "__LLVM", segname) and mem.eql(u8, "__asm", sectname)) { |
| 928 | }; | 862 | log.debug("TODO LLVM asm section: type 0x{x}, name '{s},{s}'", .{ |
| | 863 | sect.flags(), segname, sectname, |
| | 864 | }); |
| 929 | } | 865 | } |
| 930 | | 866 | |
| 931 | break :blk null; | 867 | break :blk null; |