| ... | @@ -85,15 +85,17 @@ unwind_info: UnwindInfo = .{}, | ... | @@ -85,15 +85,17 @@ unwind_info: UnwindInfo = .{}, |
| 85 | | 85 | |
| 86 | /// Tracked loadable segments during incremental linking. | 86 | /// Tracked loadable segments during incremental linking. |
| 87 | zig_text_seg_index: ?u8 = null, | 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 | zig_data_seg_index: ?u8 = null, | 90 | zig_data_seg_index: ?u8 = null, |
| | 91 | zig_bss_seg_index: ?u8 = null, |
| 90 | | 92 | |
| 91 | /// Tracked section headers with incremental updates to Zig object. | 93 | /// Tracked section headers with incremental updates to Zig object. |
| 92 | zig_text_section_index: ?u8 = null, | 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 | zig_data_section_index: ?u8 = null, | 97 | zig_data_section_index: ?u8 = null, |
| 95 | zig_bss_section_index: ?u8 = null, | 98 | zig_bss_section_index: ?u8 = null, |
| 96 | zig_got_section_index: ?u8 = null, | | |
| 97 | | 99 | |
| 98 | has_tlv: bool = false, | 100 | has_tlv: bool = false, |
| 99 | binds_to_weak: bool = false, | 101 | binds_to_weak: bool = false, |
| ... | @@ -252,6 +254,8 @@ pub fn createEmpty( | ... | @@ -252,6 +254,8 @@ pub fn createEmpty( |
| 252 | .program_code_size_hint = options.program_code_size_hint, | 254 | .program_code_size_hint = options.program_code_size_hint, |
| 253 | }); | 255 | }); |
| 254 | | 256 | |
| | 257 | std.debug.print("{}", .{self.dumpState()}); |
| | 258 | |
| 255 | // TODO init dwarf | 259 | // TODO init dwarf |
| 256 | | 260 | |
| 257 | // if (comp.config.debug_format != .strip) { | 261 | // if (comp.config.debug_format != .strip) { |
| ... | @@ -3082,33 +3086,45 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { | ... | @@ -3082,33 +3086,45 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 3082 | } | 3086 | } |
| 3083 | | 3087 | |
| 3084 | fn detectAllocCollision(self: *MachO, start: u64, size: u64) ?u64 { | 3088 | fn detectAllocCollision(self: *MachO, start: u64, size: u64) ?u64 { |
| 3085 | // TODO: header and load commands have to be part of the __TEXT segment | 3089 | // Conservatively commit one page size as reserved space for the headers as we |
| 3086 | const header_size = self.segments.items[self.header_segment_cmd_index.?].filesize; | 3090 | // expect it to grow and everything else be moved in flush anyhow. |
| | 3091 | const header_size = self.getPageSize(); |
| 3087 | if (start < header_size) | 3092 | if (start < header_size) |
| 3088 | return header_size; | 3093 | return header_size; |
| 3089 | | 3094 | |
| 3090 | const end = start + padToIdeal(size); | 3095 | const end = start + padToIdeal(size); |
| 3091 | | 3096 | |
| 3092 | for (self.sections.items(.header)) |header| { | 3097 | for (self.sections.items(.header)) |header| { |
| 3093 | const tight_size = header.size; | 3098 | if (header.isZerofill()) continue; |
| 3094 | const increased_size = padToIdeal(tight_size); | 3099 | const increased_size = padToIdeal(header.size); |
| 3095 | const test_end = header.offset + increased_size; | 3100 | const test_end = header.offset + increased_size; |
| 3096 | if (end > header.offset and start < test_end) { | 3101 | if (end > header.offset and start < test_end) { |
| 3097 | return test_end; | 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 | return null; | 3114 | return null; |
| 3102 | } | 3115 | } |
| 3103 | | 3116 | |
| 3104 | fn allocatedSize(self: *MachO, start: u64) u64 { | 3117 | fn allocatedSize(self: *MachO, start: u64) u64 { |
| 3105 | if (start == 0) | 3118 | if (start == 0) return 0; |
| 3106 | return 0; | | |
| 3107 | var min_pos: u64 = std.math.maxInt(u64); | 3119 | var min_pos: u64 = std.math.maxInt(u64); |
| 3108 | for (self.sections.items(.header)) |header| { | 3120 | for (self.sections.items(.header)) |header| { |
| 3109 | if (header.offset <= start) continue; | 3121 | if (header.offset <= start) continue; |
| 3110 | if (header.offset < min_pos) min_pos = header.offset; | 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 | return min_pos - start; | 3128 | return min_pos - start; |
| 3113 | } | 3129 | } |
| 3114 | | 3130 | |
| ... | @@ -3126,36 +3142,113 @@ const InitMetadataOptions = struct { | ... | @@ -3126,36 +3142,113 @@ const InitMetadataOptions = struct { |
| 3126 | }; | 3142 | }; |
| 3127 | | 3143 | |
| 3128 | // TODO: move to ZigObject | 3144 | // TODO: move to ZigObject |
| 3129 | // TODO: bring back pre-alloc of segments/sections | | |
| 3130 | fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { | 3145 | fn initMetadata(self: *MachO, options: InitMetadataOptions) !void { |
| 3131 | _ = options; | | |
| 3132 | | | |
| 3133 | if (!self.base.isRelocatable()) { | 3146 | if (!self.base.isRelocatable()) { |
| 3134 | // TODO: If we are not emitting a relocatable object file, init segments. | 3147 | const base_vmaddr = blk: { |
| 3135 | } | 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 | if (self.zig_text_section_index == null) { | 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 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | 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 | if (self.zig_got_section_index == null and !self.base.isRelocatable()) { | 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) { | 3237 | if (self.zig_const_section_index == null) { |
| 3148 | self.zig_data_const_section_index = try self.addSection("__DATA_CONST", "__const", .{}); | 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 | if (self.zig_data_section_index == null) { | 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 | if (self.zig_bss_section_index == null) { | 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 | .flags = macho.S_ZEROFILL, | 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 | |