authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-27 07:31:29+02:00
committergravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2023-08-29 11:39:35+02:00
log42e0850d78e63fcc602dd0e167ac90dfb3cfec02
tree62cbed417608fcffc6c7ef4f3bda6045d067f00a
parent84853c5c56e87a7ee6c5392756b0773b650d283c

macho: save indexes to all sections of interest


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,
33linkedit_segment_cmd_index: ?u8 = null,33linkedit_segment_cmd_index: ?u8 = null,
3434
35text_section_index: ?u8 = null,35text_section_index: ?u8 = null,
36stubs_section_index: ?u8 = null,
37stub_helper_section_index: ?u8 = null,
38got_section_index: ?u8 = null,
39data_const_section_index: ?u8 = null,36data_const_section_index: ?u8 = null,
40la_symbol_ptr_section_index: ?u8 = null,
41data_section_index: ?u8 = null,37data_section_index: ?u8 = null,
38bss_section_index: ?u8 = null,
42thread_vars_section_index: ?u8 = null,39thread_vars_section_index: ?u8 = null,
43thread_data_section_index: ?u8 = null,40thread_data_section_index: ?u8 = null,
41thread_bss_section_index: ?u8 = null,
42eh_frame_section_index: ?u8 = null,
43unwind_info_section_index: ?u8 = null,
44stubs_section_index: ?u8 = null,
45stub_helper_section_index: ?u8 = null,
46got_section_index: ?u8 = null,
47la_symbol_ptr_section_index: ?u8 = null,
48tlv_ptr_section_index: ?u8 = null,
4449
45locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},50locals: std.ArrayListUnmanaged(macho.nlist_64) = .{},
46globals: std.ArrayListUnmanaged(SymbolWithLoc) = .{},51globals: 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}
269301
...@@ -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, then694 // * wrt to __thread_data if defined, then
663 // * wrt to __thread_bss695 // * 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 {
687687
688 const gpa = zld.gpa;688 const gpa = zld.gpa;
689689
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 }
693693
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 {
797803
798 log.debug("parsing unwind info in {s}", .{self.name});804 log.debug("parsing unwind info in {s}", .{self.name});
799805
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 }
803809
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}
205205
206pub fn scanRelocs(zld: *Zld) !void {206pub fn scanRelocs(zld: *Zld) !void {
207 if (zld.getSectionByName("__TEXT", "__unwind_info") == null) return;207 if (zld.unwind_info_section_index == null) return;
208208
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}
234234
235pub fn collect(info: *UnwindInfo, zld: *Zld) !void {235pub 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;
237237
238 const cpu_arch = zld.options.target.cpu.arch;238 const cpu_arch = zld.options.target.cpu.arch;
239239
...@@ -551,7 +551,7 @@ fn collectPersonalityFromDwarf(...@@ -551,7 +551,7 @@ fn collectPersonalityFromDwarf(
551}551}
552552
553pub fn calcSectionSize(info: UnwindInfo, zld: *Zld) !void {553pub 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}
571571
572pub fn write(info: *UnwindInfo, zld: *Zld) !void {572pub 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}
4747
48pub fn calcSectionSize(zld: *Zld, unwind_info: *const UnwindInfo) !void {48pub 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}
9898
99pub fn write(zld: *Zld, unwind_info: *UnwindInfo) !void {99pub 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,
7575
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;
144152
145 const sect_id = self.getSectionByName("__DATA", "__data") orelse153 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;
149158
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") orelse178
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 }
171184
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 {
951972
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 }
19661995
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;