diff --git a/src/link/MachO.zig b/src/link/MachO.zig index 24dfa2c328..4f9ee0587b 100644 --- a/src/link/MachO.zig +++ b/src/link/MachO.zig @@ -807,6 +807,11 @@ fn linkWithLLD(self: *MachO, comp: *Compilation) !void { rpaths.appendAssumeCapacity(key.*); } + // frameworks + for (self.base.options.frameworks) |framework| { + log.warn("frameworks not yet supported for '-framework {s}'", .{framework}); + } + if (self.base.options.verbose_link) { var argv = std.ArrayList([]const u8).init(arena); diff --git a/src/link/MachO/Zld.zig b/src/link/MachO/Zld.zig index e9ed34fce6..dd957f1a4a 100644 --- a/src/link/MachO/Zld.zig +++ b/src/link/MachO/Zld.zig @@ -442,6 +442,25 @@ fn updateMetadata(self: *Zld) !void { const flags = source_sect.flags; switch (flags) { + macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS => { + if (self.text_section_index != null) continue; + + self.text_section_index = @intCast(u16, text_seg.sections.items.len); + try text_seg.addSection(self.allocator, .{ + .sectname = makeStaticString("__text"), + .segname = makeStaticString("__TEXT"), + .addr = 0, + .size = 0, + .offset = 0, + .@"align" = 0, + .reloff = 0, + .nreloc = 0, + .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, + .reserved1 = 0, + .reserved2 = 0, + .reserved3 = 0, + }); + }, macho.S_REGULAR, macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { if (mem.eql(u8, segname, "__TEXT")) { if (mem.eql(u8, sectname, "__ustring")) { @@ -481,8 +500,7 @@ fn updateMetadata(self: *Zld) !void { .reserved3 = 0, }); } - } else if (mem.eql(u8, segname, "__DATA")) { - if (!mem.eql(u8, sectname, "__const")) continue; + } else if (mem.eql(u8, segname, "__DATA") or mem.eql(u8, segname, "__DATA_CONST")) { if (self.data_const_section_index != null) continue; self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); @@ -503,7 +521,6 @@ fn updateMetadata(self: *Zld) !void { } }, macho.S_CSTRING_LITERALS => { - if (!mem.eql(u8, segname, "__TEXT")) continue; if (self.cstring_section_index != null) continue; self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); @@ -523,7 +540,6 @@ fn updateMetadata(self: *Zld) !void { }); }, macho.S_MOD_INIT_FUNC_POINTERS => { - if (!mem.eql(u8, segname, "__DATA")) continue; if (self.mod_init_func_section_index != null) continue; self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); @@ -543,7 +559,6 @@ fn updateMetadata(self: *Zld) !void { }); }, macho.S_MOD_TERM_FUNC_POINTERS => { - if (!mem.eql(u8, segname, "__DATA")) continue; if (self.mod_term_func_section_index != null) continue; self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len); @@ -563,7 +578,6 @@ fn updateMetadata(self: *Zld) !void { }); }, macho.S_ZEROFILL => { - if (!mem.eql(u8, segname, "__DATA")) continue; if (mem.eql(u8, sectname, "__common")) { if (self.common_section_index != null) continue; @@ -603,7 +617,6 @@ fn updateMetadata(self: *Zld) !void { } }, macho.S_THREAD_LOCAL_VARIABLES => { - if (!mem.eql(u8, segname, "__DATA")) continue; if (self.tlv_section_index != null) continue; self.tlv_section_index = @intCast(u16, data_seg.sections.items.len); @@ -623,7 +636,6 @@ fn updateMetadata(self: *Zld) !void { }); }, macho.S_THREAD_LOCAL_REGULAR => { - if (!mem.eql(u8, segname, "__DATA")) continue; if (self.tlv_data_section_index != null) continue; self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len); @@ -643,7 +655,6 @@ fn updateMetadata(self: *Zld) !void { }); }, macho.S_THREAD_LOCAL_ZEROFILL => { - if (!mem.eql(u8, segname, "__DATA")) continue; if (self.tlv_bss_section_index != null) continue; self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len); @@ -662,8 +673,32 @@ fn updateMetadata(self: *Zld) !void { .reserved3 = 0, }); }, + macho.S_COALESCED | + macho.S_ATTR_NO_TOC | + macho.S_ATTR_STRIP_STATIC_SYMS | + macho.S_ATTR_LIVE_SUPPORT => { + log.debug("TODO __eh_frame section: type 0x{x}, name '{s},{s}'", .{ + flags, segname, sectname, + }); + continue; + }, + macho.S_REGULAR | macho.S_ATTR_DEBUG => { + if (mem.eql(u8, "__LD", segname) and mem.eql(u8, "__compact_unwind", sectname)) { + log.debug("TODO compact unwind section: type 0x{x}, name '{s},{s}'", .{ + flags, segname, sectname, + }); + } + continue; + }, else => { - log.debug("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname }); + if (mem.eql(u8, "__LLVM", segname) and mem.eql(u8, "__asm", sectname)) { + log.debug("TODO LLVM bitcode section: type 0x{x}, name '{s},{s}'", .{ + flags, segname, sectname, + }); + continue; + } + log.err("unhandled section type 0x{x} for '{s},{s}'", .{ flags, segname, sectname }); + return error.UnhandledSection; }, } } @@ -857,24 +892,29 @@ fn getMatchingSection(self: *Zld, section: macho.section_64) ?MatchingSection { .seg = self.text_segment_cmd_index.?, .sect = self.ustring_section_index.?, }; - } else { - break :blk .{ - .seg = self.text_segment_cmd_index.?, - .sect = self.text_const_section_index.?, - }; } - } else if (mem.eql(u8, segname, "__DATA")) { - if (mem.eql(u8, sectname, "__data")) { - break :blk .{ - .seg = self.data_segment_cmd_index.?, - .sect = self.data_section_index.?, - }; - } else if (mem.eql(u8, sectname, "__const")) { + break :blk .{ + .seg = self.text_segment_cmd_index.?, + .sect = self.text_const_section_index.?, + }; + } + if (mem.eql(u8, segname, "__DATA_CONST")) { + break :blk .{ + .seg = self.data_const_segment_cmd_index.?, + .sect = self.data_const_section_index.?, + }; + } + if (mem.eql(u8, segname, "__DATA")) { + if (mem.eql(u8, sectname, "__const")) { break :blk .{ .seg = self.data_const_segment_cmd_index.?, .sect = self.data_const_section_index.?, }; } + break :blk .{ + .seg = self.data_segment_cmd_index.?, + .sect = self.data_section_index.?, + }; } break :blk null; }, @@ -1901,7 +1941,12 @@ fn relocTargetAddr(self: *Zld, object: *const Object, target: reloc.Relocation.T } }, .section => |sect_id| { + log.debug(" | section offset", .{}); const source_sect = object.sections.items[sect_id]; + log.debug(" | section '{s},{s}'", .{ + parseName(&source_sect.inner.segname), + parseName(&source_sect.inner.sectname), + }); const target_map = source_sect.target_map orelse unreachable; const target_seg = self.load_commands.items[target_map.segment_id].Segment; const target_sect = target_seg.sections.items[target_map.section_id];