| author | |
| committer | |
| log | 42e0850d78e63fcc602dd0e167ac90dfb3cfec02 |
| tree | 62cbed417608fcffc6c7ef4f3bda6045d067f00a |
| parent | 84853c5c56e87a7ee6c5392756b0773b650d283c |
6 files changed, 105 insertions(+), 33 deletions(-)
src/link/MachO.zig+9-4| ... | @@ -33,14 +33,19 @@ data_segment_cmd_index: ?u8 = null, | ... | @@ -33,14 +33,19 @@ data_segment_cmd_index: ?u8 = null, |
| 33 | linkedit_segment_cmd_index: ?u8 = null, | 33 | linkedit_segment_cmd_index: ?u8 = null, |
| 34 | 34 | ||
| 35 | text_section_index: ?u8 = null, | 35 | text_section_index: ?u8 = null, |
| 36 | stubs_section_index: ?u8 = null, | ||
| 37 | stub_helper_section_index: ?u8 = null, | ||
| 38 | got_section_index: ?u8 = null, | ||
| 39 | data_const_section_index: ?u8 = null, | 36 | data_const_section_index: ?u8 = null, |
| 40 | la_symbol_ptr_section_index: ?u8 = null, | ||
| 41 | data_section_index: ?u8 = null, | 37 | data_section_index: ?u8 = null, |
| 38 | bss_section_index: ?u8 = null, | ||
| 42 | thread_vars_section_index: ?u8 = null, | 39 | thread_vars_section_index: ?u8 = null, |
| 43 | thread_data_section_index: ?u8 = null, | 40 | thread_data_section_index: ?u8 = null, |
| 41 | thread_bss_section_index: ?u8 = null, | ||
| 42 | eh_frame_section_index: ?u8 = null, | ||
| 43 | unwind_info_section_index: ?u8 = null, | ||
| 44 | stubs_section_index: ?u8 = null, | ||
| 45 | stub_helper_section_index: ?u8 = null, | ||
| 46 | got_section_index: ?u8 = null, | ||
| 47 | la_symbol_ptr_section_index: ?u8 = null, | ||
| 48 | tlv_ptr_section_index: ?u8 = null, | ||
| 44 | 49 | ||
| 45 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, | 50 | locals: std.ArrayListUnmanaged(macho.nlist_64) = .{}, |
| 46 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, | 51 | globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{}, |
src/link/MachO/Atom.zig+41-9| ... | @@ -244,13 +244,16 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { | ... | @@ -244,13 +244,16 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 244 | .{}, | 244 | .{}, |
| 245 | ); | 245 | ); |
| 246 | } else if (mem.eql(u8, sectname, "__data")) { | 246 | } else if (mem.eql(u8, sectname, "__data")) { |
| 247 | break :blk zld.getSectionByName("__DATA", "__data") orelse try MachO.initSection( | 247 | if (zld.data_section_index == null) { |
| 248 | gpa, | 248 | zld.data_section_index = try MachO.initSection( |
| 249 | zld, | 249 | gpa, |
| 250 | "__DATA", | 250 | zld, |
| 251 | "__data", | 251 | "__DATA", |
| 252 | .{}, | 252 | "__data", |
| 253 | ); | 253 | .{}, |
| 254 | ); | ||
| 255 | } | ||
| 256 | break :blk zld.data_section_index.?; | ||
| 254 | } | 257 | } |
| 255 | } | 258 | } |
| 256 | break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection( | 259 | break :blk zld.getSectionByName(segname, sectname) orelse try MachO.initSection( |
| ... | @@ -264,6 +267,35 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { | ... | @@ -264,6 +267,35 @@ pub fn getOutputSection(zld: *Zld, sect: macho.section_64) !?u8 { |
| 264 | else => break :blk null, | 267 | else => break :blk null, |
| 265 | } | 268 | } |
| 266 | }; | 269 | }; |
| 270 | |||
| 271 | // TODO we can do this directly in the selection logic above. | ||
| 272 | // Or is it not worth it? | ||
| 273 | if (zld.data_const_section_index == null) { | ||
| 274 | if (zld.getSectionByName("__DATA_CONST", "__const")) |index| { | ||
| 275 | zld.data_const_section_index = index; | ||
| 276 | } | ||
| 277 | } | ||
| 278 | if (zld.thread_vars_section_index == null) { | ||
| 279 | if (zld.getSectionByName("__DATA", "__thread_vars")) |index| { | ||
| 280 | zld.thread_vars_section_index = index; | ||
| 281 | } | ||
| 282 | } | ||
| 283 | if (zld.thread_data_section_index == null) { | ||
| 284 | if (zld.getSectionByName("__DATA", "__thread_data")) |index| { | ||
| 285 | zld.thread_data_section_index = index; | ||
| 286 | } | ||
| 287 | } | ||
| 288 | if (zld.thread_bss_section_index == null) { | ||
| 289 | if (zld.getSectionByName("__DATA", "__thread_bss")) |index| { | ||
| 290 | zld.thread_bss_section_index = index; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | if (zld.bss_section_index == null) { | ||
| 294 | if (zld.getSectionByName("__DATA", "__bss")) |index| { | ||
| 295 | zld.bss_section_index = index; | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 267 | return res; | 299 | return res; |
| 268 | } | 300 | } |
| 269 | 301 | ||
| ... | @@ -662,9 +694,9 @@ pub fn getRelocTargetAddress(zld: *Zld, target: SymbolWithLoc, is_tlv: bool) !u6 | ... | @@ -662,9 +694,9 @@ pub fn getRelocTargetAddress(zld: *Zld, target: SymbolWithLoc, is_tlv: bool) !u6 |
| 662 | // * wrt to __thread_data if defined, then | 694 | // * wrt to __thread_data if defined, then |
| 663 | // * wrt to __thread_bss | 695 | // * wrt to __thread_bss |
| 664 | const sect_id: u16 = sect_id: { | 696 | const sect_id: u16 = sect_id: { |
| 665 | if (zld.getSectionByName("__DATA", "__thread_data")) |i| { | 697 | if (zld.thread_data_section_index) |i| { |
| 666 | break :sect_id i; | 698 | break :sect_id i; |
| 667 | } else if (zld.getSectionByName("__DATA", "__thread_bss")) |i| { | 699 | } else if (zld.thread_bss_section_index) |i| { |
| 668 | break :sect_id i; | 700 | break :sect_id i; |
| 669 | } else { | 701 | } else { |
| 670 | log.err("threadlocal variables present but no initializer sections found", .{}); | 702 | log.err("threadlocal variables present but no initializer sections found", .{}); |
src/link/MachO/Object.zig+12-6| ... | @@ -687,8 +687,8 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void { | ... | @@ -687,8 +687,8 @@ fn parseEhFrameSection(self: *Object, zld: *Zld, object_id: u32) !void { |
| 687 | 687 | ||
| 688 | const gpa = zld.gpa; | 688 | const gpa = zld.gpa; |
| 689 | 689 | ||
| 690 | if (zld.getSectionByName("__TEXT", "__eh_frame") == null) { | 690 | if (zld.eh_frame_section_index == null) { |
| 691 | _ = try MachO.initSection(gpa, zld, "__TEXT", "__eh_frame", .{}); | 691 | zld.eh_frame_section_index = try MachO.initSection(gpa, zld, "__TEXT", "__eh_frame", .{}); |
| 692 | } | 692 | } |
| 693 | 693 | ||
| 694 | const cpu_arch = zld.options.target.cpu.arch; | 694 | const cpu_arch = zld.options.target.cpu.arch; |
| ... | @@ -788,8 +788,14 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { | ... | @@ -788,8 +788,14 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { |
| 788 | // approach. However, we will only synthesise DWARF records and nothing more. For this reason, | 788 | // approach. However, we will only synthesise DWARF records and nothing more. For this reason, |
| 789 | // we still create the output `__TEXT,__unwind_info` section. | 789 | // we still create the output `__TEXT,__unwind_info` section. |
| 790 | if (self.hasEhFrameRecords()) { | 790 | if (self.hasEhFrameRecords()) { |
| 791 | if (zld.getSectionByName("__TEXT", "__unwind_info") == null) { | 791 | if (zld.unwind_info_section_index == null) { |
| 792 | _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{}); | 792 | zld.unwind_info_section_index = try MachO.initSection( |
| 793 | gpa, | ||
| 794 | zld, | ||
| 795 | "__TEXT", | ||
| 796 | "__unwind_info", | ||
| 797 | .{}, | ||
| 798 | ); | ||
| 793 | } | 799 | } |
| 794 | } | 800 | } |
| 795 | return; | 801 | return; |
| ... | @@ -797,8 +803,8 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { | ... | @@ -797,8 +803,8 @@ fn parseUnwindInfo(self: *Object, zld: *Zld, object_id: u32) !void { |
| 797 | 803 | ||
| 798 | log.debug("parsing unwind info in {s}", .{self.name}); | 804 | log.debug("parsing unwind info in {s}", .{self.name}); |
| 799 | 805 | ||
| 800 | if (zld.getSectionByName("__TEXT", "__unwind_info") == null) { | 806 | if (zld.unwind_info_section_index == null) { |
| 801 | _ = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{}); | 807 | zld.unwind_info_section_index = try MachO.initSection(gpa, zld, "__TEXT", "__unwind_info", .{}); |
| 802 | } | 808 | } |
| 803 | 809 | ||
| 804 | const unwind_records = self.getUnwindRecords(); | 810 | const unwind_records = self.getUnwindRecords(); |
src/link/MachO/UnwindInfo.zig+4-4| ... | @@ -204,7 +204,7 @@ pub fn deinit(info: *UnwindInfo) void { | ... | @@ -204,7 +204,7 @@ pub fn deinit(info: *UnwindInfo) void { |
| 204 | } | 204 | } |
| 205 | 205 | ||
| 206 | pub fn scanRelocs(zld: *Zld) !void { | 206 | pub fn scanRelocs(zld: *Zld) !void { |
| 207 | if (zld.getSectionByName("__TEXT", "__unwind_info") == null) return; | 207 | if (zld.unwind_info_section_index == null) return; |
| 208 | 208 | ||
| 209 | const cpu_arch = zld.options.target.cpu.arch; | 209 | const cpu_arch = zld.options.target.cpu.arch; |
| 210 | for (zld.objects.items, 0..) |*object, object_id| { | 210 | for (zld.objects.items, 0..) |*object, object_id| { |
| ... | @@ -233,7 +233,7 @@ pub fn scanRelocs(zld: *Zld) !void { | ... | @@ -233,7 +233,7 @@ pub fn scanRelocs(zld: *Zld) !void { |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | pub fn collect(info: *UnwindInfo, zld: *Zld) !void { | 235 | pub fn collect(info: *UnwindInfo, zld: *Zld) !void { |
| 236 | if (zld.getSectionByName("__TEXT", "__unwind_info") == null) return; | 236 | if (zld.unwind_info_section_index == null) return; |
| 237 | 237 | ||
| 238 | const cpu_arch = zld.options.target.cpu.arch; | 238 | const cpu_arch = zld.options.target.cpu.arch; |
| 239 | 239 | ||
| ... | @@ -551,7 +551,7 @@ fn collectPersonalityFromDwarf( | ... | @@ -551,7 +551,7 @@ fn collectPersonalityFromDwarf( |
| 551 | } | 551 | } |
| 552 | 552 | ||
| 553 | pub fn calcSectionSize(info: UnwindInfo, zld: *Zld) !void { | 553 | pub fn calcSectionSize(info: UnwindInfo, zld: *Zld) !void { |
| 554 | const sect_id = zld.getSectionByName("__TEXT", "__unwind_info") orelse return; | 554 | const sect_id = zld.unwind_info_section_index orelse return; |
| 555 | const sect = &zld.sections.items(.header)[sect_id]; | 555 | const sect = &zld.sections.items(.header)[sect_id]; |
| 556 | sect.@"align" = 2; | 556 | sect.@"align" = 2; |
| 557 | sect.size = info.calcRequiredSize(); | 557 | sect.size = info.calcRequiredSize(); |
| ... | @@ -570,7 +570,7 @@ fn calcRequiredSize(info: UnwindInfo) usize { | ... | @@ -570,7 +570,7 @@ fn calcRequiredSize(info: UnwindInfo) usize { |
| 570 | } | 570 | } |
| 571 | 571 | ||
| 572 | pub fn write(info: *UnwindInfo, zld: *Zld) !void { | 572 | pub fn write(info: *UnwindInfo, zld: *Zld) !void { |
| 573 | const sect_id = zld.getSectionByName("__TEXT", "__unwind_info") orelse return; | 573 | const sect_id = zld.unwind_info_section_index orelse return; |
| 574 | const sect = &zld.sections.items(.header)[sect_id]; | 574 | const sect = &zld.sections.items(.header)[sect_id]; |
| 575 | const seg_id = zld.sections.items(.segment_index)[sect_id]; | 575 | const seg_id = zld.sections.items(.segment_index)[sect_id]; |
| 576 | const seg = zld.segments.items[seg_id]; | 576 | const seg = zld.segments.items[seg_id]; |
src/link/MachO/eh_frame.zig+2-2| ... | @@ -46,7 +46,7 @@ pub fn scanRelocs(zld: *Zld) !void { | ... | @@ -46,7 +46,7 @@ pub fn scanRelocs(zld: *Zld) !void { |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | pub fn calcSectionSize(zld: *Zld, unwind_info: *const UnwindInfo) !void { | 48 | pub fn calcSectionSize(zld: *Zld, unwind_info: *const UnwindInfo) !void { |
| 49 | const sect_id = zld.getSectionByName("__TEXT", "__eh_frame") orelse return; | 49 | const sect_id = zld.eh_frame_section_index orelse return; |
| 50 | const sect = &zld.sections.items(.header)[sect_id]; | 50 | const sect = &zld.sections.items(.header)[sect_id]; |
| 51 | sect.@"align" = 3; | 51 | sect.@"align" = 3; |
| 52 | sect.size = 0; | 52 | sect.size = 0; |
| ... | @@ -97,7 +97,7 @@ pub fn calcSectionSize(zld: *Zld, unwind_info: *const UnwindInfo) !void { | ... | @@ -97,7 +97,7 @@ pub fn calcSectionSize(zld: *Zld, unwind_info: *const UnwindInfo) !void { |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | pub fn write(zld: *Zld, unwind_info: *UnwindInfo) !void { | 99 | pub fn write(zld: *Zld, unwind_info: *UnwindInfo) !void { |
| 100 | const sect_id = zld.getSectionByName("__TEXT", "__eh_frame") orelse return; | 100 | const sect_id = zld.eh_frame_section_index orelse return; |
| 101 | const sect = zld.sections.items(.header)[sect_id]; | 101 | const sect = zld.sections.items(.header)[sect_id]; |
| 102 | const seg_id = zld.sections.items(.segment_index)[sect_id]; | 102 | const seg_id = zld.sections.items(.segment_index)[sect_id]; |
| 103 | const seg = zld.segments.items[seg_id]; | 103 | const seg = zld.segments.items[seg_id]; |
src/link/MachO/zld.zig+37-8| ... | @@ -74,6 +74,14 @@ pub const Zld = struct { | ... | @@ -74,6 +74,14 @@ pub const Zld = struct { |
| 74 | linkedit_segment_cmd_index: ?u8 = null, | 74 | linkedit_segment_cmd_index: ?u8 = null, |
| 75 | 75 | ||
| 76 | text_section_index: ?u8 = null, | 76 | text_section_index: ?u8 = null, |
| 77 | data_const_section_index: ?u8 = null, | ||
| 78 | data_section_index: ?u8 = null, | ||
| 79 | bss_section_index: ?u8 = null, | ||
| 80 | thread_vars_section_index: ?u8 = null, | ||
| 81 | thread_data_section_index: ?u8 = null, | ||
| 82 | thread_bss_section_index: ?u8 = null, | ||
| 83 | eh_frame_section_index: ?u8 = null, | ||
| 84 | unwind_info_section_index: ?u8 = null, | ||
| 77 | got_section_index: ?u8 = null, | 85 | got_section_index: ?u8 = null, |
| 78 | tlv_ptr_section_index: ?u8 = null, | 86 | tlv_ptr_section_index: ?u8 = null, |
| 79 | stubs_section_index: ?u8 = null, | 87 | stubs_section_index: ?u8 = null, |
| ... | @@ -142,9 +150,10 @@ pub const Zld = struct { | ... | @@ -142,9 +150,10 @@ pub const Zld = struct { |
| 142 | const sym = self.getSymbolPtr(.{ .sym_index = sym_index }); | 150 | const sym = self.getSymbolPtr(.{ .sym_index = sym_index }); |
| 143 | sym.n_type = macho.N_SECT; | 151 | sym.n_type = macho.N_SECT; |
| 144 | 152 | ||
| 145 | const sect_id = self.getSectionByName("__DATA", "__data") orelse | 153 | if (self.data_section_index == null) { |
| 146 | try MachO.initSection(self.gpa, self, "__DATA", "__data", .{}); | 154 | self.data_section_index = try MachO.initSection(self.gpa, self, "__DATA", "__data", .{}); |
| 147 | sym.n_sect = sect_id + 1; | 155 | } |
| 156 | sym.n_sect = self.data_section_index.? + 1; | ||
| 148 | self.dyld_private_atom_index = atom_index; | 157 | self.dyld_private_atom_index = atom_index; |
| 149 | 158 | ||
| 150 | self.addAtomToSection(atom_index); | 159 | self.addAtomToSection(atom_index); |
| ... | @@ -166,13 +175,17 @@ pub const Zld = struct { | ... | @@ -166,13 +175,17 @@ pub const Zld = struct { |
| 166 | // text blocks for each tentative definition. | 175 | // text blocks for each tentative definition. |
| 167 | const size = sym.n_value; | 176 | const size = sym.n_value; |
| 168 | const alignment = (sym.n_desc >> 8) & 0x0f; | 177 | const alignment = (sym.n_desc >> 8) & 0x0f; |
| 169 | const sect_id = self.getSectionByName("__DATA", "__bss") orelse | 178 | |
| 170 | try MachO.initSection(gpa, self, "__DATA", "__bss", .{ .flags = macho.S_ZEROFILL }); | 179 | if (self.bss_section_index == null) { |
| 180 | self.bss_section_index = try MachO.initSection(gpa, self, "__DATA", "__bss", .{ | ||
| 181 | .flags = macho.S_ZEROFILL, | ||
| 182 | }); | ||
| 183 | } | ||
| 171 | 184 | ||
| 172 | sym.* = .{ | 185 | sym.* = .{ |
| 173 | .n_strx = sym.n_strx, | 186 | .n_strx = sym.n_strx, |
| 174 | .n_type = macho.N_SECT | macho.N_EXT, | 187 | .n_type = macho.N_SECT | macho.N_EXT, |
| 175 | .n_sect = sect_id + 1, | 188 | .n_sect = self.bss_section_index.? + 1, |
| 176 | .n_desc = 0, | 189 | .n_desc = 0, |
| 177 | .n_value = 0, | 190 | .n_value = 0, |
| 178 | }; | 191 | }; |
| ... | @@ -768,7 +781,7 @@ pub const Zld = struct { | ... | @@ -768,7 +781,7 @@ pub const Zld = struct { |
| 768 | const atom_index = self.dyld_private_atom_index orelse return; | 781 | const atom_index = self.dyld_private_atom_index orelse return; |
| 769 | const atom = self.getAtom(atom_index); | 782 | const atom = self.getAtom(atom_index); |
| 770 | const sym = self.getSymbol(atom.getSymbolWithLoc()); | 783 | const sym = self.getSymbol(atom.getSymbolWithLoc()); |
| 771 | const sect_id = self.getSectionByName("__DATA", "__data").?; | 784 | const sect_id = self.data_section_index.?; |
| 772 | const header = self.sections.items(.header)[sect_id]; | 785 | const header = self.sections.items(.header)[sect_id]; |
| 773 | const offset = sym.n_value - header.addr + header.offset; | 786 | const offset = sym.n_value - header.addr + header.offset; |
| 774 | log.debug("writing __dyld_private at offset 0x{x}", .{offset}); | 787 | log.debug("writing __dyld_private at offset 0x{x}", .{offset}); |
| ... | @@ -918,6 +931,14 @@ pub const Zld = struct { | ... | @@ -918,6 +931,14 @@ pub const Zld = struct { |
| 918 | }); | 931 | }); |
| 919 | for (&[_]*?u8{ | 932 | for (&[_]*?u8{ |
| 920 | &self.text_section_index, | 933 | &self.text_section_index, |
| 934 | &self.data_const_section_index, | ||
| 935 | &self.data_section_index, | ||
| 936 | &self.bss_section_index, | ||
| 937 | &self.thread_vars_section_index, | ||
| 938 | &self.thread_data_section_index, | ||
| 939 | &self.thread_bss_section_index, | ||
| 940 | &self.eh_frame_section_index, | ||
| 941 | &self.unwind_info_section_index, | ||
| 921 | &self.got_section_index, | 942 | &self.got_section_index, |
| 922 | &self.tlv_ptr_section_index, | 943 | &self.tlv_ptr_section_index, |
| 923 | &self.stubs_section_index, | 944 | &self.stubs_section_index, |
| ... | @@ -951,6 +972,14 @@ pub const Zld = struct { | ... | @@ -951,6 +972,14 @@ pub const Zld = struct { |
| 951 | 972 | ||
| 952 | for (&[_]*?u8{ | 973 | for (&[_]*?u8{ |
| 953 | &self.text_section_index, | 974 | &self.text_section_index, |
| 975 | &self.data_const_section_index, | ||
| 976 | &self.data_section_index, | ||
| 977 | &self.bss_section_index, | ||
| 978 | &self.thread_vars_section_index, | ||
| 979 | &self.thread_data_section_index, | ||
| 980 | &self.thread_bss_section_index, | ||
| 981 | &self.eh_frame_section_index, | ||
| 982 | &self.unwind_info_section_index, | ||
| 954 | &self.got_section_index, | 983 | &self.got_section_index, |
| 955 | &self.tlv_ptr_section_index, | 984 | &self.tlv_ptr_section_index, |
| 956 | &self.stubs_section_index, | 985 | &self.stubs_section_index, |
| ... | @@ -1964,7 +1993,7 @@ pub const Zld = struct { | ... | @@ -1964,7 +1993,7 @@ pub const Zld = struct { |
| 1964 | else => unreachable, | 1993 | else => unreachable, |
| 1965 | } | 1994 | } |
| 1966 | 1995 | ||
| 1967 | if (self.getSectionByName("__DATA", "__thread_vars")) |sect_id| { | 1996 | if (self.thread_vars_section_index) |sect_id| { |
| 1968 | header.flags |= macho.MH_HAS_TLV_DESCRIPTORS; | 1997 | header.flags |= macho.MH_HAS_TLV_DESCRIPTORS; |
| 1969 | if (self.sections.items(.header)[sect_id].size > 0) { | 1998 | if (self.sections.items(.header)[sect_id].size > 0) { |
| 1970 | header.flags |= macho.MH_HAS_TLV_DESCRIPTORS; | 1999 | header.flags |= macho.MH_HAS_TLV_DESCRIPTORS; |