| ... | ... | @@ -789,6 +789,31 @@ pub fn flush(self: *MachO, comp: *Compilation) !void { |
| 789 | 789 | try self.allocateTextBlocks(); |
| 790 | 790 | try self.flushZld(); |
| 791 | 791 | } else { |
| 792 | try self.parseTextBlocks(); |
| 793 | try self.allocateGlobalSymbols(); |
| 794 | { |
| 795 | log.debug("locals:", .{}); |
| 796 | for (self.locals.items) |sym| { |
| 797 | log.debug(" {s}: {}", .{ self.getString(sym.n_strx), sym }); |
| 798 | } |
| 799 | log.debug("globals:", .{}); |
| 800 | for (self.globals.items) |sym| { |
| 801 | log.debug(" {s}: {}", .{ self.getString(sym.n_strx), sym }); |
| 802 | } |
| 803 | log.debug("undefs:", .{}); |
| 804 | for (self.undefs.items) |sym| { |
| 805 | log.debug(" {s}: {}", .{ self.getString(sym.n_strx), sym }); |
| 806 | } |
| 807 | log.debug("unresolved:", .{}); |
| 808 | for (self.unresolved.keys()) |key| { |
| 809 | log.debug(" {d} => {s}", .{ key, self.unresolved.get(key).? }); |
| 810 | } |
| 811 | log.debug("resolved:", .{}); |
| 812 | var it = self.symbol_resolver.iterator(); |
| 813 | while (it.next()) |entry| { |
| 814 | log.debug(" {s} => {}", .{ self.getString(entry.key_ptr.*), entry.value_ptr.* }); |
| 815 | } |
| 816 | } |
| 792 | 817 | try self.writeAtoms(); |
| 793 | 818 | try self.flushModule(comp); |
| 794 | 819 | } |
| ... | ... | @@ -1114,12 +1139,14 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1114 | 1139 | const segname = commands.segmentName(sect); |
| 1115 | 1140 | const sectname = commands.sectionName(sect); |
| 1116 | 1141 | |
| 1142 | var needs_allocation = false; |
| 1117 | 1143 | const res: ?MatchingSection = blk: { |
| 1118 | 1144 | switch (commands.sectionType(sect)) { |
| 1119 | 1145 | macho.S_4BYTE_LITERALS, macho.S_8BYTE_LITERALS, macho.S_16BYTE_LITERALS => { |
| 1120 | 1146 | if (self.text_const_section_index == null) { |
| 1121 | 1147 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| 1122 | 1148 | try text_seg.addSection(self.base.allocator, "__const", .{}); |
| 1149 | needs_allocation = true; |
| 1123 | 1150 | } |
| 1124 | 1151 | |
| 1125 | 1152 | break :blk .{ |
| ... | ... | @@ -1136,6 +1163,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1136 | 1163 | try text_seg.addSection(self.base.allocator, "__objc_methname", .{ |
| 1137 | 1164 | .flags = macho.S_CSTRING_LITERALS, |
| 1138 | 1165 | }); |
| 1166 | needs_allocation = true; |
| 1139 | 1167 | } |
| 1140 | 1168 | |
| 1141 | 1169 | break :blk .{ |
| ... | ... | @@ -1148,6 +1176,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1148 | 1176 | try text_seg.addSection(self.base.allocator, "__objc_methtype", .{ |
| 1149 | 1177 | .flags = macho.S_CSTRING_LITERALS, |
| 1150 | 1178 | }); |
| 1179 | needs_allocation = true; |
| 1151 | 1180 | } |
| 1152 | 1181 | |
| 1153 | 1182 | break :blk .{ |
| ... | ... | @@ -1158,6 +1187,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1158 | 1187 | if (self.objc_classname_section_index == null) { |
| 1159 | 1188 | self.objc_classname_section_index = @intCast(u16, text_seg.sections.items.len); |
| 1160 | 1189 | try text_seg.addSection(self.base.allocator, "__objc_classname", .{}); |
| 1190 | needs_allocation = true; |
| 1161 | 1191 | } |
| 1162 | 1192 | |
| 1163 | 1193 | break :blk .{ |
| ... | ... | @@ -1171,6 +1201,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1171 | 1201 | try text_seg.addSection(self.base.allocator, "__cstring", .{ |
| 1172 | 1202 | .flags = macho.S_CSTRING_LITERALS, |
| 1173 | 1203 | }); |
| 1204 | needs_allocation = true; |
| 1174 | 1205 | } |
| 1175 | 1206 | |
| 1176 | 1207 | break :blk .{ |
| ... | ... | @@ -1185,6 +1216,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1185 | 1216 | try data_seg.addSection(self.base.allocator, "__objc_selrefs", .{ |
| 1186 | 1217 | .flags = macho.S_LITERAL_POINTERS, |
| 1187 | 1218 | }); |
| 1219 | needs_allocation = true; |
| 1188 | 1220 | } |
| 1189 | 1221 | |
| 1190 | 1222 | break :blk .{ |
| ... | ... | @@ -1202,6 +1234,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1202 | 1234 | try data_const_seg.addSection(self.base.allocator, "__mod_init_func", .{ |
| 1203 | 1235 | .flags = macho.S_MOD_INIT_FUNC_POINTERS, |
| 1204 | 1236 | }); |
| 1237 | needs_allocation = true; |
| 1205 | 1238 | } |
| 1206 | 1239 | |
| 1207 | 1240 | break :blk .{ |
| ... | ... | @@ -1215,6 +1248,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1215 | 1248 | try data_const_seg.addSection(self.base.allocator, "__mod_term_func", .{ |
| 1216 | 1249 | .flags = macho.S_MOD_TERM_FUNC_POINTERS, |
| 1217 | 1250 | }); |
| 1251 | needs_allocation = true; |
| 1218 | 1252 | } |
| 1219 | 1253 | |
| 1220 | 1254 | break :blk .{ |
| ... | ... | @@ -1228,6 +1262,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1228 | 1262 | try data_seg.addSection(self.base.allocator, "__bss", .{ |
| 1229 | 1263 | .flags = macho.S_ZEROFILL, |
| 1230 | 1264 | }); |
| 1265 | needs_allocation = true; |
| 1231 | 1266 | } |
| 1232 | 1267 | |
| 1233 | 1268 | break :blk .{ |
| ... | ... | @@ -1241,6 +1276,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1241 | 1276 | try data_seg.addSection(self.base.allocator, "__thread_vars", .{ |
| 1242 | 1277 | .flags = macho.S_THREAD_LOCAL_VARIABLES, |
| 1243 | 1278 | }); |
| 1279 | needs_allocation = true; |
| 1244 | 1280 | } |
| 1245 | 1281 | |
| 1246 | 1282 | break :blk .{ |
| ... | ... | @@ -1254,6 +1290,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1254 | 1290 | try data_seg.addSection(self.base.allocator, "__thread_data", .{ |
| 1255 | 1291 | .flags = macho.S_THREAD_LOCAL_REGULAR, |
| 1256 | 1292 | }); |
| 1293 | needs_allocation = true; |
| 1257 | 1294 | } |
| 1258 | 1295 | |
| 1259 | 1296 | break :blk .{ |
| ... | ... | @@ -1267,6 +1304,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1267 | 1304 | try data_seg.addSection(self.base.allocator, "__thread_bss", .{ |
| 1268 | 1305 | .flags = macho.S_THREAD_LOCAL_ZEROFILL, |
| 1269 | 1306 | }); |
| 1307 | needs_allocation = true; |
| 1270 | 1308 | } |
| 1271 | 1309 | |
| 1272 | 1310 | break :blk .{ |
| ... | ... | @@ -1281,6 +1319,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1281 | 1319 | if (self.eh_frame_section_index == null) { |
| 1282 | 1320 | self.eh_frame_section_index = @intCast(u16, text_seg.sections.items.len); |
| 1283 | 1321 | try text_seg.addSection(self.base.allocator, "__eh_frame", .{}); |
| 1322 | needs_allocation = true; |
| 1284 | 1323 | } |
| 1285 | 1324 | |
| 1286 | 1325 | break :blk .{ |
| ... | ... | @@ -1293,6 +1332,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1293 | 1332 | if (self.data_const_section_index == null) { |
| 1294 | 1333 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 1295 | 1334 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); |
| 1335 | needs_allocation = true; |
| 1296 | 1336 | } |
| 1297 | 1337 | |
| 1298 | 1338 | break :blk .{ |
| ... | ... | @@ -1307,6 +1347,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1307 | 1347 | try text_seg.addSection(self.base.allocator, "__text", .{ |
| 1308 | 1348 | .flags = macho.S_REGULAR | macho.S_ATTR_PURE_INSTRUCTIONS | macho.S_ATTR_SOME_INSTRUCTIONS, |
| 1309 | 1349 | }); |
| 1350 | needs_allocation = true; |
| 1310 | 1351 | } |
| 1311 | 1352 | |
| 1312 | 1353 | break :blk .{ |
| ... | ... | @@ -1329,6 +1370,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1329 | 1370 | if (self.ustring_section_index == null) { |
| 1330 | 1371 | self.ustring_section_index = @intCast(u16, text_seg.sections.items.len); |
| 1331 | 1372 | try text_seg.addSection(self.base.allocator, "__ustring", .{}); |
| 1373 | needs_allocation = true; |
| 1332 | 1374 | } |
| 1333 | 1375 | |
| 1334 | 1376 | break :blk .{ |
| ... | ... | @@ -1339,6 +1381,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1339 | 1381 | if (self.gcc_except_tab_section_index == null) { |
| 1340 | 1382 | self.gcc_except_tab_section_index = @intCast(u16, text_seg.sections.items.len); |
| 1341 | 1383 | try text_seg.addSection(self.base.allocator, "__gcc_except_tab", .{}); |
| 1384 | needs_allocation = true; |
| 1342 | 1385 | } |
| 1343 | 1386 | |
| 1344 | 1387 | break :blk .{ |
| ... | ... | @@ -1349,6 +1392,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1349 | 1392 | if (self.objc_methlist_section_index == null) { |
| 1350 | 1393 | self.objc_methlist_section_index = @intCast(u16, text_seg.sections.items.len); |
| 1351 | 1394 | try text_seg.addSection(self.base.allocator, "__objc_methlist", .{}); |
| 1395 | needs_allocation = true; |
| 1352 | 1396 | } |
| 1353 | 1397 | |
| 1354 | 1398 | break :blk .{ |
| ... | ... | @@ -1364,6 +1408,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1364 | 1408 | if (self.data_const_section_index == null) { |
| 1365 | 1409 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 1366 | 1410 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); |
| 1411 | needs_allocation = true; |
| 1367 | 1412 | } |
| 1368 | 1413 | |
| 1369 | 1414 | break :blk .{ |
| ... | ... | @@ -1374,6 +1419,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1374 | 1419 | if (self.text_const_section_index == null) { |
| 1375 | 1420 | self.text_const_section_index = @intCast(u16, text_seg.sections.items.len); |
| 1376 | 1421 | try text_seg.addSection(self.base.allocator, "__const", .{}); |
| 1422 | needs_allocation = true; |
| 1377 | 1423 | } |
| 1378 | 1424 | |
| 1379 | 1425 | break :blk .{ |
| ... | ... | @@ -1387,6 +1433,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1387 | 1433 | if (self.data_const_section_index == null) { |
| 1388 | 1434 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 1389 | 1435 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); |
| 1436 | needs_allocation = true; |
| 1390 | 1437 | } |
| 1391 | 1438 | |
| 1392 | 1439 | break :blk .{ |
| ... | ... | @@ -1400,6 +1447,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1400 | 1447 | if (self.data_const_section_index == null) { |
| 1401 | 1448 | self.data_const_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 1402 | 1449 | try data_const_seg.addSection(self.base.allocator, "__const", .{}); |
| 1450 | needs_allocation = true; |
| 1403 | 1451 | } |
| 1404 | 1452 | |
| 1405 | 1453 | break :blk .{ |
| ... | ... | @@ -1410,6 +1458,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1410 | 1458 | if (self.objc_cfstring_section_index == null) { |
| 1411 | 1459 | self.objc_cfstring_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 1412 | 1460 | try data_const_seg.addSection(self.base.allocator, "__cfstring", .{}); |
| 1461 | needs_allocation = true; |
| 1413 | 1462 | } |
| 1414 | 1463 | |
| 1415 | 1464 | break :blk .{ |
| ... | ... | @@ -1420,6 +1469,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1420 | 1469 | if (self.objc_classlist_section_index == null) { |
| 1421 | 1470 | self.objc_classlist_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 1422 | 1471 | try data_const_seg.addSection(self.base.allocator, "__objc_classlist", .{}); |
| 1472 | needs_allocation = true; |
| 1423 | 1473 | } |
| 1424 | 1474 | |
| 1425 | 1475 | break :blk .{ |
| ... | ... | @@ -1430,6 +1480,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1430 | 1480 | if (self.objc_imageinfo_section_index == null) { |
| 1431 | 1481 | self.objc_imageinfo_section_index = @intCast(u16, data_const_seg.sections.items.len); |
| 1432 | 1482 | try data_const_seg.addSection(self.base.allocator, "__objc_imageinfo", .{}); |
| 1483 | needs_allocation = true; |
| 1433 | 1484 | } |
| 1434 | 1485 | |
| 1435 | 1486 | break :blk .{ |
| ... | ... | @@ -1440,6 +1491,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1440 | 1491 | if (self.objc_const_section_index == null) { |
| 1441 | 1492 | self.objc_const_section_index = @intCast(u16, data_seg.sections.items.len); |
| 1442 | 1493 | try data_seg.addSection(self.base.allocator, "__objc_const", .{}); |
| 1494 | needs_allocation = true; |
| 1443 | 1495 | } |
| 1444 | 1496 | |
| 1445 | 1497 | break :blk .{ |
| ... | ... | @@ -1450,6 +1502,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1450 | 1502 | if (self.objc_classrefs_section_index == null) { |
| 1451 | 1503 | self.objc_classrefs_section_index = @intCast(u16, data_seg.sections.items.len); |
| 1452 | 1504 | try data_seg.addSection(self.base.allocator, "__objc_classrefs", .{}); |
| 1505 | needs_allocation = true; |
| 1453 | 1506 | } |
| 1454 | 1507 | |
| 1455 | 1508 | break :blk .{ |
| ... | ... | @@ -1460,6 +1513,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1460 | 1513 | if (self.objc_data_section_index == null) { |
| 1461 | 1514 | self.objc_data_section_index = @intCast(u16, data_seg.sections.items.len); |
| 1462 | 1515 | try data_seg.addSection(self.base.allocator, "__objc_data", .{}); |
| 1516 | needs_allocation = true; |
| 1463 | 1517 | } |
| 1464 | 1518 | |
| 1465 | 1519 | break :blk .{ |
| ... | ... | @@ -1470,6 +1524,7 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1470 | 1524 | if (self.data_section_index == null) { |
| 1471 | 1525 | self.data_section_index = @intCast(u16, data_seg.sections.items.len); |
| 1472 | 1526 | try data_seg.addSection(self.base.allocator, "__data", .{}); |
| 1527 | needs_allocation = true; |
| 1473 | 1528 | } |
| 1474 | 1529 | |
| 1475 | 1530 | break :blk .{ |
| ... | ... | @@ -1494,6 +1549,36 @@ pub fn getMatchingSection(self: *MachO, sect: macho.section_64) !?MatchingSectio |
| 1494 | 1549 | if (res) |match| { |
| 1495 | 1550 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); |
| 1496 | 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 | } |
| 1497 | 1582 | } |
| 1498 | 1583 | |
| 1499 | 1584 | return res; |
| ... | ... | @@ -1759,23 +1844,41 @@ pub fn createEmptyAtom(self: *MachO, local_sym_index: u32, size: u64, alignment: |
| 1759 | 1844 | } |
| 1760 | 1845 | |
| 1761 | 1846 | pub fn allocateAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !u64 { |
| 1762 | | // TODO converge with `allocateTextBlock` |
| 1763 | | const seg = self.load_commands.items[match.seg].Segment; |
| 1764 | | const sect = seg.sections.items[match.sect]; |
| 1847 | const seg = &self.load_commands.items[match.seg].Segment; |
| 1848 | const sect = &seg.sections.items[match.sect]; |
| 1765 | 1849 | const sym = &self.locals.items[atom.local_sym_index]; |
| 1766 | | const base_addr = if (self.blocks.get(match)) |last| blk: { |
| 1850 | |
| 1851 | var atom_placement: ?*TextBlock = null; |
| 1852 | |
| 1853 | // TODO converge with `allocateTextBlock` and handle free list |
| 1854 | const vaddr = if (self.blocks.get(match)) |last| blk: { |
| 1767 | 1855 | const last_atom_sym = self.locals.items[last.local_sym_index]; |
| 1768 | | break :blk last_atom_sym.n_value + last.size; |
| 1856 | const ideal_capacity = padToIdeal(last.size); |
| 1857 | const ideal_capacity_end_vaddr = last_atom_sym.n_value + ideal_capacity; |
| 1858 | const last_atom_alignment = try math.powi(u32, 2, atom.alignment); |
| 1859 | const new_start_vaddr = mem.alignForwardGeneric(u64, ideal_capacity_end_vaddr, last_atom_alignment); |
| 1860 | atom_placement = last; |
| 1861 | break :blk new_start_vaddr; |
| 1769 | 1862 | } else sect.addr; |
| 1770 | | const atom_alignment = try math.powi(u32, 2, atom.alignment); |
| 1771 | | const vaddr = mem.alignForwardGeneric(u64, base_addr, atom_alignment); |
| 1863 | |
| 1772 | 1864 | log.debug("allocating atom for symbol {s} at address 0x{x}", .{ self.getString(sym.n_strx), vaddr }); |
| 1773 | 1865 | |
| 1774 | | const expand_section = true; |
| 1866 | const expand_section = atom_placement == null or atom_placement.?.next == null; |
| 1775 | 1867 | if (expand_section) { |
| 1776 | | // Expand the section, possibly shifting all the atoms for the sections following it. |
| 1777 | | // It might also be needed to shift entire segments too if there is not enough |
| 1778 | | // padding left. |
| 1868 | const needed_size = (vaddr + atom.size) - sect.addr; |
| 1869 | const end_addr = blk: { |
| 1870 | const next_ordinal = self.section_ordinals.getIndex(match).?; // Ordinals are +1 to begin with. |
| 1871 | const end_addr = if (self.section_ordinals.keys().len > next_ordinal) inner: { |
| 1872 | const next_match = self.section_ordinals.keys()[next_ordinal]; |
| 1873 | const next_seg = self.load_commands.items[next_match.seg].Segment; |
| 1874 | const next_sect = next_seg.sections.items[next_match.sect]; |
| 1875 | break :inner next_sect.addr; |
| 1876 | } else seg.inner.filesize; |
| 1877 | break :blk end_addr; |
| 1878 | }; |
| 1879 | assert(needed_size <= end_addr); // TODO must expand the section |
| 1880 | sect.size = needed_size; |
| 1881 | self.load_commands_dirty = true; |
| 1779 | 1882 | } |
| 1780 | 1883 | const n_sect = @intCast(u8, self.section_ordinals.getIndex(match).? + 1); |
| 1781 | 1884 | sym.n_value = vaddr; |
| ... | ... | @@ -1828,6 +1931,21 @@ pub fn writeAtom(self: *MachO, atom: *TextBlock, match: MatchingSection) !void { |
| 1828 | 1931 | try self.writeLocalSymbol(atom.local_sym_index); |
| 1829 | 1932 | } |
| 1830 | 1933 | |
| 1934 | fn allocateGlobalSymbols(self: *MachO) !void { |
| 1935 | // TODO should we do this in `allocateAtom` (or similar)? Then, we would need to |
| 1936 | // store the link atom -> globals somewhere. |
| 1937 | var sym_it = self.symbol_resolver.valueIterator(); |
| 1938 | while (sym_it.next()) |resolv| { |
| 1939 | if (resolv.where != .global) continue; |
| 1940 | |
| 1941 | assert(resolv.local_sym_index != 0); |
| 1942 | const local_sym = self.locals.items[resolv.local_sym_index]; |
| 1943 | const sym = &self.globals.items[resolv.where_index]; |
| 1944 | sym.n_value = local_sym.n_value; |
| 1945 | sym.n_sect = local_sym.n_sect; |
| 1946 | } |
| 1947 | } |
| 1948 | |
| 1831 | 1949 | pub fn allocateAtomStage1(self: *MachO, atom: *TextBlock, match: MatchingSection) !void { |
| 1832 | 1950 | // Update target section's metadata |
| 1833 | 1951 | // TODO should we update segment's size here too? |
| ... | ... | @@ -2313,14 +2431,14 @@ fn resolveSymbolsInObject( |
| 2313 | 2431 | continue; |
| 2314 | 2432 | }, |
| 2315 | 2433 | .undef => { |
| 2316 | | const undef = &self.undefs.items[resolv.where_index]; |
| 2317 | | undef.* = .{ |
| 2318 | | .n_strx = 0, |
| 2319 | | .n_type = macho.N_UNDF, |
| 2320 | | .n_sect = 0, |
| 2321 | | .n_desc = 0, |
| 2322 | | .n_value = 0, |
| 2323 | | }; |
| 2434 | // const undef = &self.undefs.items[resolv.where_index]; |
| 2435 | // undef.* = .{ |
| 2436 | // .n_strx = 0, |
| 2437 | // .n_type = macho.N_UNDF, |
| 2438 | // .n_sect = 0, |
| 2439 | // .n_desc = 0, |
| 2440 | // .n_value = 0, |
| 2441 | // }; |
| 2324 | 2442 | _ = self.unresolved.fetchSwapRemove(resolv.where_index); |
| 2325 | 2443 | }, |
| 2326 | 2444 | } |
| ... | ... | @@ -2457,18 +2575,9 @@ fn resolveSymbols(self: *MachO) !void { |
| 2457 | 2575 | // text blocks for each tentative defintion. |
| 2458 | 2576 | while (tentatives.popOrNull()) |entry| { |
| 2459 | 2577 | const sym = &self.globals.items[entry.key]; |
| 2460 | | const match: MatchingSection = blk: { |
| 2461 | | if (self.bss_section_index == null) { |
| 2462 | | const data_seg = &self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 2463 | | self.bss_section_index = @intCast(u16, data_seg.sections.items.len); |
| 2464 | | try data_seg.addSection(self.base.allocator, "__bss", .{ |
| 2465 | | .flags = macho.S_ZEROFILL, |
| 2466 | | }); |
| 2467 | | } |
| 2468 | | break :blk .{ |
| 2469 | | .seg = self.data_segment_cmd_index.?, |
| 2470 | | .sect = self.bss_section_index.?, |
| 2471 | | }; |
| 2578 | const match = MatchingSection{ |
| 2579 | .seg = self.data_segment_cmd_index.?, |
| 2580 | .sect = self.bss_section_index.?, |
| 2472 | 2581 | }; |
| 2473 | 2582 | _ = try self.section_ordinals.getOrPut(self.base.allocator, match); |
| 2474 | 2583 | |