| ... | ... | @@ -85,15 +85,17 @@ unwind_info: UnwindInfo = .{}, |
| 85 | 85 | |
| 86 | 86 | /// Tracked loadable segments during incremental linking. |
| 87 | 87 | zig_text_seg_index: ?u8 = null, |
| 88 | | zig_data_const_seg_index: ?u8 = null, |
| 88 | zig_got_seg_index: ?u8 = null, |
| 89 | zig_const_seg_index: ?u8 = null, |
| 89 | 90 | zig_data_seg_index: ?u8 = null, |
| 91 | zig_bss_seg_index: ?u8 = null, |
| 90 | 92 | |
| 91 | 93 | /// Tracked section headers with incremental updates to Zig object. |
| 92 | 94 | zig_text_section_index: ?u8 = null, |
| 93 | | zig_data_const_section_index: ?u8 = null, |
| 95 | zig_got_section_index: ?u8 = null, |
| 96 | zig_const_section_index: ?u8 = null, |
| 94 | 97 | zig_data_section_index: ?u8 = null, |
| 95 | 98 | zig_bss_section_index: ?u8 = null, |
| 96 | | zig_got_section_index: ?u8 = null, |
| 97 | 99 | |
| 98 | 100 | has_tlv: bool = false, |
| 99 | 101 | binds_to_weak: bool = false, |
| ... | ... | @@ -252,6 +254,8 @@ pub fn createEmpty( |
| 252 | 254 | .program_code_size_hint = options.program_code_size_hint, |
| 253 | 255 | }); |
| 254 | 256 | |
| 257 | std.debug.print("{}", .{self.dumpState()}); |
| 258 | |
| 255 | 259 | // TODO init dwarf |
| 256 | 260 | |
| 257 | 261 | // if (comp.config.debug_format != .strip) { |
| ... | ... | @@ -3082,33 +3086,45 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 3082 | 3086 | } |
| 3083 | 3087 | |
| 3084 | 3088 | fn detectAllocCollision(self: *MachO, start: u64, size: u64) ?u64 { |
| 3085 | | // TODO: header and load commands have to be part of the __TEXT segment |
| 3086 | | const header_size = self.segments.items[self.header_segment_cmd_index.?].filesize; |
| 3089 | // Conservatively commit one page size as reserved space for the headers as we |
| 3090 | // expect it to grow and everything else be moved in flush anyhow. |
| 3091 | const header_size = self.getPageSize(); |
| 3087 | 3092 | if (start < header_size) |
| 3088 | 3093 | return header_size; |
| 3089 | 3094 | |
| 3090 | 3095 | const end = start + padToIdeal(size); |
| 3091 | 3096 | |
| 3092 | 3097 | for (self.sections.items(.header)) |header| { |
| 3093 | | const tight_size = header.size; |
| 3094 | | const increased_size = padToIdeal(tight_size); |
| 3098 | if (header.isZerofill()) continue; |
| 3099 | const increased_size = padToIdeal(header.size); |
| 3095 | 3100 | const test_end = header.offset + increased_size; |
| 3096 | 3101 | if (end > header.offset and start < test_end) { |
| 3097 | 3102 | return test_end; |
| 3098 | 3103 | } |
| 3099 | 3104 | } |
| 3100 | 3105 | |
| 3106 | for (self.segments.items) |seg| { |
| 3107 | const increased_size = padToIdeal(seg.filesize); |
| 3108 | const test_end = seg.fileoff +| increased_size; |
| 3109 | if (end > seg.fileoff and start < test_end) { |
| 3110 | return test_end; |
| 3111 | } |
| 3112 | } |
| 3113 | |
| 3101 | 3114 | return null; |
| 3102 | 3115 | } |
| 3103 | 3116 | |
| 3104 | 3117 | fn allocatedSize(self: *MachO, start: u64) u64 { |
| 3105 | | if (start == 0) |
| 3106 | | return 0; |
| 3118 | if (start == 0) return 0; |
| 3107 | 3119 | var min_pos: u64 = std.math.maxInt(u64); |
| 3108 | 3120 | for (self.sections.items(.header)) |header| { |
| 3109 | 3121 | if (header.offset <= start) continue; |
| 3110 | 3122 | if (header.offset < min_pos) min_pos = header.offset; |
| 3111 | 3123 | } |
| 3124 | for (self.segments.items) |seg| { |
| 3125 | if (seg.fileoff <= start) continue; |
| 3126 | if (seg.fileoff < min_pos) min_pos = seg.fileoff; |
| 3127 | } |
| 3112 | 3128 | return min_pos - start; |
| 3113 | 3129 | } |
| 3114 | 3130 | |
| ... | ... | @@ -3126,36 +3142,113 @@ const InitMetadataOptions = struct { |
| 3126 | 3142 | }; |
| 3127 | 3143 | |
| 3128 | 3144 | // TODO: move to ZigObject |
| 3129 | | // TODO: bring back pre-alloc of segments/sections |
| 3130 | 3145 | fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3131 | | _ = options; |
| 3132 | | |
| 3133 | 3146 | if (!self.base.isRelocatable()) { |
| 3134 | | // TODO: If we are not emitting a relocatable object file, init segments. |
| 3135 | | } |
| 3147 | const base_vmaddr = blk: { |
| 3148 | const pagezero_size = self.pagezero_size orelse default_pagezero_size; |
| 3149 | break :blk mem.alignBackward(u64, pagezero_size, self.getPageSize()); |
| 3150 | }; |
| 3151 | |
| 3152 | { |
| 3153 | const filesize = options.program_code_size_hint; |
| 3154 | const off = self.findFreeSpace(filesize, self.getPageSize()); |
| 3155 | self.zig_text_seg_index = try self.addSegment("__TEXT_ZIG", .{ |
| 3156 | .fileoff = off, |
| 3157 | .filesize = filesize, |
| 3158 | .vmaddr = base_vmaddr + 0x8000000, |
| 3159 | .vmsize = filesize, |
| 3160 | .prot = macho.PROT.READ | macho.PROT.EXEC, |
| 3161 | }); |
| 3162 | } |
| 3163 | |
| 3164 | { |
| 3165 | const filesize = options.symbol_count_hint * @sizeOf(u64); |
| 3166 | const off = self.findFreeSpace(filesize, self.getPageSize()); |
| 3167 | self.zig_got_seg_index = try self.addSegment("__GOT_ZIG", .{ |
| 3168 | .fileoff = off, |
| 3169 | .filesize = filesize, |
| 3170 | .vmaddr = base_vmaddr + 0x4000000, |
| 3171 | .vmsize = filesize, |
| 3172 | .prot = macho.PROT.READ | macho.PROT.WRITE, |
| 3173 | }); |
| 3174 | } |
| 3175 | |
| 3176 | { |
| 3177 | const filesize: u64 = 1024; |
| 3178 | const off = self.findFreeSpace(filesize, self.getPageSize()); |
| 3179 | self.zig_const_seg_index = try self.addSegment("__CONST_ZIG", .{ |
| 3180 | .fileoff = off, |
| 3181 | .filesize = filesize, |
| 3182 | .vmaddr = base_vmaddr + 0xc000000, |
| 3183 | .vmsize = filesize, |
| 3184 | .prot = macho.PROT.READ | macho.PROT.WRITE, |
| 3185 | }); |
| 3186 | } |
| 3187 | |
| 3188 | { |
| 3189 | const filesize: u64 = 1024; |
| 3190 | const off = self.findFreeSpace(filesize, self.getPageSize()); |
| 3191 | self.zig_data_seg_index = try self.addSegment("__DATA_ZIG", .{ |
| 3192 | .fileoff = off, |
| 3193 | .filesize = filesize, |
| 3194 | .vmaddr = base_vmaddr + 0x10000000, |
| 3195 | .vmsize = filesize, |
| 3196 | .prot = macho.PROT.READ | macho.PROT.WRITE, |
| 3197 | }); |
| 3198 | } |
| 3199 | |
| 3200 | { |
| 3201 | const memsize: u64 = 1024; |
| 3202 | self.zig_bss_seg_index = try self.addSegment("__BSS_ZIG", .{ |
| 3203 | .vmaddr = base_vmaddr + 0x14000000, |
| 3204 | .vmsize = memsize, |
| 3205 | .prot = macho.PROT.READ | macho.PROT.WRITE, |
| 3206 | }); |
| 3207 | } |
| 3208 | } else { |
| 3209 | @panic("TODO initMetadata when relocatable"); |
| 3210 | } |
| 3211 | |
| 3212 | const appendSect = struct { |
| 3213 | fn appendSect(macho_file: *MachO, sect_id: u8, seg_id: u8) void { |
| 3214 | const sect = &macho_file.sections.items(.header)[sect_id]; |
| 3215 | const seg = &macho_file.segments.items[seg_id]; |
| 3216 | seg.cmdsize += @sizeOf(macho.section_64); |
| 3217 | seg.nsects += 1; |
| 3218 | sect.addr = seg.vmaddr; |
| 3219 | sect.offset = @intCast(seg.fileoff); |
| 3220 | sect.size = seg.vmsize; |
| 3221 | macho_file.sections.items(.segment_id)[sect_id] = seg_id; |
| 3222 | } |
| 3223 | }.appendSect; |
| 3136 | 3224 | |
| 3137 | 3225 | if (self.zig_text_section_index == null) { |
| 3138 | | self.zig_text_section_index = try self.addSection("__TEXT", "__text", .{ |
| 3226 | self.zig_text_section_index = try self.addSection("__TEXT_ZIG", "__text_zig", .{ |
| 3139 | 3227 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 3140 | 3228 | }); |
| 3229 | appendSect(self, self.zig_text_section_index.?, self.zig_text_seg_index.?); |
| 3141 | 3230 | } |
| 3142 | 3231 | |
| 3143 | 3232 | if (self.zig_got_section_index == null and !self.base.isRelocatable()) { |
| 3144 | | self.zig_got_section_index = try self.addSection("__DATA_CONST", "__got_zig", .{}); |
| 3233 | self.zig_got_section_index = try self.addSection("__GOT_ZIG", "__got_zig", .{}); |
| 3234 | appendSect(self, self.zig_got_section_index.?, self.zig_got_seg_index.?); |
| 3145 | 3235 | } |
| 3146 | 3236 | |
| 3147 | | if (self.zig_data_const_section_index == null) { |
| 3148 | | self.zig_data_const_section_index = try self.addSection("__DATA_CONST", "__const", .{}); |
| 3237 | if (self.zig_const_section_index == null) { |
| 3238 | self.zig_const_section_index = try self.addSection("__CONST_ZIG", "__const_zig", .{}); |
| 3239 | appendSect(self, self.zig_const_section_index.?, self.zig_const_seg_index.?); |
| 3149 | 3240 | } |
| 3150 | 3241 | |
| 3151 | 3242 | if (self.zig_data_section_index == null) { |
| 3152 | | self.zig_data_section_index = try self.addSection("__DATA", "__data", .{}); |
| 3243 | self.zig_data_section_index = try self.addSection("__DATA_ZIG", "__data_zig", .{}); |
| 3244 | appendSect(self, self.zig_data_section_index.?, self.zig_data_seg_index.?); |
| 3153 | 3245 | } |
| 3154 | 3246 | |
| 3155 | 3247 | if (self.zig_bss_section_index == null) { |
| 3156 | | self.zig_bss_section_index = try self.addSection("__DATA", "_bss", .{ |
| 3248 | self.zig_bss_section_index = try self.addSection("__BSS_ZIG", "__bss_zig", .{ |
| 3157 | 3249 | .flags = macho.S_ZEROFILL, |
| 3158 | 3250 | }); |
| 3251 | appendSect(self, self.zig_bss_section_index.?, self.zig_bss_seg_index.?); |
| 3159 | 3252 | } |
| 3160 | 3253 | } |
| 3161 | 3254 | |