| ... | @@ -1133,20 +1133,19 @@ pub const MatchingSection = struct { | ... | @@ -1133,20 +1133,19 @@ pub const MatchingSection = struct { |
| 1133 | }; | 1133 | }; |
| 1134 | | 1134 | |
| 1135 | pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection { | 1135 | pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSection { |
| 1136 | const text_seg = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | | |
| 1137 | const data_const_seg = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | | |
| 1138 | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 1139 | const segname = commands.segmentName(sect); | 1136 | const segname = commands.segmentName(sect); |
| 1140 | const sectname = commands.sectionName(sect); | 1137 | const sectname = commands.sectionName(sect); |
| 1141 | | | |
| 1142 | var needs_allocation = false; | | |
| 1143 | const res: ?MatchingSection = blk: { | 1138 | const res: ?MatchingSection = blk: { |
| 1144 | switch (commands.sectionType(sect)) { | 1139 | switch (commands.sectionType(sect)) { |
| 1145 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { | 1140 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 1146 | if (self.text_const_section_index == null) { | 1141 | if (self.text_const_section_index == null) { |
| 1147 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | 1142 | self.text_const_section_index = try self.allocateSection( |
| 1148 | try text_seg.addSection(self.base.allocator, "__const", .{}); | 1143 | self.text_segment_cmd_index.?, |
| 1149 | needs_allocation = true; | 1144 | "__const", |
| | 1145 | sect.size, |
| | 1146 | sect.@"align", |
| | 1147 | .{}, |
| | 1148 | ); |
| 1150 | } | 1149 | } |
| 1151 | | 1150 | |
| 1152 | break :blk .{ | 1151 | break :blk .{ |
| ... | @@ -1159,11 +1158,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1159,11 +1158,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1159 | // TODO it seems the common values within the sections in objects are deduplicated/merged | 1158 | // TODO it seems the common values within the sections in objects are deduplicated/merged |
| 1160 | // on merging the sections' contents. | 1159 | // on merging the sections' contents. |
| 1161 | if (self.objc_methname_section_index == null) { | 1160 | if (self.objc_methname_section_index == null) { |
| 1162 | self.objc_methname_section_index = @intCast(u16, text_seg.sections.items.len); | 1161 | self.objc_methname_section_index = try self.allocateSection( |
| 1163 | try text_seg.addSection(self.base.allocator, "__objc_methname", .{ | 1162 | self.text_segment_cmd_index.?, |
| 1164 | .flags = macho.S_CSTRING_LITERALS, | 1163 | "__objc_methname", |
| 1165 | }); | 1164 | sect.size, |
| 1166 | needs_allocation = true; | 1165 | sect.@"align", |
| | 1166 | .{}, |
| | 1167 | ); |
| 1167 | } | 1168 | } |
| 1168 | | 1169 | |
| 1169 | break :blk .{ | 1170 | break :blk .{ |
| ... | @@ -1172,11 +1173,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1172,11 +1173,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1172 | }; | 1173 | }; |
| 1173 | } else if (mem.eql(u8, sectname, "__objc_methtype")) { | 1174 | } else if (mem.eql(u8, sectname, "__objc_methtype")) { |
| 1174 | if (self.objc_methtype_section_index == null) { | 1175 | if (self.objc_methtype_section_index == null) { |
| 1175 | self.objc_methtype_section_index = @intCast(u16, text_seg.sections.items.len); | 1176 | self.objc_methtype_section_index = try self.allocateSection( |
| 1176 | try text_seg.addSection(self.base.allocator, "__objc_methtype", .{ | 1177 | self.text_segment_cmd_index.?, |
| 1177 | .flags = macho.S_CSTRING_LITERALS, | 1178 | "__objc_methtype", |
| 1178 | }); | 1179 | sect.size, |
| 1179 | needs_allocation = true; | 1180 | sect.@"align", |
| | 1181 | .{}, |
| | 1182 | ); |
| 1180 | } | 1183 | } |
| 1181 | | 1184 | |
| 1182 | break :blk .{ | 1185 | break :blk .{ |
| ... | @@ -1185,9 +1188,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1185,9 +1188,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1185 | }; | 1188 | }; |
| 1186 | } else if (mem.eql(u8, sectname, "__objc_classname")) { | 1189 | } else if (mem.eql(u8, sectname, "__objc_classname")) { |
| 1187 | if (self.objc_classname_section_index == null) { | 1190 | if (self.objc_classname_section_index == null) { |
| 1188 | self.objc_classname_section_index = @intCast(u16, text_seg.sections.items.len); | 1191 | self.objc_classname_section_index = try self.allocateSection( |
| 1189 | try text_seg.addSection(self.base.allocator, "__objc_classname", .{}); | 1192 | self.text_segment_cmd_index.?, |
| 1190 | needs_allocation = true; | 1193 | "__objc_classname", |
| | 1194 | sect.size, |
| | 1195 | sect.@"align", |
| | 1196 | .{}, |
| | 1197 | ); |
| 1191 | } | 1198 | } |
| 1192 | | 1199 | |
| 1193 | break :blk .{ | 1200 | break :blk .{ |
| ... | @@ -1197,11 +1204,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1197,11 +1204,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1197 | } | 1204 | } |
| 1198 | | 1205 | |
| 1199 | if (self.cstring_section_index == null) { | 1206 | if (self.cstring_section_index == null) { |
| 1200 | self.cstring_section_index = @intCast(u16, text_seg.sections.items.len); | 1207 | self.cstring_section_index = try self.allocateSection( |
| 1201 | try text_seg.addSection(self.base.allocator, "__cstring", .{ | 1208 | self.text_segment_cmd_index.?, |
| 1202 | .flags = macho.S_CSTRING_LITERALS, | 1209 | "__cstring", |
| 1203 | }); | 1210 | sect.size, |
| 1204 | needs_allocation = true; | 1211 | sect.@"align", |
| | 1212 | .{ |
| | 1213 | .flags = macho.S_CSTRING_LITERALS, |
| | 1214 | }, |
| | 1215 | ); |
| 1205 | } | 1216 | } |
| 1206 | | 1217 | |
| 1207 | break :blk .{ | 1218 | break :blk .{ |
| ... | @@ -1212,29 +1223,37 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1212,29 +1223,37 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1212 | macho.S_LITERAL_POINTERS => { | 1223 | macho.S_LITERAL_POINTERS => { |
| 1213 | if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__objc_selrefs")) { | 1224 | if (mem.eql(u8, segname, "__DATA") and mem.eql(u8, sectname, "__objc_selrefs")) { |
| 1214 | if (self.objc_selrefs_section_index == null) { | 1225 | if (self.objc_selrefs_section_index == null) { |
| 1215 | self.objc_selrefs_section_index = @intCast(u16, data_seg.sections.items.len); | 1226 | self.objc_selrefs_section_index = try self.allocateSection( |
| 1216 | try data_seg.addSection(self.base.allocator, "__objc_selrefs", .{ | 1227 | self.data_segment_cmd_index.?, |
| 1217 | .flags = macho.S_LITERAL_POINTERS, | 1228 | "__objc_selrefs", |
| 1218 | }); | 1229 | sect.size, |
| 1219 | needs_allocation = true; | 1230 | sect.@"align", |
| | 1231 | .{ |
| | 1232 | .flags = macho.S_LITERAL_POINTERS, |
| | 1233 | }, |
| | 1234 | ); |
| 1220 | } | 1235 | } |
| 1221 | | 1236 | |
| 1222 | break :blk .{ | 1237 | break :blk .{ |
| 1223 | .seg = self.data_segment_cmd_index.?, | 1238 | .seg = self.data_segment_cmd_index.?, |
| 1224 | .sect = self.objc_selrefs_section_index.?, | 1239 | .sect = self.objc_selrefs_section_index.?, |
| 1225 | }; | 1240 | }; |
| | 1241 | } else { |
| | 1242 | // TODO investigate |
| | 1243 | break :blk null; |
| 1226 | } | 1244 | } |
| 1227 | | | |
| 1228 | // TODO investigate | | |
| 1229 | break :blk null; | | |
| 1230 | }, | 1245 | }, |
| 1231 | macho.S_MOD_INIT_FUNC_POINTERS => { | 1246 | macho.S_MOD_INIT_FUNC_POINTERS => { |
| 1232 | if (self.mod_init_func_section_index == null) { | 1247 | if (self.mod_init_func_section_index == null) { |
| 1233 | self.mod_init_func_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1248 | self.mod_init_func_section_index = try self.allocateSection( |
| 1234 | try data_const_seg.addSection(self.base.allocator, "__mod_init_func", .{ | 1249 | self.data_const_segment_cmd_index.?, |
| 1235 | .flags = macho.S_MOD_INIT_FUNC_POINTERS, | 1250 | "__mod_init_func", |
| 1236 | }); | 1251 | sect.size, |
| 1237 | needs_allocation = true; | 1252 | sect.@"align", |
| | 1253 | .{ |
| | 1254 | .flags = macho.S_MOD_INIT_FUNC_POINTERS, |
| | 1255 | }, |
| | 1256 | ); |
| 1238 | } | 1257 | } |
| 1239 | | 1258 | |
| 1240 | break :blk .{ | 1259 | break :blk .{ |
| ... | @@ -1244,11 +1263,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1244,11 +1263,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1244 | }, | 1263 | }, |
| 1245 | macho.S_MOD_TERM_FUNC_POINTERS => { | 1264 | macho.S_MOD_TERM_FUNC_POINTERS => { |
| 1246 | if (self.mod_term_func_section_index == null) { | 1265 | if (self.mod_term_func_section_index == null) { |
| 1247 | self.mod_term_func_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1266 | self.mod_term_func_section_index = try self.allocateSection( |
| 1248 | try data_const_seg.addSection(self.base.allocator, "__mod_term_func", .{ | 1267 | self.data_const_segment_cmd_index.?, |
| 1249 | .flags = macho.S_MOD_TERM_FUNC_POINTERS, | 1268 | "__mod_term_func", |
| 1250 | }); | 1269 | sect.size, |
| 1251 | needs_allocation = true; | 1270 | sect.@"align", |
| | 1271 | .{ |
| | 1272 | .flags = macho.S_MOD_TERM_FUNC_POINTERS, |
| | 1273 | }, |
| | 1274 | ); |
| 1252 | } | 1275 | } |
| 1253 | | 1276 | |
| 1254 | break :blk .{ | 1277 | break :blk .{ |
| ... | @@ -1258,11 +1281,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1258,11 +1281,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1258 | }, | 1281 | }, |
| 1259 | macho.S_ZEROFILL => { | 1282 | macho.S_ZEROFILL => { |
| 1260 | if (self.bss_section_index == null) { | 1283 | if (self.bss_section_index == null) { |
| 1261 | self.bss_section_index = @intCast(u16, data_seg.sections.items.len); | 1284 | self.bss_section_index = try self.allocateSection( |
| 1262 | try data_seg.addSection(self.base.allocator, "__bss", .{ | 1285 | self.data_segment_cmd_index.?, |
| 1263 | .flags = macho.S_ZEROFILL, | 1286 | "__bss", |
| 1264 | }); | 1287 | sect.size, |
| 1265 | needs_allocation = true; | 1288 | sect.@"align", |
| | 1289 | .{ |
| | 1290 | .flags = macho.S_ZEROFILL, |
| | 1291 | }, |
| | 1292 | ); |
| 1266 | } | 1293 | } |
| 1267 | | 1294 | |
| 1268 | break :blk .{ | 1295 | break :blk .{ |
| ... | @@ -1272,11 +1299,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1272,11 +1299,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1272 | }, | 1299 | }, |
| 1273 | macho.S_THREAD_LOCAL_VARIABLES => { | 1300 | macho.S_THREAD_LOCAL_VARIABLES => { |
| 1274 | if (self.tlv_section_index == null) { | 1301 | if (self.tlv_section_index == null) { |
| 1275 | self.tlv_section_index = @intCast(u16, data_seg.sections.items.len); | 1302 | self.tlv_section_index = try self.allocateSection( |
| 1276 | try data_seg.addSection(self.base.allocator, "__thread_vars", .{ | 1303 | self.data_segment_cmd_index.?, |
| 1277 | .flags = macho.S_THREAD_LOCAL_VARIABLES, | 1304 | "__thread_vars", |
| 1278 | }); | 1305 | sect.size, |
| 1279 | needs_allocation = true; | 1306 | sect.@"align", |
| | 1307 | .{ |
| | 1308 | .flags = macho.S_THREAD_LOCAL_VARIABLES, |
| | 1309 | }, |
| | 1310 | ); |
| 1280 | } | 1311 | } |
| 1281 | | 1312 | |
| 1282 | break :blk .{ | 1313 | break :blk .{ |
| ... | @@ -1286,11 +1317,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1286,11 +1317,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1286 | }, | 1317 | }, |
| 1287 | macho.S_THREAD_LOCAL_REGULAR => { | 1318 | macho.S_THREAD_LOCAL_REGULAR => { |
| 1288 | if (self.tlv_data_section_index == null) { | 1319 | if (self.tlv_data_section_index == null) { |
| 1289 | self.tlv_data_section_index = @intCast(u16, data_seg.sections.items.len); | 1320 | self.tlv_data_section_index = try self.allocateSection( |
| 1290 | try data_seg.addSection(self.base.allocator, "__thread_data", .{ | 1321 | self.data_segment_cmd_index.?, |
| 1291 | .flags = macho.S_THREAD_LOCAL_REGULAR, | 1322 | "__thread_data", |
| 1292 | }); | 1323 | sect.size, |
| 1293 | needs_allocation = true; | 1324 | sect.@"align", |
| | 1325 | .{ |
| | 1326 | .flags = macho.S_THREAD_LOCAL_REGULAR, |
| | 1327 | }, |
| | 1328 | ); |
| 1294 | } | 1329 | } |
| 1295 | | 1330 | |
| 1296 | break :blk .{ | 1331 | break :blk .{ |
| ... | @@ -1300,11 +1335,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1300,11 +1335,15 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1300 | }, | 1335 | }, |
| 1301 | macho.S_THREAD_LOCAL_ZEROFILL => { | 1336 | macho.S_THREAD_LOCAL_ZEROFILL => { |
| 1302 | if (self.tlv_bss_section_index == null) { | 1337 | if (self.tlv_bss_section_index == null) { |
| 1303 | self.tlv_bss_section_index = @intCast(u16, data_seg.sections.items.len); | 1338 | self.tlv_bss_section_index = try self.allocateSection( |
| 1304 | try data_seg.addSection(self.base.allocator, "__thread_bss", .{ | 1339 | self.data_segment_cmd_index.?, |
| 1305 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, | 1340 | "__thread_bss", |
| 1306 | }); | 1341 | sect.size, |
| 1307 | needs_allocation = true; | 1342 | sect.@"align", |
| | 1343 | .{ |
| | 1344 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| | 1345 | }, |
| | 1346 | ); |
| 1308 | } | 1347 | } |
| 1309 | | 1348 | |
| 1310 | break :blk .{ | 1349 | break :blk .{ |
| ... | @@ -1317,9 +1356,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1317,9 +1356,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1317 | // TODO I believe __eh_frame is currently part of __unwind_info section | 1356 | // TODO I believe __eh_frame is currently part of __unwind_info section |
| 1318 | // in the latest ld64 output. | 1357 | // in the latest ld64 output. |
| 1319 | if (self.eh_frame_section_index == null) { | 1358 | if (self.eh_frame_section_index == null) { |
| 1320 | self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len); | 1359 | self.eh_frame_section_index = try self.allocateSection( |
| 1321 | try text_seg.addSection(self.base.allocator, "__eh_frame", .{}); | 1360 | self.text_segment_cmd_index.?, |
| 1322 | needs_allocation = true; | 1361 | "__eh_frame", |
| | 1362 | sect.size, |
| | 1363 | sect.@"align", |
| | 1364 | .{}, |
| | 1365 | ); |
| 1323 | } | 1366 | } |
| 1324 | | 1367 | |
| 1325 | break :blk .{ | 1368 | break :blk .{ |
| ... | @@ -1330,9 +1373,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1330,9 +1373,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1330 | | 1373 | |
| 1331 | // TODO audit this: is this the right mapping? | 1374 | // TODO audit this: is this the right mapping? |
| 1332 | if (self.data_const_section_index == null) { | 1375 | if (self.data_const_section_index == null) { |
| 1333 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1376 | self.data_const_section_index = try self.allocateSection( |
| 1334 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); | 1377 | self.data_const_segment_cmd_index.?, |
| 1335 | needs_allocation = true; | 1378 | "__const", |
| | 1379 | sect.size, |
| | 1380 | sect.@"align", |
| | 1381 | .{}, |
| | 1382 | ); |
| 1336 | } | 1383 | } |
| 1337 | | 1384 | |
| 1338 | break :blk .{ | 1385 | break :blk .{ |
| ... | @@ -1343,11 +1390,17 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1343,11 +1390,17 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1343 | macho.S_REGULAR => { | 1390 | macho.S_REGULAR => { |
| 1344 | if (commands.sectionIsCode(sect)) { | 1391 | if (commands.sectionIsCode(sect)) { |
| 1345 | if (self.text_section_index == null) { | 1392 | if (self.text_section_index == null) { |
| 1346 | self.text_section_index = @intCast(u16, text_seg.sections.items.len); | 1393 | self.text_section_index = try self.allocateSection( |
| 1347 | try text_seg.addSection(self.base.allocator, "__text", .{ | 1394 | self.text_segment_cmd_index.?, |
| 1348 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | 1395 | "__text", |
| 1349 | }); | 1396 | sect.size, |
| 1350 | needs_allocation = true; | 1397 | sect.@"align", |
| | 1398 | .{ |
| | 1399 | .flags = macho.S_REGULAR | |
| | 1400 | macho.S_ATTR_PURE_INSTRUCTIONS | |
| | 1401 | macho.S_ATTR_SOME_INSTRUCTIONS, |
| | 1402 | }, |
| | 1403 | ); |
| 1351 | } | 1404 | } |
| 1352 | | 1405 | |
| 1353 | break :blk .{ | 1406 | break :blk .{ |
| ... | @@ -1368,9 +1421,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1368,9 +1421,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1368 | if (mem.eql(u8, segname, "__TEXT")) { | 1421 | if (mem.eql(u8, segname, "__TEXT")) { |
| 1369 | if (mem.eql(u8, sectname, "__ustring")) { | 1422 | if (mem.eql(u8, sectname, "__ustring")) { |
| 1370 | if (self.ustring_section_index == null) { | 1423 | if (self.ustring_section_index == null) { |
| 1371 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); | 1424 | self.ustring_section_index = try self.allocateSection( |
| 1372 | try text_seg.addSection(self.base.allocator, "__ustring", .{}); | 1425 | self.text_segment_cmd_index.?, |
| 1373 | needs_allocation = true; | 1426 | "__ustring", |
| | 1427 | sect.size, |
| | 1428 | sect.@"align", |
| | 1429 | .{}, |
| | 1430 | ); |
| 1374 | } | 1431 | } |
| 1375 | | 1432 | |
| 1376 | break :blk .{ | 1433 | break :blk .{ |
| ... | @@ -1379,9 +1436,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1379,9 +1436,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1379 | }; | 1436 | }; |
| 1380 | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { | 1437 | } else if (mem.eql(u8, sectname, "__gcc_except_tab")) { |
| 1381 | if (self.gcc_except_tab_section_index == null) { | 1438 | if (self.gcc_except_tab_section_index == null) { |
| 1382 | self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len); | 1439 | self.gcc_except_tab_section_index = try self.allocateSection( |
| 1383 | try text_seg.addSection(self.base.allocator, "__gcc_except_tab", .{}); | 1440 | self.text_segment_cmd_index.?, |
| 1384 | needs_allocation = true; | 1441 | "__gcc_except_tab", |
| | 1442 | sect.size, |
| | 1443 | sect.@"align", |
| | 1444 | .{}, |
| | 1445 | ); |
| 1385 | } | 1446 | } |
| 1386 | | 1447 | |
| 1387 | break :blk .{ | 1448 | break :blk .{ |
| ... | @@ -1390,9 +1451,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1390,9 +1451,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1390 | }; | 1451 | }; |
| 1391 | } else if (mem.eql(u8, sectname, "__objc_methlist")) { | 1452 | } else if (mem.eql(u8, sectname, "__objc_methlist")) { |
| 1392 | if (self.objc_methlist_section_index == null) { | 1453 | if (self.objc_methlist_section_index == null) { |
| 1393 | self.objc_methlist_section_index = @intCast(u16, text_seg.sections.items.len); | 1454 | self.objc_methlist_section_index = try self.allocateSection( |
| 1394 | try text_seg.addSection(self.base.allocator, "__objc_methlist", .{}); | 1455 | self.text_segment_cmd_index.?, |
| 1395 | needs_allocation = true; | 1456 | "__objc_methlist", |
| | 1457 | sect.size, |
| | 1458 | sect.@"align", |
| | 1459 | .{}, |
| | 1460 | ); |
| 1396 | } | 1461 | } |
| 1397 | | 1462 | |
| 1398 | break :blk .{ | 1463 | break :blk .{ |
| ... | @@ -1406,9 +1471,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1406,9 +1471,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1406 | mem.eql(u8, sectname, "__gopclntab")) | 1471 | mem.eql(u8, sectname, "__gopclntab")) |
| 1407 | { | 1472 | { |
| 1408 | if (self.data_const_section_index == null) { | 1473 | if (self.data_const_section_index == null) { |
| 1409 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1474 | self.data_const_section_index = try self.allocateSection( |
| 1410 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); | 1475 | self.data_const_segment_cmd_index.?, |
| 1411 | needs_allocation = true; | 1476 | "__const", |
| | 1477 | sect.size, |
| | 1478 | sect.@"align", |
| | 1479 | .{}, |
| | 1480 | ); |
| 1412 | } | 1481 | } |
| 1413 | | 1482 | |
| 1414 | break :blk .{ | 1483 | break :blk .{ |
| ... | @@ -1417,9 +1486,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1417,9 +1486,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1417 | }; | 1486 | }; |
| 1418 | } else { | 1487 | } else { |
| 1419 | if (self.text_const_section_index == null) { | 1488 | if (self.text_const_section_index == null) { |
| 1420 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); | 1489 | self.text_const_section_index = try self.allocateSection( |
| 1421 | try text_seg.addSection(self.base.allocator, "__const", .{}); | 1490 | self.text_segment_cmd_index.?, |
| 1422 | needs_allocation = true; | 1491 | "__const", |
| | 1492 | sect.size, |
| | 1493 | sect.@"align", |
| | 1494 | .{}, |
| | 1495 | ); |
| 1423 | } | 1496 | } |
| 1424 | | 1497 | |
| 1425 | break :blk .{ | 1498 | break :blk .{ |
| ... | @@ -1431,9 +1504,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1431,9 +1504,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1431 | | 1504 | |
| 1432 | if (mem.eql(u8, segname, "__DATA_CONST")) { | 1505 | if (mem.eql(u8, segname, "__DATA_CONST")) { |
| 1433 | if (self.data_const_section_index == null) { | 1506 | if (self.data_const_section_index == null) { |
| 1434 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1507 | self.data_const_section_index = try self.allocateSection( |
| 1435 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); | 1508 | self.data_const_segment_cmd_index.?, |
| 1436 | needs_allocation = true; | 1509 | "__const", |
| | 1510 | sect.size, |
| | 1511 | sect.@"align", |
| | 1512 | .{}, |
| | 1513 | ); |
| 1437 | } | 1514 | } |
| 1438 | | 1515 | |
| 1439 | break :blk .{ | 1516 | break :blk .{ |
| ... | @@ -1445,9 +1522,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1445,9 +1522,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1445 | if (mem.eql(u8, segname, "__DATA")) { | 1522 | if (mem.eql(u8, segname, "__DATA")) { |
| 1446 | if (mem.eql(u8, sectname, "__const")) { | 1523 | if (mem.eql(u8, sectname, "__const")) { |
| 1447 | if (self.data_const_section_index == null) { | 1524 | if (self.data_const_section_index == null) { |
| 1448 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1525 | self.data_const_section_index = try self.allocateSection( |
| 1449 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); | 1526 | self.data_const_segment_cmd_index.?, |
| 1450 | needs_allocation = true; | 1527 | "__const", |
| | 1528 | sect.size, |
| | 1529 | sect.@"align", |
| | 1530 | .{}, |
| | 1531 | ); |
| 1451 | } | 1532 | } |
| 1452 | | 1533 | |
| 1453 | break :blk .{ | 1534 | break :blk .{ |
| ... | @@ -1456,9 +1537,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1456,9 +1537,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1456 | }; | 1537 | }; |
| 1457 | } else if (mem.eql(u8, sectname, "__cfstring")) { | 1538 | } else if (mem.eql(u8, sectname, "__cfstring")) { |
| 1458 | if (self.objc_cfstring_section_index == null) { | 1539 | if (self.objc_cfstring_section_index == null) { |
| 1459 | self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1540 | self.objc_cfstring_section_index = try self.allocateSection( |
| 1460 | try data_const_seg.addSection(self.base.allocator, "__cfstring", .{}); | 1541 | self.data_const_segment_cmd_index.?, |
| 1461 | needs_allocation = true; | 1542 | "__cfstring", |
| | 1543 | sect.size, |
| | 1544 | sect.@"align", |
| | 1545 | .{}, |
| | 1546 | ); |
| 1462 | } | 1547 | } |
| 1463 | | 1548 | |
| 1464 | break :blk .{ | 1549 | break :blk .{ |
| ... | @@ -1467,9 +1552,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1467,9 +1552,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1467 | }; | 1552 | }; |
| 1468 | } else if (mem.eql(u8, sectname, "__objc_classlist")) { | 1553 | } else if (mem.eql(u8, sectname, "__objc_classlist")) { |
| 1469 | if (self.objc_classlist_section_index == null) { | 1554 | if (self.objc_classlist_section_index == null) { |
| 1470 | self.objc_classlist_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1555 | self.objc_classlist_section_index = try self.allocateSection( |
| 1471 | try data_const_seg.addSection(self.base.allocator, "__objc_classlist", .{}); | 1556 | self.data_const_segment_cmd_index.?, |
| 1472 | needs_allocation = true; | 1557 | "__objc_classlist", |
| | 1558 | sect.size, |
| | 1559 | sect.@"align", |
| | 1560 | .{}, |
| | 1561 | ); |
| 1473 | } | 1562 | } |
| 1474 | | 1563 | |
| 1475 | break :blk .{ | 1564 | break :blk .{ |
| ... | @@ -1478,9 +1567,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1478,9 +1567,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1478 | }; | 1567 | }; |
| 1479 | } else if (mem.eql(u8, sectname, "__objc_imageinfo")) { | 1568 | } else if (mem.eql(u8, sectname, "__objc_imageinfo")) { |
| 1480 | if (self.objc_imageinfo_section_index == null) { | 1569 | if (self.objc_imageinfo_section_index == null) { |
| 1481 | self.objc_imageinfo_section_index = @intCast(u16, data_const_seg.sections.items.len); | 1570 | self.objc_imageinfo_section_index = try self.allocateSection( |
| 1482 | try data_const_seg.addSection(self.base.allocator, "__objc_imageinfo", .{}); | 1571 | self.data_const_segment_cmd_index.?, |
| 1483 | needs_allocation = true; | 1572 | "__objc_imageinfo", |
| | 1573 | sect.size, |
| | 1574 | sect.@"align", |
| | 1575 | .{}, |
| | 1576 | ); |
| 1484 | } | 1577 | } |
| 1485 | | 1578 | |
| 1486 | break :blk .{ | 1579 | break :blk .{ |
| ... | @@ -1489,9 +1582,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1489,9 +1582,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1489 | }; | 1582 | }; |
| 1490 | } else if (mem.eql(u8, sectname, "__objc_const")) { | 1583 | } else if (mem.eql(u8, sectname, "__objc_const")) { |
| 1491 | if (self.objc_const_section_index == null) { | 1584 | if (self.objc_const_section_index == null) { |
| 1492 | self.objc_const_section_index = @intCast(u16, data_seg.sections.items.len); | 1585 | self.objc_const_section_index = try self.allocateSection( |
| 1493 | try data_seg.addSection(self.base.allocator, "__objc_const", .{}); | 1586 | self.data_segment_cmd_index.?, |
| 1494 | needs_allocation = true; | 1587 | "__objc_const", |
| | 1588 | sect.size, |
| | 1589 | sect.@"align", |
| | 1590 | .{}, |
| | 1591 | ); |
| 1495 | } | 1592 | } |
| 1496 | | 1593 | |
| 1497 | break :blk .{ | 1594 | break :blk .{ |
| ... | @@ -1500,9 +1597,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1500,9 +1597,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1500 | }; | 1597 | }; |
| 1501 | } else if (mem.eql(u8, sectname, "__objc_classrefs")) { | 1598 | } else if (mem.eql(u8, sectname, "__objc_classrefs")) { |
| 1502 | if (self.objc_classrefs_section_index == null) { | 1599 | if (self.objc_classrefs_section_index == null) { |
| 1503 | self.objc_classrefs_section_index = @intCast(u16, data_seg.sections.items.len); | 1600 | self.objc_classrefs_section_index = try self.allocateSection( |
| 1504 | try data_seg.addSection(self.base.allocator, "__objc_classrefs", .{}); | 1601 | self.data_segment_cmd_index.?, |
| 1505 | needs_allocation = true; | 1602 | "__objc_classrefs", |
| | 1603 | sect.size, |
| | 1604 | sect.@"align", |
| | 1605 | .{}, |
| | 1606 | ); |
| 1506 | } | 1607 | } |
| 1507 | | 1608 | |
| 1508 | break :blk .{ | 1609 | break :blk .{ |
| ... | @@ -1511,9 +1612,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1511,9 +1612,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1511 | }; | 1612 | }; |
| 1512 | } else if (mem.eql(u8, sectname, "__objc_data")) { | 1613 | } else if (mem.eql(u8, sectname, "__objc_data")) { |
| 1513 | if (self.objc_data_section_index == null) { | 1614 | if (self.objc_data_section_index == null) { |
| 1514 | self.objc_data_section_index = @intCast(u16, data_seg.sections.items.len); | 1615 | self.objc_data_section_index = try self.allocateSection( |
| 1515 | try data_seg.addSection(self.base.allocator, "__objc_data", .{}); | 1616 | self.data_segment_cmd_index.?, |
| 1516 | needs_allocation = true; | 1617 | "__objc_data", |
| | 1618 | sect.size, |
| | 1619 | sect.@"align", |
| | 1620 | .{}, |
| | 1621 | ); |
| 1517 | } | 1622 | } |
| 1518 | | 1623 | |
| 1519 | break :blk .{ | 1624 | break :blk .{ |
| ... | @@ -1522,9 +1627,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1522,9 +1627,13 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1522 | }; | 1627 | }; |
| 1523 | } else { | 1628 | } else { |
| 1524 | if (self.data_section_index == null) { | 1629 | if (self.data_section_index == null) { |
| 1525 | self.data_section_index = @intCast(u16, data_seg.sections.items.len); | 1630 | self.data_section_index = try self.allocateSection( |
| 1526 | try data_seg.addSection(self.base.allocator, "__data", .{}); | 1631 | self.data_segment_cmd_index.?, |
| 1527 | needs_allocation = true; | 1632 | "__data", |
| | 1633 | sect.size, |
| | 1634 | sect.@"align", |
| | 1635 | .{}, |
| | 1636 | ); |
| 1528 | } | 1637 | } |
| 1529 | | 1638 | |
| 1530 | break :blk .{ | 1639 | break :blk .{ |
| ... | @@ -1545,42 +1654,6 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio | ... | @@ -1545,42 +1654,6 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1545 | else => break :blk null, | 1654 | else => break :blk null, |
| 1546 | } | 1655 | } |
| 1547 | }; | 1656 | }; |
| 1548 | | | |
| 1549 | if (res) |match| { | | |
| 1550 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 1551 | _ = try self.block_free_lists.getOrPutValue(self.base.allocator, match, .{}); | | |
| 1552 | | | |
| 1553 | const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1; | | |
| 1554 | if (!use_stage1) { | | |
| 1555 | const target_seg = &self.load_commands.items[match.seg].Segment; | | |
| 1556 | const target_sect = &target_seg.sections.items[match.sect]; | | |
| 1557 | | | |
| 1558 | // Update section's alignment | | |
| 1559 | // TODO if sect.@"align" > target_sect.@"align", should we move the entire | | |
| 1560 | // section to match the required alignment? | | |
| 1561 | target_sect.@"align" = math.max(target_sect.@"align", sect.@"align"); | | |
| 1562 | | | |
| 1563 | if (needs_allocation) { | | |
| 1564 | const alignment = try math.powi(u32, 2, target_sect.@"align"); | | |
| 1565 | const needed_size = sect.size; | | |
| 1566 | const off = target_seg.findFreeSpace(needed_size, alignment, self.header_pad); | | |
| 1567 | assert(off + needed_size <= target_seg.inner.fileoff + target_seg.inner.filesize); // TODO expand | | |
| 1568 | | | |
| 1569 | log.debug("found {s},{s} section free space 0x{x} to 0x{x}", .{ | | |
| 1570 | segname, | | |
| 1571 | sectname, | | |
| 1572 | off, | | |
| 1573 | off + needed_size, | | |
| 1574 | }); | | |
| 1575 | | | |
| 1576 | target_sect.addr = target_seg.inner.vmaddr + off; | | |
| 1577 | target_sect.size = needed_size; | | |
| 1578 | target_sect.offset = @intCast(u32, off); | | |
| 1579 | self.load_commands_dirty = true; | | |
| 1580 | } | | |
| 1581 | } | | |
| 1582 | } | | |
| 1583 | | | |
| 1584 | return res; | 1657 | return res; |
| 1585 | } | 1658 | } |
| 1586 | | 1659 | |
| ... | @@ -3878,9 +3951,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -3878,9 +3951,12 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 3878 | if (self.pagezero_segment_cmd_index == null) { | 3951 | if (self.pagezero_segment_cmd_index == null) { |
| 3879 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); | 3952 | self.pagezero_segment_cmd_index = @intCast(u16, self.load_commands.items.len); |
| 3880 | try self.load_commands.append(self.base.allocator, .{ | 3953 | try self.load_commands.append(self.base.allocator, .{ |
| 3881 | .Segment = SegmentCommand.empty("__PAGEZERO", .{ | 3954 | .Segment = .{ |
| 3882 | .vmsize = 0x100000000, // size always set to 4GB | 3955 | .inner = .{ |
| 3883 | }), | 3956 | .segname = makeStaticString("__PAGEZERO"), |
| | 3957 | .vmsize = 0x100000000, // size always set to 4GB |
| | 3958 | }, |
| | 3959 | }, |
| 3884 | }); | 3960 | }); |
| 3885 | self.load_commands_dirty = true; | 3961 | self.load_commands_dirty = true; |
| 3886 | } | 3962 | } |
| ... | @@ -3895,51 +3971,39 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -3895,51 +3971,39 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 3895 | log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size }); | 3971 | log.debug("found __TEXT segment free space 0x{x} to 0x{x}", .{ 0, needed_size }); |
| 3896 | | 3972 | |
| 3897 | try self.load_commands.append(self.base.allocator, .{ | 3973 | try self.load_commands.append(self.base.allocator, .{ |
| 3898 | .Segment = SegmentCommand.empty("__TEXT", .{ | 3974 | .Segment = .{ |
| 3899 | .vmaddr = 0x100000000, // always starts at 4GB | 3975 | .inner = .{ |
| 3900 | .vmsize = needed_size, | 3976 | .segname = makeStaticString("__TEXT"), |
| 3901 | .filesize = needed_size, | 3977 | .vmaddr = 0x100000000, // always starts at 4GB |
| 3902 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, | 3978 | .vmsize = needed_size, |
| 3903 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, | 3979 | .filesize = needed_size, |
| 3904 | }), | 3980 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| | 3981 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_EXECUTE, |
| | 3982 | }, |
| | 3983 | }, |
| 3905 | }); | 3984 | }); |
| 3906 | self.load_commands_dirty = true; | 3985 | self.load_commands_dirty = true; |
| 3907 | } | 3986 | } |
| 3908 | | 3987 | |
| 3909 | if (self.text_section_index == null) { | 3988 | if (self.text_section_index == null) { |
| 3910 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | | |
| 3911 | self.text_section_index = @intCast(u16, text_segment.sections.items.len); | | |
| 3912 | | | |
| 3913 | const alignment: u2 = switch (self.base.options.target.cpu.arch) { | 3989 | const alignment: u2 = switch (self.base.options.target.cpu.arch) { |
| 3914 | .x86_64 => 0, | 3990 | .x86_64 => 0, |
| 3915 | .aarch64 => 2, | 3991 | .aarch64 => 2, |
| 3916 | else => unreachable, // unhandled architecture type | 3992 | else => unreachable, // unhandled architecture type |
| 3917 | }; | 3993 | }; |
| 3918 | const needed_size = self.base.options.program_code_size_hint; | 3994 | const needed_size = self.base.options.program_code_size_hint; |
| 3919 | const off = text_segment.findFreeSpace(needed_size, @as(u16, 1) << alignment, self.header_pad); | 3995 | self.text_section_index = try self.allocateSection( |
| 3920 | | 3996 | self.text_segment_cmd_index.?, |
| 3921 | log.debug("found __text section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 3997 | "__text", |
| 3922 | | 3998 | needed_size, |
| 3923 | try text_segment.addSection(self.base.allocator, "__text", .{ | 3999 | alignment, |
| 3924 | .addr = text_segment.inner.vmaddr + off, | 4000 | .{ |
| 3925 | .size = @intCast(u32, needed_size), | 4001 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 3926 | .offset = @intCast(u32, off), | 4002 | }, |
| 3927 | .@"align" = alignment, | 4003 | ); |
| 3928 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | | |
| 3929 | }); | | |
| 3930 | const match = MatchingSection{ | | |
| 3931 | .seg = self.text_segment_cmd_index.?, | | |
| 3932 | .sect = self.text_section_index.?, | | |
| 3933 | }; | | |
| 3934 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 3935 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 3936 | self.load_commands_dirty = true; | | |
| 3937 | } | 4004 | } |
| 3938 | | 4005 | |
| 3939 | if (self.stubs_section_index == null) { | 4006 | if (self.stubs_section_index == null) { |
| 3940 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | | |
| 3941 | self.stubs_section_index = @intCast(u16, text_segment.sections.items.len); | | |
| 3942 | | | |
| 3943 | const alignment: u2 = switch (self.base.options.target.cpu.arch) { | 4007 | const alignment: u2 = switch (self.base.options.target.cpu.arch) { |
| 3944 | .x86_64 => 0, | 4008 | .x86_64 => 0, |
| 3945 | .aarch64 => 2, | 4009 | .aarch64 => 2, |
| ... | @@ -3951,32 +4015,19 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -3951,32 +4015,19 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 3951 | else => unreachable, // unhandled architecture type | 4015 | else => unreachable, // unhandled architecture type |
| 3952 | }; | 4016 | }; |
| 3953 | const needed_size = stub_size * self.base.options.symbol_count_hint; | 4017 | const needed_size = stub_size * self.base.options.symbol_count_hint; |
| 3954 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); | 4018 | self.stubs_section_index = try self.allocateSection( |
| 3955 | assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment. | 4019 | self.text_segment_cmd_index.?, |
| 3956 | | 4020 | "__stubs", |
| 3957 | log.debug("found __stubs section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4021 | needed_size, |
| 3958 | | 4022 | alignment, |
| 3959 | try text_segment.addSection(self.base.allocator, "__stubs", .{ | 4023 | .{ |
| 3960 | .addr = text_segment.inner.vmaddr + off, | 4024 | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 3961 | .size = needed_size, | 4025 | .reserved2 = stub_size, |
| 3962 | .offset = @intCast(u32, off), | 4026 | }, |
| 3963 | .@"align" = alignment, | 4027 | ); |
| 3964 | .flags = macho.S_SYMBOL_STUBS | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | | |
| 3965 | .reserved2 = stub_size, | | |
| 3966 | }); | | |
| 3967 | const match = MatchingSection{ | | |
| 3968 | .seg = self.text_segment_cmd_index.?, | | |
| 3969 | .sect = self.stubs_section_index.?, | | |
| 3970 | }; | | |
| 3971 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 3972 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 3973 | self.load_commands_dirty = true; | | |
| 3974 | } | 4028 | } |
| 3975 | | 4029 | |
| 3976 | if (self.stub_helper_section_index == null) { | 4030 | if (self.stub_helper_section_index == null) { |
| 3977 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | | |
| 3978 | self.stub_helper_section_index = @intCast(u16, text_segment.sections.items.len); | | |
| 3979 | | | |
| 3980 | const alignment: u2 = switch (self.base.options.target.cpu.arch) { | 4031 | const alignment: u2 = switch (self.base.options.target.cpu.arch) { |
| 3981 | .x86_64 => 0, | 4032 | .x86_64 => 0, |
| 3982 | .aarch64 => 2, | 4033 | .aarch64 => 2, |
| ... | @@ -3993,25 +4044,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -3993,25 +4044,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 3993 | else => unreachable, | 4044 | else => unreachable, |
| 3994 | }; | 4045 | }; |
| 3995 | const needed_size = stub_size * self.base.options.symbol_count_hint + preamble_size; | 4046 | const needed_size = stub_size * self.base.options.symbol_count_hint + preamble_size; |
| 3996 | const off = text_segment.findFreeSpace(needed_size, @alignOf(u64), self.header_pad); | 4047 | self.stub_helper_section_index = try self.allocateSection( |
| 3997 | assert(off + needed_size <= text_segment.inner.fileoff + text_segment.inner.filesize); // TODO Must expand __TEXT segment. | 4048 | self.text_segment_cmd_index.?, |
| 3998 | | 4049 | "__stub_helper", |
| 3999 | log.debug("found __stub_helper section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4050 | needed_size, |
| 4000 | | 4051 | alignment, |
| 4001 | try text_segment.addSection(self.base.allocator, "__stub_helper", .{ | 4052 | .{ |
| 4002 | .addr = text_segment.inner.vmaddr + off, | 4053 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 4003 | .size = needed_size, | 4054 | }, |
| 4004 | .offset = @intCast(u32, off), | 4055 | ); |
| 4005 | .@"align" = alignment, | | |
| 4006 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, | | |
| 4007 | }); | | |
| 4008 | const match = MatchingSection{ | | |
| 4009 | .seg = self.text_segment_cmd_index.?, | | |
| 4010 | .sect = self.stub_helper_section_index.?, | | |
| 4011 | }; | | |
| 4012 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4013 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4014 | self.load_commands_dirty = true; | | |
| 4015 | } | 4056 | } |
| 4016 | | 4057 | |
| 4017 | if (self.data_const_segment_cmd_index == null) { | 4058 | if (self.data_const_segment_cmd_index == null) { |
| ... | @@ -4020,45 +4061,39 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4020,45 +4061,39 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4020 | const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4061 | const ideal_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4021 | const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size); | 4062 | const needed_size = mem.alignForwardGeneric(u64, padToIdeal(ideal_size), self.page_size); |
| 4022 | | 4063 | |
| 4023 | log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size }); | 4064 | log.debug("found __DATA_CONST segment free space 0x{x} to 0x{x}", .{ |
| | 4065 | address_and_offset.offset, |
| | 4066 | address_and_offset.offset + needed_size, |
| | 4067 | }); |
| 4024 | | 4068 | |
| 4025 | try self.load_commands.append(self.base.allocator, .{ | 4069 | try self.load_commands.append(self.base.allocator, .{ |
| 4026 | .Segment = SegmentCommand.empty("__DATA_CONST", .{ | 4070 | .Segment = .{ |
| 4027 | .vmaddr = address_and_offset.address, | 4071 | .inner = .{ |
| 4028 | .vmsize = needed_size, | 4072 | .segname = makeStaticString("__DATA_CONST"), |
| 4029 | .fileoff = address_and_offset.offset, | 4073 | .vmaddr = address_and_offset.address, |
| 4030 | .filesize = needed_size, | 4074 | .vmsize = needed_size, |
| 4031 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, | 4075 | .fileoff = address_and_offset.offset, |
| 4032 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, | 4076 | .filesize = needed_size, |
| 4033 | }), | 4077 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| | 4078 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| | 4079 | }, |
| | 4080 | }, |
| 4034 | }); | 4081 | }); |
| 4035 | self.load_commands_dirty = true; | 4082 | self.load_commands_dirty = true; |
| 4036 | } | 4083 | } |
| 4037 | | 4084 | |
| 4038 | if (self.got_section_index == null) { | 4085 | if (self.got_section_index == null) { |
| 4039 | const dc_segment = &self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; | | |
| 4040 | self.got_section_index = @intCast(u16, dc_segment.sections.items.len); | | |
| 4041 | | | |
| 4042 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4086 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4043 | const off = dc_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 4087 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4044 | assert(off + needed_size <= dc_segment.inner.fileoff + dc_segment.inner.filesize); // TODO Must expand __DATA_CONST segment. | 4088 | self.got_section_index = try self.allocateSection( |
| 4045 | | 4089 | self.data_const_segment_cmd_index.?, |
| 4046 | log.debug("found __got section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4090 | "__got", |
| 4047 | | 4091 | needed_size, |
| 4048 | try dc_segment.addSection(self.base.allocator, "__got", .{ | 4092 | alignment, |
| 4049 | .addr = dc_segment.inner.vmaddr + off - dc_segment.inner.fileoff, | 4093 | .{ |
| 4050 | .size = needed_size, | 4094 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, |
| 4051 | .offset = @intCast(u32, off), | 4095 | }, |
| 4052 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 4096 | ); |
| 4053 | .flags = macho.S_NON_LAZY_SYMBOL_POINTERS, | | |
| 4054 | }); | | |
| 4055 | const match = MatchingSection{ | | |
| 4056 | .seg = self.data_const_segment_cmd_index.?, | | |
| 4057 | .sect = self.got_section_index.?, | | |
| 4058 | }; | | |
| 4059 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4060 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4061 | self.load_commands_dirty = true; | | |
| 4062 | } | 4097 | } |
| 4063 | | 4098 | |
| 4064 | if (self.data_segment_cmd_index == null) { | 4099 | if (self.data_segment_cmd_index == null) { |
| ... | @@ -4070,175 +4105,115 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4070,175 +4105,115 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4070 | log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size }); | 4105 | log.debug("found __DATA segment free space 0x{x} to 0x{x}", .{ address_and_offset.offset, address_and_offset.offset + needed_size }); |
| 4071 | | 4106 | |
| 4072 | try self.load_commands.append(self.base.allocator, .{ | 4107 | try self.load_commands.append(self.base.allocator, .{ |
| 4073 | .Segment = SegmentCommand.empty("__DATA", .{ | 4108 | .Segment = .{ |
| 4074 | .vmaddr = address_and_offset.address, | 4109 | .inner = .{ |
| 4075 | .vmsize = needed_size, | 4110 | .segname = makeStaticString("__DATA"), |
| 4076 | .fileoff = address_and_offset.offset, | 4111 | .vmaddr = address_and_offset.address, |
| 4077 | .filesize = needed_size, | 4112 | .vmsize = needed_size, |
| 4078 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, | 4113 | .fileoff = address_and_offset.offset, |
| 4079 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, | 4114 | .filesize = needed_size, |
| 4080 | }), | 4115 | .maxprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| | 4116 | .initprot = macho.VM_PROT_READ | macho.VM_PROT_WRITE, |
| | 4117 | }, |
| | 4118 | }, |
| 4081 | }); | 4119 | }); |
| 4082 | self.load_commands_dirty = true; | 4120 | self.load_commands_dirty = true; |
| 4083 | } | 4121 | } |
| 4084 | | 4122 | |
| 4085 | if (self.la_symbol_ptr_section_index == null) { | 4123 | if (self.la_symbol_ptr_section_index == null) { |
| 4086 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 4087 | self.la_symbol_ptr_section_index = @intCast(u16, data_segment.sections.items.len); | | |
| 4088 | | | |
| 4089 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4124 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4090 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 4125 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4091 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. | 4126 | self.la_symbol_ptr_section_index = try self.allocateSection( |
| 4092 | | 4127 | self.data_segment_cmd_index.?, |
| 4093 | log.debug("found __la_symbol_ptr section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4128 | "__la_symbol_ptr", |
| 4094 | | 4129 | needed_size, |
| 4095 | try data_segment.addSection(self.base.allocator, "__la_symbol_ptr", .{ | 4130 | alignment, |
| 4096 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4131 | .{ |
| 4097 | .size = needed_size, | 4132 | .flags = macho.S_LAZY_SYMBOL_POINTERS, |
| 4098 | .offset = @intCast(u32, off), | 4133 | }, |
| 4099 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 4134 | ); |
| 4100 | .flags = macho.S_LAZY_SYMBOL_POINTERS, | | |
| 4101 | }); | | |
| 4102 | const match = MatchingSection{ | | |
| 4103 | .seg = self.data_segment_cmd_index.?, | | |
| 4104 | .sect = self.la_symbol_ptr_section_index.?, | | |
| 4105 | }; | | |
| 4106 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4107 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4108 | self.load_commands_dirty = true; | | |
| 4109 | } | 4135 | } |
| 4110 | | 4136 | |
| 4111 | if (self.data_section_index == null) { | 4137 | if (self.data_section_index == null) { |
| 4112 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 4113 | self.data_section_index = @intCast(u16, data_segment.sections.items.len); | | |
| 4114 | | | |
| 4115 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4138 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4116 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 4139 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4117 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. | 4140 | self.data_section_index = try self.allocateSection( |
| 4118 | | 4141 | self.data_segment_cmd_index.?, |
| 4119 | log.debug("found __data section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4142 | "__data", |
| 4120 | | 4143 | needed_size, |
| 4121 | try data_segment.addSection(self.base.allocator, "__data", .{ | 4144 | alignment, |
| 4122 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4145 | .{}, |
| 4123 | .size = needed_size, | 4146 | ); |
| 4124 | .offset = @intCast(u32, off), | | |
| 4125 | .@"align" = 3, // 2^3 = @sizeOf(u64) | | |
| 4126 | }); | | |
| 4127 | const match = MatchingSection{ | | |
| 4128 | .seg = self.data_segment_cmd_index.?, | | |
| 4129 | .sect = self.data_section_index.?, | | |
| 4130 | }; | | |
| 4131 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4132 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4133 | self.load_commands_dirty = true; | | |
| 4134 | } | 4147 | } |
| 4135 | | 4148 | |
| 4136 | if (self.tlv_section_index == null) { | 4149 | if (self.tlv_section_index == null) { |
| 4137 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 4138 | self.tlv_section_index = @intCast(u16, data_segment.sections.items.len); | | |
| 4139 | | | |
| 4140 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4150 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4141 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 4151 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4142 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. | 4152 | self.tlv_section_index = try self.allocateSection( |
| 4143 | | 4153 | self.data_segment_cmd_index.?, |
| 4144 | log.debug("found __thread_vars section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4154 | "__thread_vars", |
| 4145 | | 4155 | needed_size, |
| 4146 | try data_segment.addSection(self.base.allocator, "__thread_vars", .{ | 4156 | alignment, |
| 4147 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4157 | .{ |
| 4148 | .size = needed_size, | 4158 | .flags = macho.S_THREAD_LOCAL_VARIABLES, |
| 4149 | .offset = @intCast(u32, off), | 4159 | }, |
| 4150 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 4160 | ); |
| 4151 | .flags = macho.S_THREAD_LOCAL_VARIABLES, | | |
| 4152 | }); | | |
| 4153 | const match = MatchingSection{ | | |
| 4154 | .seg = self.data_segment_cmd_index.?, | | |
| 4155 | .sect = self.tlv_section_index.?, | | |
| 4156 | }; | | |
| 4157 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4158 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4159 | self.load_commands_dirty = true; | | |
| 4160 | } | 4161 | } |
| 4161 | | 4162 | |
| 4162 | if (self.tlv_data_section_index == null) { | 4163 | if (self.tlv_data_section_index == null) { |
| 4163 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 4164 | self.tlv_data_section_index = @intCast(u16, data_segment.sections.items.len); | | |
| 4165 | | | |
| 4166 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4164 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4167 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 4165 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4168 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. | 4166 | self.tlv_data_section_index = try self.allocateSection( |
| 4169 | | 4167 | self.data_segment_cmd_index.?, |
| 4170 | log.debug("found __thread_data section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4168 | "__thread_data", |
| 4171 | | 4169 | needed_size, |
| 4172 | try data_segment.addSection(self.base.allocator, "__thread_data", .{ | 4170 | alignment, |
| 4173 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4171 | .{ |
| 4174 | .size = needed_size, | 4172 | .flags = macho.S_THREAD_LOCAL_REGULAR, |
| 4175 | .offset = @intCast(u32, off), | 4173 | }, |
| 4176 | .@"align" = 3, // 2^3 = @sizeOf(u64) | 4174 | ); |
| 4177 | .flags = macho.S_THREAD_LOCAL_REGULAR, | | |
| 4178 | }); | | |
| 4179 | const match = MatchingSection{ | | |
| 4180 | .seg = self.data_segment_cmd_index.?, | | |
| 4181 | .sect = self.tlv_data_section_index.?, | | |
| 4182 | }; | | |
| 4183 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4184 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4185 | self.load_commands_dirty = true; | | |
| 4186 | } | 4175 | } |
| 4187 | | 4176 | |
| 4188 | if (self.tlv_bss_section_index == null) { | 4177 | if (self.tlv_bss_section_index == null) { |
| 4189 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 4190 | self.tlv_bss_section_index = @intCast(u16, data_segment.sections.items.len); | | |
| 4191 | | | |
| 4192 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4178 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4193 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 4179 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4194 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. | 4180 | self.tlv_bss_section_index = try self.allocateSection( |
| 4195 | | 4181 | self.data_segment_cmd_index.?, |
| 4196 | log.debug("found __thread_bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4182 | "__thread_bss", |
| | 4183 | needed_size, |
| | 4184 | alignment, |
| | 4185 | .{ |
| | 4186 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| | 4187 | }, |
| | 4188 | ); |
| 4197 | | 4189 | |
| 4198 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the | 4190 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the |
| 4199 | // beginning of the file. | 4191 | // beginning of the file. |
| 4200 | self.tlv_bss_file_offset = off; | 4192 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 4201 | try data_segment.addSection(self.base.allocator, "__thread_bss", .{ | 4193 | const out_sect = &seg.sections.items[self.tlv_bss_section_index.?]; |
| 4202 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4194 | self.tlv_bss_file_offset = out_sect.offset; |
| 4203 | .size = needed_size, | 4195 | out_sect.offset = 0; |
| 4204 | .@"align" = 3, // 2^3 = @sizeOf(u64) | | |
| 4205 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, | | |
| 4206 | }); | | |
| 4207 | const match = MatchingSection{ | | |
| 4208 | .seg = self.data_segment_cmd_index.?, | | |
| 4209 | .sect = self.tlv_bss_section_index.?, | | |
| 4210 | }; | | |
| 4211 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4212 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4213 | self.load_commands_dirty = true; | | |
| 4214 | } | 4196 | } |
| 4215 | | 4197 | |
| 4216 | if (self.bss_section_index == null) { | 4198 | if (self.bss_section_index == null) { |
| 4217 | const data_segment = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; | | |
| 4218 | self.bss_section_index = @intCast(u16, data_segment.sections.items.len); | | |
| 4219 | | | |
| 4220 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; | 4199 | const needed_size = @sizeOf(u64) * self.base.options.symbol_count_hint; |
| 4221 | const off = data_segment.findFreeSpace(needed_size, @alignOf(u64), null); | 4200 | const alignment: u16 = 3; // 2^3 = @sizeOf(u64) |
| 4222 | assert(off + needed_size <= data_segment.inner.fileoff + data_segment.inner.filesize); // TODO Must expand __DATA segment. | 4201 | self.bss_section_index = try self.allocateSection( |
| 4223 | | 4202 | self.data_segment_cmd_index.?, |
| 4224 | log.debug("found __bss section free space 0x{x} to 0x{x}", .{ off, off + needed_size }); | 4203 | "__bss", |
| | 4204 | needed_size, |
| | 4205 | alignment, |
| | 4206 | .{ |
| | 4207 | .flags = macho.S_ZEROFILL, |
| | 4208 | }, |
| | 4209 | ); |
| 4225 | | 4210 | |
| 4226 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the | 4211 | // We keep offset to the section in a separate variable as the actual section is usually pointing at the |
| 4227 | // beginning of the file. | 4212 | // beginning of the file. |
| 4228 | self.bss_file_offset = off; | 4213 | const seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 4229 | try data_segment.addSection(self.base.allocator, "__bss", .{ | 4214 | const out_sect = &seg.sections.items[self.bss_section_index.?]; |
| 4230 | .addr = data_segment.inner.vmaddr + off - data_segment.inner.fileoff, | 4215 | self.bss_file_offset = out_sect.offset; |
| 4231 | .size = 0, | 4216 | out_sect.offset = 0; |
| 4232 | .@"align" = 3, // 2^3 = @sizeOf(u64) | | |
| 4233 | .flags = macho.S_ZEROFILL, | | |
| 4234 | }); | | |
| 4235 | const match = MatchingSection{ | | |
| 4236 | .seg = self.data_segment_cmd_index.?, | | |
| 4237 | .sect = self.bss_section_index.?, | | |
| 4238 | }; | | |
| 4239 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); | | |
| 4240 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); | | |
| 4241 | self.load_commands_dirty = true; | | |
| 4242 | } | 4217 | } |
| 4243 | | 4218 | |
| 4244 | if (self.linkedit_segment_cmd_index == null) { | 4219 | if (self.linkedit_segment_cmd_index == null) { |
| ... | @@ -4248,12 +4223,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4248,12 +4223,15 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4248 | log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset}); | 4223 | log.debug("found __LINKEDIT segment free space at 0x{x}", .{address_and_offset.offset}); |
| 4249 | | 4224 | |
| 4250 | try self.load_commands.append(self.base.allocator, .{ | 4225 | try self.load_commands.append(self.base.allocator, .{ |
| 4251 | .Segment = SegmentCommand.empty("__LINKEDIT", .{ | 4226 | .Segment = .{ |
| 4252 | .vmaddr = address_and_offset.address, | 4227 | .inner = .{ |
| 4253 | .fileoff = address_and_offset.offset, | 4228 | .segname = makeStaticString("__LINKEDIT"), |
| 4254 | .maxprot = macho.VM_PROT_READ, | 4229 | .vmaddr = address_and_offset.address, |
| 4255 | .initprot = macho.VM_PROT_READ, | 4230 | .fileoff = address_and_offset.offset, |
| 4256 | }), | 4231 | .maxprot = macho.VM_PROT_READ, |
| | 4232 | .initprot = macho.VM_PROT_READ, |
| | 4233 | }, |
| | 4234 | }, |
| 4257 | }); | 4235 | }); |
| 4258 | self.load_commands_dirty = true; | 4236 | self.load_commands_dirty = true; |
| 4259 | } | 4237 | } |
| ... | @@ -4485,6 +4463,67 @@ pub fn populateMissingMetadata(self: *MachO) !void { | ... | @@ -4485,6 +4463,67 @@ pub fn populateMissingMetadata(self: *MachO) !void { |
| 4485 | } | 4463 | } |
| 4486 | } | 4464 | } |
| 4487 | | 4465 | |
| | 4466 | const AllocateSectionOpts = struct { |
| | 4467 | flags: u32 = macho.S_REGULAR, |
| | 4468 | reserved1: u32 = 0, |
| | 4469 | reserved2: u32 = 0, |
| | 4470 | }; |
| | 4471 | |
| | 4472 | fn allocateSection( |
| | 4473 | self: *MachO, |
| | 4474 | segment_id: u16, |
| | 4475 | sectname: []const u8, |
| | 4476 | size: u64, |
| | 4477 | alignment: u32, |
| | 4478 | opts: AllocateSectionOpts, |
| | 4479 | ) !u16 { |
| | 4480 | const seg = &self.load_commands.items[segment_id].Segment; |
| | 4481 | var sect = macho.section_64{ |
| | 4482 | .sectname = makeStaticString(sectname), |
| | 4483 | .segname = seg.inner.segname, |
| | 4484 | .size = @intCast(u32, size), |
| | 4485 | .@"align" = alignment, |
| | 4486 | .flags = opts.flags, |
| | 4487 | .reserved1 = opts.reserved1, |
| | 4488 | .reserved2 = opts.reserved2, |
| | 4489 | }; |
| | 4490 | |
| | 4491 | const use_stage1 = build_options.is_stage1 and self.base.options.use_stage1; |
| | 4492 | if (!use_stage1) { |
| | 4493 | const alignment_pow_2 = try math.powi(u32, 2, alignment); |
| | 4494 | const padding: ?u64 = if (segment_id == self.text_segment_cmd_index.?) self.header_pad else null; |
| | 4495 | const off = seg.findFreeSpace(size, alignment_pow_2, padding); |
| | 4496 | |
| | 4497 | assert(off + size <= seg.inner.fileoff + seg.inner.filesize); // TODO expand |
| | 4498 | |
| | 4499 | log.debug("found {s},{s} section free space 0x{x} to 0x{x}", .{ |
| | 4500 | commands.segmentName(sect), |
| | 4501 | commands.sectionName(sect), |
| | 4502 | off, |
| | 4503 | off + size, |
| | 4504 | }); |
| | 4505 | |
| | 4506 | sect.addr = seg.inner.vmaddr + off - seg.inner.fileoff; |
| | 4507 | sect.offset = @intCast(u32, off); |
| | 4508 | } |
| | 4509 | |
| | 4510 | const index = @intCast(u16, seg.sections.items.len); |
| | 4511 | try seg.sections.append(self.base.allocator, sect); |
| | 4512 | seg.inner.cmdsize += @sizeOf(macho.section_64); |
| | 4513 | seg.inner.nsects += 1; |
| | 4514 | |
| | 4515 | const match = MatchingSection{ |
| | 4516 | .seg = segment_id, |
| | 4517 | .sect = index, |
| | 4518 | }; |
| | 4519 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); |
| | 4520 | try self.block_free_lists.putNoClobber(self.base.allocator, match, .{}); |
| | 4521 | |
| | 4522 | self.load_commands_dirty = true; |
| | 4523 | |
| | 4524 | return index; |
| | 4525 | } |
| | 4526 | |
| 4488 | fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { | 4527 | fn allocateTextBlock(self: *MachO, text_block: *TextBlock, new_block_size: u64, alignment: u64) !u64 { |
| 4489 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; | 4528 | const text_segment = &self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 4490 | const text_section = &text_segment.sections.items[self.text_section_index.?]; | 4529 | const text_section = &text_segment.sections.items[self.text_section_index.?]; |
| ... | @@ -5513,6 +5552,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { | ... | @@ -5513,6 +5552,13 @@ pub fn padToIdeal(actual_size: anytype) @TypeOf(actual_size) { |
| 5513 | std.math.maxInt(@TypeOf(actual_size)); | 5552 | std.math.maxInt(@TypeOf(actual_size)); |
| 5514 | } | 5553 | } |
| 5515 | | 5554 | |
| | 5555 | pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| | 5556 | var buf = [_]u8{0} ** 16; |
| | 5557 | assert(bytes.len <= buf.len); |
| | 5558 | mem.copy(u8, &buf, bytes); |
| | 5559 | return buf; |
| | 5560 | } |
| | 5561 | |
| 5516 | pub fn makeString(self: *MachO, string: []const u8) !u32 { | 5562 | pub fn makeString(self: *MachO, string: []const u8) !u32 { |
| 5517 | if (self.strtab_dir.getAdapted(@as([]const u8, string), StringSliceAdapter{ .strtab = &self.strtab })) |off| { | 5563 | if (self.strtab_dir.getAdapted(@as([]const u8, string), StringSliceAdapter{ .strtab = &self.strtab })) |off| { |
| 5518 | log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off }); | 5564 | log.debug("reusing string '{s}' at offset 0x{x}", .{ string, off }); |