authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-21 14:16:10+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2021-06-24 18:56:09+02:00
loga480ae6e37199a3b210a4029f3d3c728e959a21d
treed68a2ef6eac3d64af9adf990dc985bd8ed698592
parent5f9b4cba6da9540d5a2fd03d9b379d0b7eb5937d

zld: handle objc-specific sections


1 files changed, 138 insertions(+), 1 deletions(-)

src/link/MachO/Zld.zig+138-1
...@@ -73,6 +73,11 @@ gcc_except_tab_section_index: ?u16 = null,...@@ -73,6 +73,11 @@ gcc_except_tab_section_index: ?u16 = null,
73unwind_info_section_index: ?u16 = null,73unwind_info_section_index: ?u16 = null,
74eh_frame_section_index: ?u16 = null,74eh_frame_section_index: ?u16 = null,
7575
76objc_methlist_section_index: ?u16 = null,
77objc_methname_section_index: ?u16 = null,
78objc_methtype_section_index: ?u16 = null,
79objc_classname_section_index: ?u16 = null,
80
76// __DATA_CONST segment sections81// __DATA_CONST segment sections
77got_section_index: ?u16 = null,82got_section_index: ?u16 = null,
78mod_init_func_section_index: ?u16 = null,83mod_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,
80data_const_section_index: ?u16 = null,85data_const_section_index: ?u16 = null,
8186
82objc_cfstring_section_index: ?u16 = null,87objc_cfstring_section_index: ?u16 = null,
88objc_classlist_section_index: ?u16 = null,
89objc_imageinfo_section_index: ?u16 = null,
8390
84// __DATA segment sections91// __DATA segment sections
85tlv_section_index: ?u16 = null,92tlv_section_index: ?u16 = null,
...@@ -90,6 +97,11 @@ data_section_index: ?u16 = null,...@@ -90,6 +97,11 @@ data_section_index: ?u16 = null,
90bss_section_index: ?u16 = null,97bss_section_index: ?u16 = null,
91common_section_index: ?u16 = null,98common_section_index: ?u16 = null,
9299
100objc_const_section_index: ?u16 = null,
101objc_selrefs_section_index: ?u16 = null,
102objc_classrefs_section_index: ?u16 = null,
103objc_data_section_index: ?u16 = null,
104
93globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{},105globals: std.StringArrayHashMapUnmanaged(*Symbol) = .{},
94imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{},106imports: std.StringArrayHashMapUnmanaged(*Symbol) = .{},
95unresolved: std.StringArrayHashMapUnmanaged(*Symbol) = .{},107unresolved: 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 {
612624
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 segment1077 // __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,