| ... | @@ -82,6 +82,18 @@ lazy_bind: LazyBindSection = .{}, | ... | @@ -82,6 +82,18 @@ lazy_bind: LazyBindSection = .{}, |
| 82 | export_trie: ExportTrieSection = .{}, | 82 | export_trie: ExportTrieSection = .{}, |
| 83 | unwind_info: UnwindInfo = .{}, | 83 | unwind_info: UnwindInfo = .{}, |
| 84 | | 84 | |
| | 85 | /// Tracked loadable segments during incremental linking. |
| | 86 | zig_text_seg_index: ?u8 = null, |
| | 87 | zig_data_const_seg_index: ?u8 = null, |
| | 88 | zig_data_seg_index: ?u8 = null, |
| | 89 | |
| | 90 | /// Tracked section headers with incremental updates to Zig object. |
| | 91 | zig_text_section_index: ?u8 = null, |
| | 92 | zig_data_const_section_index: ?u8 = null, |
| | 93 | zig_data_section_index: ?u8 = null, |
| | 94 | zig_bss_section_index: ?u8 = null, |
| | 95 | zig_got_section_index: ?u8 = null, |
| | 96 | |
| 85 | has_tlv: bool = false, | 97 | has_tlv: bool = false, |
| 86 | binds_to_weak: bool = false, | 98 | binds_to_weak: bool = false, |
| 87 | weak_defines: bool = false, | 99 | weak_defines: bool = false, |
| ... | @@ -234,8 +246,11 @@ pub fn createEmpty( | ... | @@ -234,8 +246,11 @@ pub fn createEmpty( |
| 234 | } }); | 246 | } }); |
| 235 | self.zig_object = index; | 247 | self.zig_object = index; |
| 236 | try self.getZigObject().?.init(self); | 248 | try self.getZigObject().?.init(self); |
| | 249 | try self.initMetadata(.{ |
| | 250 | .symbol_count_hint = options.symbol_count_hint, |
| | 251 | .program_code_size_hint = options.program_code_size_hint, |
| | 252 | }); |
| 237 | | 253 | |
| 238 | // TODO init metadata | | |
| 239 | // TODO init dwarf | 254 | // TODO init dwarf |
| 240 | | 255 | |
| 241 | // if (comp.config.debug_format != .strip) { | 256 | // if (comp.config.debug_format != .strip) { |
| ... | @@ -3103,6 +3118,45 @@ fn findFreeSpace(self: *MachO, object_size: u64, min_alignment: u32) u64 { | ... | @@ -3103,6 +3118,45 @@ fn findFreeSpace(self: *MachO, object_size: u64, min_alignment: u32) u64 { |
| 3103 | return start; | 3118 | return start; |
| 3104 | } | 3119 | } |
| 3105 | | 3120 | |
| | 3121 | const InitMetadataOptions = struct { |
| | 3122 | symbol_count_hint: u64, |
| | 3123 | program_code_size_hint: u64, |
| | 3124 | }; |
| | 3125 | |
| | 3126 | // TODO: move to ZigObject |
| | 3127 | // TODO: bring back pre-alloc of segments/sections |
| | 3128 | fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| | 3129 | _ = options; |
| | 3130 | |
| | 3131 | if (!self.base.isRelocatable()) { |
| | 3132 | // TODO: If we are not emitting a relocatable object file, init segments. |
| | 3133 | } |
| | 3134 | |
| | 3135 | if (self.zig_text_section_index == null) { |
| | 3136 | self.zig_text_section_index = try self.addSection("__TEXT", "__text", .{ |
| | 3137 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| | 3138 | }); |
| | 3139 | } |
| | 3140 | |
| | 3141 | if (self.zig_got_section_index == null and !self.base.isRelocatable()) { |
| | 3142 | self.zig_got_section_index = try self.addSection("__DATA_CONST", "__got_zig", .{}); |
| | 3143 | } |
| | 3144 | |
| | 3145 | if (self.zig_data_const_section_index == null) { |
| | 3146 | self.zig_data_const_section_index = try self.addSection("__DATA_CONST", "__const", .{}); |
| | 3147 | } |
| | 3148 | |
| | 3149 | if (self.zig_data_section_index == null) { |
| | 3150 | self.zig_data_section_index = try self.addSection("__DATA", "__data", .{}); |
| | 3151 | } |
| | 3152 | |
| | 3153 | if (self.zig_bss_section_index == null) { |
| | 3154 | self.zig_bss_section_index = try self.addSection("__DATA", "_bss", .{ |
| | 3155 | .flags = macho.S_ZEROFILL, |
| | 3156 | }); |
| | 3157 | } |
| | 3158 | } |
| | 3159 | |
| 3106 | pub fn getTarget(self: MachO) std.Target { | 3160 | pub fn getTarget(self: MachO) std.Target { |
| 3107 | return self.base.comp.root_mod.resolved_target.result; | 3161 | return self.base.comp.root_mod.resolved_target.result; |
| 3108 | } | 3162 | } |
| ... | @@ -3148,6 +3202,29 @@ inline fn requiresThunks(self: MachO) bool { | ... | @@ -3148,6 +3202,29 @@ inline fn requiresThunks(self: MachO) bool { |
| 3148 | return self.getTarget().cpu.arch == .aarch64; | 3202 | return self.getTarget().cpu.arch == .aarch64; |
| 3149 | } | 3203 | } |
| 3150 | | 3204 | |
| | 3205 | pub fn addSegment(self: *MachO, name: []const u8, opts: struct { |
| | 3206 | vmaddr: u64 = 0, |
| | 3207 | vmsize: u64 = 0, |
| | 3208 | fileoff: u64 = 0, |
| | 3209 | filesize: u64 = 0, |
| | 3210 | prot: macho.vm_prot_t = macho.PROT.NONE, |
| | 3211 | }) error{OutOfMemory}!u8 { |
| | 3212 | const gpa = self.base.comp.gpa; |
| | 3213 | const index = @as(u8, @intCast(self.segments.items.len)); |
| | 3214 | try self.segments.append(gpa, .{ |
| | 3215 | .segname = makeStaticString(name), |
| | 3216 | .vmaddr = opts.vmaddr, |
| | 3217 | .vmsize = opts.vmsize, |
| | 3218 | .fileoff = opts.fileoff, |
| | 3219 | .filesize = opts.filesize, |
| | 3220 | .maxprot = opts.prot, |
| | 3221 | .initprot = opts.prot, |
| | 3222 | .nsects = 0, |
| | 3223 | .cmdsize = @sizeOf(macho.segment_command_64), |
| | 3224 | }); |
| | 3225 | return index; |
| | 3226 | } |
| | 3227 | |
| 3151 | const AddSectionOpts = struct { | 3228 | const AddSectionOpts = struct { |
| 3152 | flags: u32 = macho.S_REGULAR, | 3229 | flags: u32 = macho.S_REGULAR, |
| 3153 | reserved1: u32 = 0, | 3230 | reserved1: u32 = 0, |