| ... | @@ -73,6 +73,11 @@ gcc_except_tab_section_index: ?u16 = null, | ... | @@ -73,6 +73,11 @@ gcc_except_tab_section_index: ?u16 = null, |
| 73 | unwind_info_section_index: ?u16 = null, | 73 | unwind_info_section_index: ?u16 = null, |
| 74 | eh_frame_section_index: ?u16 = null, | 74 | eh_frame_section_index: ?u16 = null, |
| 75 | | 75 | |
| | 76 | objc_methlist_section_index: ?u16 = null, |
| | 77 | objc_methname_section_index: ?u16 = null, |
| | 78 | objc_methtype_section_index: ?u16 = null, |
| | 79 | objc_classname_section_index: ?u16 = null, |
| | 80 | |
| 76 | // __DATA_CONST segment sections | 81 | // __DATA_CONST segment sections |
| 77 | got_section_index: ?u16 = null, | 82 | got_section_index: ?u16 = null, |
| 78 | mod_init_func_section_index: ?u16 = null, | 83 | mod_init_func_section_index: ?u16 = null, |
| ... | @@ -80,6 +85,8 @@ mod_term_func_section_index: ?u16 = null, | ... | @@ -80,6 +85,8 @@ mod_term_func_section_index: ?u16 = null, |
| 80 | data_const_section_index: ?u16 = null, | 85 | data_const_section_index: ?u16 = null, |
| 81 | | 86 | |
| 82 | objc_cfstring_section_index: ?u16 = null, | 87 | objc_cfstring_section_index: ?u16 = null, |
| | 88 | objc_classlist_section_index: ?u16 = null, |
| | 89 | objc_imageinfo_section_index: ?u16 = null, |
| 83 | | 90 | |
| 84 | // __DATA segment sections | 91 | // __DATA segment sections |
| 85 | tlv_section_index: ?u16 = null, | 92 | tlv_section_index: ?u16 = null, |
| ... | @@ -90,6 +97,11 @@ data_section_index: ?u16 = null, | ... | @@ -90,6 +97,11 @@ data_section_index: ?u16 = null, |
| 90 | bss_section_index: ?u16 = null, | 97 | bss_section_index: ?u16 = null, |
| 91 | common_section_index: ?u16 = null, | 98 | common_section_index: ?u16 = null, |
| 92 | | 99 | |
| | 100 | objc_const_section_index: ?u16 = null, |
| | 101 | objc_selrefs_section_index: ?u16 = null, |
| | 102 | objc_classrefs_section_index: ?u16 = null, |
| | 103 | objc_data_section_index: ?u16 = null, |
| | 104 | |
| 93 | globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 105 | globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 94 | imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 106 | imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| 95 | unresolved: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 107 | unresolved: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, |
| ... | @@ -612,7 +624,7 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { | ... | @@ -612,7 +624,7 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { |
| 612 | | 624 | |
| 613 | const res: ?MatchingSection = blk: { | 625 | const res: ?MatchingSection = blk: { |
| 614 | switch (sect.sectionType()) { | 626 | switch (sect.sectionType()) { |
| 615 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS, macho.S_LITERAL_POINTERS => { | 627 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 616 | if (self.text_const_section_index == null) { | 628 | if (self.text_const_section_index == null) { |
| 617 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | 629 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| 618 | try text_seg.addSection(self.allocator, "__const", "__TEXT", .{}); | 630 | try text_seg.addSection(self.allocator, "__const", "__TEXT", .{}); |
| ... | @@ -624,6 +636,44 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { | ... | @@ -624,6 +636,44 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { |
| 624 | }; | 636 | }; |
| 625 | }, | 637 | }, |
| 626 | macho.S_CSTRING_LITERALS => { | 638 | macho.S_CSTRING_LITERALS => { |
| | 639 | if (mem.eql(u8, sectname, "__objc_methname")) { |
| | 640 | // TODO it seems the common values within the sections in objects are deduplicated/merged |
| | 641 | // on merging the sections' contents. |
| | 642 | if (self.objc_methname_section_index == null) { |
| | 643 | self.objc_methname_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 644 | try text_seg.addSection(self.allocator, "__objc_methname", "__TEXT", .{ |
| | 645 | .flags = macho.S_CSTRING_LITERALS, |
| | 646 | }); |
| | 647 | } |
| | 648 | |
| | 649 | break :blk .{ |
| | 650 | .seg = self.text_segment_cmd_index.?, |
| | 651 | .sect = self.objc_methname_section_index.?, |
| | 652 | }; |
| | 653 | } else if (mem.eql(u8, sectname, "__objc_methtype")) { |
| | 654 | if (self.objc_methtype_section_index == null) { |
| | 655 | self.objc_methtype_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 656 | try text_seg.addSection(self.allocator, "__objc_methtype", "__TEXT", .{ |
| | 657 | .flags = macho.S_CSTRING_LITERALS, |
| | 658 | }); |
| | 659 | } |
| | 660 | |
| | 661 | break :blk .{ |
| | 662 | .seg = self.text_segment_cmd_index.?, |
| | 663 | .sect = self.objc_methtype_section_index.?, |
| | 664 | }; |
| | 665 | } else if (mem.eql(u8, sectname, "__objc_classname")) { |
| | 666 | if (self.objc_classname_section_index == null) { |
| | 667 | self.objc_classname_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 668 | try text_seg.addSection(self.allocator, "__objc_classname", "__TEXT", .{}); |
| | 669 | } |
| | 670 | |
| | 671 | break :blk .{ |
| | 672 | .seg = self.text_segment_cmd_index.?, |
| | 673 | .sect = self.objc_classname_section_index.?, |
| | 674 | }; |
| | 675 | } |
| | 676 | |
| 627 | if (self.cstring_section_index == null) { | 677 | if (self.cstring_section_index == null) { |
| 628 | self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); | 678 | self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); |
| 629 | try text_seg.addSection(self.allocator, "__cstring", "__TEXT", .{ | 679 | try text_seg.addSection(self.allocator, "__cstring", "__TEXT", .{ |
| ... | @@ -636,6 +686,24 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { | ... | @@ -636,6 +686,24 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { |
| 636 | .sect = self.cstring_section_index.?, | 686 | .sect = self.cstring_section_index.?, |
| 637 | }; | 687 | }; |
| 638 | }, | 688 | }, |
| | 689 | macho.S_LITERAL_POINTERS => { |
| | 690 | if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__objc_selrefs")) { |
| | 691 | if (self.objc_selrefs_section_index == null) { |
| | 692 | self.objc_selrefs_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 693 | try data_seg.addSection(self.allocator, "__objc_selrefs", "__DATA", .{ |
| | 694 | .flags = macho.S_LITERAL_POINTERS, |
| | 695 | }); |
| | 696 | } |
| | 697 | |
| | 698 | break :blk .{ |
| | 699 | .seg = self.data_segment_cmd_index.?, |
| | 700 | .sect = self.objc_selrefs_section_index.?, |
| | 701 | }; |
| | 702 | } |
| | 703 | |
| | 704 | // TODO investigate |
| | 705 | break :blk null; |
| | 706 | }, |
| 639 | macho.S_MOD_INIT_FUNC_POINTERS => { | 707 | macho.S_MOD_INIT_FUNC_POINTERS => { |
| 640 | if (self.mod_init_func_section_index == null) { | 708 | if (self.mod_init_func_section_index == null) { |
| 641 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); | 709 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| ... | @@ -799,6 +867,16 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { | ... | @@ -799,6 +867,16 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { |
| 799 | .seg = self.text_segment_cmd_index.?, | 867 | .seg = self.text_segment_cmd_index.?, |
| 800 | .sect = self.gcc_except_tab_section_index.?, | 868 | .sect = self.gcc_except_tab_section_index.?, |
| 801 | }; | 869 | }; |
| | 870 | } else if (mem.eql(u8, sectname, "__objc_methlist")) { |
| | 871 | if (self.objc_methlist_section_index == null) { |
| | 872 | self.objc_methlist_section_index = @intCast(u16, text_seg.sections.items.len); |
| | 873 | try text_seg.addSection(self.allocator, "__objc_methlist", "__TEXT", .{}); |
| | 874 | } |
| | 875 | |
| | 876 | break :blk .{ |
| | 877 | .seg = self.text_segment_cmd_index.?, |
| | 878 | .sect = self.objc_methlist_section_index.?, |
| | 879 | }; |
| 802 | } else { | 880 | } else { |
| 803 | if (self.text_const_section_index == null) { | 881 | if (self.text_const_section_index == null) { |
| 804 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | 882 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| ... | @@ -845,6 +923,56 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { | ... | @@ -845,6 +923,56 @@ fn getMatchingSection(self: *Zld, sect: Object.Section) !?MatchingSection { |
| 845 | .seg = self.data_const_segment_cmd_index.?, | 923 | .seg = self.data_const_segment_cmd_index.?, |
| 846 | .sect = self.objc_cfstring_section_index.?, | 924 | .sect = self.objc_cfstring_section_index.?, |
| 847 | }; | 925 | }; |
| | 926 | } else if (mem.eql(u8, sectname, "__objc_classlist")) { |
| | 927 | if (self.objc_classlist_section_index == null) { |
| | 928 | self.objc_classlist_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 929 | try data_const_seg.addSection(self.allocator, "__objc_classlist", "__DATA_CONST", .{}); |
| | 930 | } |
| | 931 | |
| | 932 | break :blk .{ |
| | 933 | .seg = self.data_const_segment_cmd_index.?, |
| | 934 | .sect = self.objc_classlist_section_index.?, |
| | 935 | }; |
| | 936 | } else if (mem.eql(u8, sectname, "__objc_imageinfo")) { |
| | 937 | if (self.objc_imageinfo_section_index == null) { |
| | 938 | self.objc_imageinfo_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| | 939 | try data_const_seg.addSection(self.allocator, "__objc_imageinfo", "__DATA_CONST", .{}); |
| | 940 | } |
| | 941 | |
| | 942 | break :blk .{ |
| | 943 | .seg = self.data_const_segment_cmd_index.?, |
| | 944 | .sect = self.objc_imageinfo_section_index.?, |
| | 945 | }; |
| | 946 | } else if (mem.eql(u8, sectname, "__objc_const")) { |
| | 947 | if (self.objc_const_section_index == null) { |
| | 948 | self.objc_const_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 949 | try data_seg.addSection(self.allocator, "__objc_const", "__DATA", .{}); |
| | 950 | } |
| | 951 | |
| | 952 | break :blk .{ |
| | 953 | .seg = self.data_segment_cmd_index.?, |
| | 954 | .sect = self.objc_const_section_index.?, |
| | 955 | }; |
| | 956 | } else if (mem.eql(u8, sectname, "__objc_classrefs")) { |
| | 957 | if (self.objc_classrefs_section_index == null) { |
| | 958 | self.objc_classrefs_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 959 | try data_seg.addSection(self.allocator, "__objc_classrefs", "__DATA", .{}); |
| | 960 | } |
| | 961 | |
| | 962 | break :blk .{ |
| | 963 | .seg = self.data_segment_cmd_index.?, |
| | 964 | .sect = self.objc_classrefs_section_index.?, |
| | 965 | }; |
| | 966 | } else if (mem.eql(u8, sectname, "__objc_data")) { |
| | 967 | if (self.objc_data_section_index == null) { |
| | 968 | self.objc_data_section_index = @intCast(u16, data_seg.sections.items.len); |
| | 969 | try data_seg.addSection(self.allocator, "__objc_data", "__DATA", .{}); |
| | 970 | } |
| | 971 | |
| | 972 | break :blk .{ |
| | 973 | .seg = self.data_segment_cmd_index.?, |
| | 974 | .sect = self.objc_data_section_index.?, |
| | 975 | }; |
| 848 | } else { | 976 | } else { |
| 849 | if (self.data_section_index == null) { | 977 | if (self.data_section_index == null) { |
| 850 | self.data_section_index = @intCast(u16, data_seg.sections.items.len); | 978 | self.data_section_index = @intCast(u16, data_seg.sections.items.len); |
| ... | @@ -896,6 +1024,9 @@ fn sortSections(self: *Zld) !void { | ... | @@ -896,6 +1024,9 @@ fn sortSections(self: *Zld) !void { |
| 896 | &self.cstring_section_index, | 1024 | &self.cstring_section_index, |
| 897 | &self.ustring_section_index, | 1025 | &self.ustring_section_index, |
| 898 | &self.text_const_section_index, | 1026 | &self.text_const_section_index, |
| | 1027 | &self.objc_methname_section_index, |
| | 1028 | &self.objc_methtype_section_index, |
| | 1029 | &self.objc_classname_section_index, |
| 899 | &self.eh_frame_section_index, | 1030 | &self.eh_frame_section_index, |
| 900 | }; | 1031 | }; |
| 901 | for (indices) |maybe_index| { | 1032 | for (indices) |maybe_index| { |
| ... | @@ -922,6 +1053,8 @@ fn sortSections(self: *Zld) !void { | ... | @@ -922,6 +1053,8 @@ fn sortSections(self: *Zld) !void { |
| 922 | &self.mod_term_func_section_index, | 1053 | &self.mod_term_func_section_index, |
| 923 | &self.data_const_section_index, | 1054 | &self.data_const_section_index, |
| 924 | &self.objc_cfstring_section_index, | 1055 | &self.objc_cfstring_section_index, |
| | 1056 | &self.objc_classlist_section_index, |
| | 1057 | &self.objc_imageinfo_section_index, |
| 925 | }; | 1058 | }; |
| 926 | for (indices) |maybe_index| { | 1059 | for (indices) |maybe_index| { |
| 927 | const new_index: u16 = if (maybe_index.*) |index| blk: { | 1060 | const new_index: u16 = if (maybe_index.*) |index| blk: { |
| ... | @@ -944,6 +1077,10 @@ fn sortSections(self: *Zld) !void { | ... | @@ -944,6 +1077,10 @@ fn sortSections(self: *Zld) !void { |
| 944 | // __DATA segment | 1077 | // __DATA segment |
| 945 | const indices = &[_]*?u16{ | 1078 | const indices = &[_]*?u16{ |
| 946 | &self.la_symbol_ptr_section_index, | 1079 | &self.la_symbol_ptr_section_index, |
| | 1080 | &self.objc_const_section_index, |
| | 1081 | &self.objc_selrefs_section_index, |
| | 1082 | &self.objc_classrefs_section_index, |
| | 1083 | &self.objc_data_section_index, |
| 947 | &self.data_section_index, | 1084 | &self.data_section_index, |
| 948 | &self.tlv_section_index, | 1085 | &self.tlv_section_index, |
| 949 | &self.tlv_data_section_index, | 1086 | &self.tlv_data_section_index, |