| ... | ... | @@ -75,6 +75,7 @@ bss_section_index: ?u16 = null, |
| 75 | 75 | |
| 76 | 76 | symtab: std.StringArrayHashMapUnmanaged(Symbol) = .{}, |
| 77 | 77 | strtab: std.ArrayListUnmanaged(u8) = .{}, |
| 78 | strtab_dir: std.StringHashMapUnmanaged(u32) = .{}, |
| 78 | 79 | |
| 79 | 80 | threadlocal_offsets: std.ArrayListUnmanaged(u64) = .{}, |
| 80 | 81 | local_rebases: std.ArrayListUnmanaged(Pointer) = .{}, |
| ... | ... | @@ -94,7 +95,6 @@ const GotEntry = struct { |
| 94 | 95 | index: u32, |
| 95 | 96 | target_addr: u64, |
| 96 | 97 | file: u16, |
| 97 | | local_index: u32, |
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | 100 | const MappingKey = struct { |
| ... | ... | @@ -153,10 +153,18 @@ pub fn deinit(self: *Zld) void { |
| 153 | 153 | self.unhandled_sections.deinit(self.allocator); |
| 154 | 154 | |
| 155 | 155 | for (self.symtab.items()) |*entry| { |
| 156 | | self.allocator.free(entry.key); |
| 156 | entry.value.deinit(self.allocator); |
| 157 | 157 | } |
| 158 | 158 | self.symtab.deinit(self.allocator); |
| 159 | 159 | self.strtab.deinit(self.allocator); |
| 160 | |
| 161 | { |
| 162 | var it = self.strtab_dir.iterator(); |
| 163 | while (it.next()) |entry| { |
| 164 | self.allocator.free(entry.key); |
| 165 | } |
| 166 | } |
| 167 | self.strtab_dir.deinit(self.allocator); |
| 160 | 168 | } |
| 161 | 169 | |
| 162 | 170 | pub fn closeFiles(self: Zld) void { |
| ... | ... | @@ -274,7 +282,7 @@ fn parseInputFiles(self: *Zld, files: []const []const u8) !void { |
| 274 | 282 | continue; |
| 275 | 283 | } |
| 276 | 284 | |
| 277 | | log.warn("unexpected input file of unknown type '{s}'", .{file_name}); |
| 285 | log.debug("unexpected input file of unknown type '{s}'", .{file_name}); |
| 278 | 286 | } |
| 279 | 287 | |
| 280 | 288 | // Based on our classification, proceed with parsing. |
| ... | ... | @@ -326,7 +334,7 @@ fn mapAndUpdateSections( |
| 326 | 334 | .target_sect_id = target_sect_id, |
| 327 | 335 | .offset = @intCast(u32, offset), |
| 328 | 336 | }); |
| 329 | | log.warn("{s}: {s},{s} mapped to {s},{s} from 0x{x} to 0x{x}", .{ |
| 337 | log.debug("{s}: {s},{s} mapped to {s},{s} from 0x{x} to 0x{x}", .{ |
| 330 | 338 | object.name, |
| 331 | 339 | parseName(&source_sect.segname), |
| 332 | 340 | parseName(&source_sect.sectname), |
| ... | ... | @@ -536,7 +544,7 @@ fn updateMetadata(self: *Zld) !void { |
| 536 | 544 | }); |
| 537 | 545 | }, |
| 538 | 546 | else => { |
| 539 | | log.warn("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname }); |
| 547 | log.debug("unhandled section type 0x{x} for '{s}/{s}'", .{ flags, segname, sectname }); |
| 540 | 548 | }, |
| 541 | 549 | } |
| 542 | 550 | } |
| ... | ... | @@ -560,7 +568,7 @@ fn updateMetadata(self: *Zld) !void { |
| 560 | 568 | |
| 561 | 569 | const segname = parseName(&source_sect.segname); |
| 562 | 570 | const sectname = parseName(&source_sect.sectname); |
| 563 | | log.warn("section '{s}/{s}' will be unmapped", .{ segname, sectname }); |
| 571 | log.debug("section '{s}/{s}' will be unmapped", .{ segname, sectname }); |
| 564 | 572 | try self.unhandled_sections.putNoClobber(self.allocator, .{ |
| 565 | 573 | .object_id = object_id, |
| 566 | 574 | .source_sect_id = source_sect_id, |
| ... | ... | @@ -874,15 +882,9 @@ fn allocateSegment(self: *Zld, index: u16, offset: u64) !void { |
| 874 | 882 | |
| 875 | 883 | fn allocateSymbols(self: *Zld) !void { |
| 876 | 884 | for (self.objects.items) |*object, object_id| { |
| 877 | | for (object.symtab.items) |*sym| { |
| 878 | | switch (sym.tag) { |
| 879 | | .import => unreachable, |
| 880 | | .undef => continue, |
| 881 | | else => {}, |
| 882 | | } |
| 883 | | |
| 884 | | const sym_name = object.getString(sym.inner.n_strx); |
| 885 | | const source_sect_id = sym.inner.n_sect - 1; |
| 885 | for (object.locals.items()) |*entry| { |
| 886 | const source_sym = object.symtab.items[entry.value.index.?]; |
| 887 | const source_sect_id = source_sym.n_sect - 1; |
| 886 | 888 | |
| 887 | 889 | // TODO I am more and more convinced we should store the mapping as part of the Object struct. |
| 888 | 890 | const target_mapping = self.mappings.get(.{ |
| ... | ... | @@ -894,7 +896,7 @@ fn allocateSymbols(self: *Zld) !void { |
| 894 | 896 | .source_sect_id = source_sect_id, |
| 895 | 897 | }) != null) continue; |
| 896 | 898 | |
| 897 | | log.err("section not mapped for symbol '{s}': {}", .{ sym_name, sym }); |
| 899 | log.err("section not mapped for symbol '{s}'", .{entry.value.name}); |
| 898 | 900 | return error.SectionNotMappedForSymbol; |
| 899 | 901 | }; |
| 900 | 902 | |
| ... | ... | @@ -903,9 +905,9 @@ fn allocateSymbols(self: *Zld) !void { |
| 903 | 905 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; |
| 904 | 906 | const target_sect = target_seg.sections.items[target_mapping.target_sect_id]; |
| 905 | 907 | const target_addr = target_sect.addr + target_mapping.offset; |
| 906 | | const n_value = sym.inner.n_value - source_sect.addr + target_addr; |
| 908 | const n_value = source_sym.n_value - source_sect.addr + target_addr; |
| 907 | 909 | |
| 908 | | log.warn("resolving local symbol '{s}' at 0x{x}", .{ sym_name, n_value }); |
| 910 | log.debug("resolving local symbol '{s}' at 0x{x}", .{ entry.value.name, n_value }); |
| 909 | 911 | |
| 910 | 912 | // TODO there might be a more generic way of doing this. |
| 911 | 913 | var n_sect: u8 = 0; |
| ... | ... | @@ -918,8 +920,8 @@ fn allocateSymbols(self: *Zld) !void { |
| 918 | 920 | n_sect += @intCast(u8, cmd.Segment.sections.items.len); |
| 919 | 921 | } |
| 920 | 922 | |
| 921 | | sym.inner.n_value = n_value; |
| 922 | | sym.inner.n_sect = n_sect; |
| 923 | entry.value.address = n_value; |
| 924 | entry.value.section = n_sect; |
| 923 | 925 | } |
| 924 | 926 | } |
| 925 | 927 | |
| ... | ... | @@ -927,15 +929,13 @@ fn allocateSymbols(self: *Zld) !void { |
| 927 | 929 | if (entry.value.tag == .import) continue; |
| 928 | 930 | |
| 929 | 931 | const object_id = entry.value.file orelse unreachable; |
| 930 | | const index = entry.value.index orelse unreachable; |
| 931 | | |
| 932 | 932 | const object = self.objects.items[object_id]; |
| 933 | | const sym = object.symtab.items[index]; |
| 933 | const local = object.locals.get(entry.key) orelse unreachable; |
| 934 | 934 | |
| 935 | | log.warn("resolving {} symbol '{s}' at 0x{x}", .{ entry.value.tag, entry.key, sym.inner.n_value }); |
| 935 | log.debug("resolving {} symbol '{s}' at 0x{x}", .{ entry.value.tag, entry.key, local.address }); |
| 936 | 936 | |
| 937 | | entry.value.inner.n_value = sym.inner.n_value; |
| 938 | | entry.value.inner.n_sect = sym.inner.n_sect; |
| 937 | entry.value.address = local.address; |
| 938 | entry.value.section = local.section; |
| 939 | 939 | } |
| 940 | 940 | } |
| 941 | 941 | |
| ... | ... | @@ -944,19 +944,15 @@ fn allocateStubsAndGotEntries(self: *Zld) !void { |
| 944 | 944 | if (entry.value.tag == .import) continue; |
| 945 | 945 | |
| 946 | 946 | const object = self.objects.items[entry.value.file]; |
| 947 | | const sym = object.symtab.items[entry.value.local_index]; |
| 948 | | const sym_name = object.getString(sym.inner.n_strx); |
| 949 | | assert(mem.eql(u8, sym_name, entry.key)); |
| 950 | | |
| 951 | 947 | entry.value.target_addr = target_addr: { |
| 952 | | if (sym.tag == .undef) { |
| 953 | | const glob = self.symtab.get(sym_name) orelse unreachable; |
| 954 | | break :target_addr glob.inner.n_value; |
| 948 | if (object.locals.get(entry.key)) |local| { |
| 949 | break :target_addr local.address; |
| 955 | 950 | } |
| 956 | | break :target_addr sym.inner.n_value; |
| 951 | const global = self.symtab.get(entry.key) orelse unreachable; |
| 952 | break :target_addr global.address; |
| 957 | 953 | }; |
| 958 | 954 | |
| 959 | | log.warn("resolving GOT entry '{s}' at 0x{x}", .{ |
| 955 | log.debug("resolving GOT entry '{s}' at 0x{x}", .{ |
| 960 | 956 | entry.key, |
| 961 | 957 | entry.value.target_addr, |
| 962 | 958 | }); |
| ... | ... | @@ -1114,7 +1110,7 @@ fn writeLazySymbolPointer(self: *Zld, index: u32) !void { |
| 1114 | 1110 | var buf: [@sizeOf(u64)]u8 = undefined; |
| 1115 | 1111 | mem.writeIntLittle(u64, &buf, end); |
| 1116 | 1112 | const off = la_symbol_ptr.offset + index * @sizeOf(u64); |
| 1117 | | log.warn("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off }); |
| 1113 | log.debug("writing lazy symbol pointer entry 0x{x} at 0x{x}", .{ end, off }); |
| 1118 | 1114 | try self.file.?.pwriteAll(&buf, off); |
| 1119 | 1115 | } |
| 1120 | 1116 | |
| ... | ... | @@ -1127,7 +1123,7 @@ fn writeStub(self: *Zld, index: u32) !void { |
| 1127 | 1123 | const stub_off = stubs.offset + index * stubs.reserved2; |
| 1128 | 1124 | const stub_addr = stubs.addr + index * stubs.reserved2; |
| 1129 | 1125 | const la_ptr_addr = la_symbol_ptr.addr + index * @sizeOf(u64); |
| 1130 | | log.warn("writing stub at 0x{x}", .{stub_off}); |
| 1126 | log.debug("writing stub at 0x{x}", .{stub_off}); |
| 1131 | 1127 | var code = try self.allocator.alloc(u8, stubs.reserved2); |
| 1132 | 1128 | defer self.allocator.free(code); |
| 1133 | 1129 | switch (self.arch.?) { |
| ... | ... | @@ -1232,71 +1228,52 @@ fn writeStubInStubHelper(self: *Zld, index: u32) !void { |
| 1232 | 1228 | |
| 1233 | 1229 | fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1234 | 1230 | const object = self.objects.items[object_id]; |
| 1235 | | log.warn("resolving symbols in '{s}'", .{object.name}); |
| 1231 | log.debug("resolving symbols in '{s}'", .{object.name}); |
| 1236 | 1232 | |
| 1237 | 1233 | for (object.symtab.items) |sym, sym_id| { |
| 1238 | | switch (sym.tag) { |
| 1239 | | .local, .stab => continue, // If symbol is local to CU, we don't put it in the global symbol table. |
| 1240 | | .weak, .strong => { |
| 1241 | | const sym_name = object.getString(sym.inner.n_strx); |
| 1242 | | const global = self.symtab.getEntry(sym_name) orelse { |
| 1243 | | // Put new global symbol into the symbol table. |
| 1244 | | const name = try self.allocator.dupe(u8, sym_name); |
| 1245 | | try self.symtab.putNoClobber(self.allocator, name, .{ |
| 1246 | | .tag = sym.tag, |
| 1247 | | .inner = .{ |
| 1248 | | .n_strx = 0, // This will be populated later. |
| 1249 | | .n_value = 0, // This will be populated later, |
| 1250 | | .n_type = macho.N_SECT | macho.N_EXT, |
| 1251 | | .n_desc = 0, |
| 1252 | | .n_sect = 0, // This will be populated later. |
| 1253 | | }, |
| 1254 | | .file = object_id, |
| 1255 | | .index = @intCast(u32, sym_id), |
| 1256 | | }); |
| 1257 | | continue; |
| 1258 | | }; |
| 1259 | | |
| 1260 | | switch (global.value.tag) { |
| 1261 | | .weak => continue, // If symbol is weak, nothing to do. |
| 1262 | | .strong => { |
| 1263 | | log.err("symbol '{s}' defined multiple times", .{sym_name}); |
| 1264 | | return error.MultipleSymbolDefinitions; |
| 1265 | | }, |
| 1266 | | else => {}, |
| 1267 | | } |
| 1268 | | |
| 1269 | | global.value = .{ |
| 1270 | | .tag = .strong, |
| 1271 | | .inner = .{ |
| 1272 | | .n_strx = 0, // This will be populated later. |
| 1273 | | .n_value = 0, // This will be populated later, |
| 1274 | | .n_type = macho.N_SECT | macho.N_EXT, |
| 1275 | | .n_desc = 0, |
| 1276 | | .n_sect = 0, // This will be populated later. |
| 1277 | | }, |
| 1278 | | .file = object_id, |
| 1279 | | .index = @intCast(u32, sym_id), |
| 1280 | | }; |
| 1281 | | }, |
| 1282 | | .undef => { |
| 1283 | | const sym_name = object.getString(sym.inner.n_strx); |
| 1284 | | if (self.symtab.contains(sym_name)) continue; // Nothing to do if we already found a definition. |
| 1285 | | |
| 1234 | if (Symbol.isLocal(sym)) { |
| 1235 | // If symbol is local to CU, we don't put it in the global symbol table. |
| 1236 | continue; |
| 1237 | } else if (Symbol.isGlobal(sym)) { |
| 1238 | const sym_name = object.getString(sym.n_strx); |
| 1239 | const global = self.symtab.getEntry(sym_name) orelse { |
| 1240 | // Put new global symbol into the symbol table. |
| 1286 | 1241 | const name = try self.allocator.dupe(u8, sym_name); |
| 1287 | 1242 | try self.symtab.putNoClobber(self.allocator, name, .{ |
| 1288 | | .tag = .undef, |
| 1289 | | .inner = .{ |
| 1290 | | .n_strx = 0, |
| 1291 | | .n_value = 0, |
| 1292 | | .n_type = 0, |
| 1293 | | .n_desc = 0, |
| 1294 | | .n_sect = 0, |
| 1295 | | }, |
| 1243 | .tag = if (Symbol.isWeakDef(sym)) .weak else .strong, |
| 1244 | .name = name, |
| 1245 | .address = 0, |
| 1246 | .section = 0, |
| 1247 | .file = object_id, |
| 1248 | .index = @intCast(u32, sym_id), |
| 1296 | 1249 | }); |
| 1297 | | }, |
| 1298 | | .import => unreachable, // We don't expect any imports just yet. |
| 1299 | | } |
| 1250 | continue; |
| 1251 | }; |
| 1252 | |
| 1253 | switch (global.value.tag) { |
| 1254 | .weak => continue, // If symbol is weak, nothing to do. |
| 1255 | .strong => { |
| 1256 | log.err("symbol '{s}' defined multiple times", .{sym_name}); |
| 1257 | return error.MultipleSymbolDefinitions; |
| 1258 | }, |
| 1259 | else => {}, |
| 1260 | } |
| 1261 | |
| 1262 | global.value.tag = .strong; |
| 1263 | global.value.file = object_id; |
| 1264 | global.value.index = @intCast(u32, sym_id); |
| 1265 | } else if (Symbol.isUndef(sym)) { |
| 1266 | const sym_name = object.getString(sym.n_strx); |
| 1267 | if (self.symtab.contains(sym_name)) continue; // Nothing to do if we already found a definition. |
| 1268 | |
| 1269 | const name = try self.allocator.dupe(u8, sym_name); |
| 1270 | try self.symtab.putNoClobber(self.allocator, name, .{ |
| 1271 | .tag = .undef, |
| 1272 | .name = name, |
| 1273 | .address = 0, |
| 1274 | .section = 0, |
| 1275 | }); |
| 1276 | } else unreachable; |
| 1300 | 1277 | } |
| 1301 | 1278 | } |
| 1302 | 1279 | |
| ... | ... | @@ -1316,7 +1293,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 1316 | 1293 | for (self.symtab.items()) |entry| { |
| 1317 | 1294 | if (entry.value.tag != .undef) continue; |
| 1318 | 1295 | |
| 1319 | | const sym_name = entry.key; |
| 1296 | const sym_name = entry.value.name; |
| 1320 | 1297 | |
| 1321 | 1298 | // Check if the entry exists in a static archive. |
| 1322 | 1299 | const offsets = archive.toc.get(sym_name) orelse { |
| ... | ... | @@ -1349,25 +1326,18 @@ fn resolveSymbols(self: *Zld) !void { |
| 1349 | 1326 | // a libSystem.B.tbd definition file? |
| 1350 | 1327 | for (self.symtab.items()) |*entry| { |
| 1351 | 1328 | if (entry.value.tag != .undef) continue; |
| 1352 | | entry.value = .{ |
| 1353 | | .tag = .import, |
| 1354 | | .inner = .{ |
| 1355 | | .n_strx = 0, // This will be populated once we write the string table. |
| 1356 | | .n_type = macho.N_UNDF | macho.N_EXT, |
| 1357 | | .n_sect = 0, |
| 1358 | | .n_desc = macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY | macho.N_SYMBOL_RESOLVER, |
| 1359 | | .n_value = 0, |
| 1360 | | }, |
| 1361 | | .file = 0, |
| 1362 | | }; |
| 1329 | |
| 1330 | entry.value.tag = .import; |
| 1331 | entry.value.file = 0; |
| 1363 | 1332 | } |
| 1364 | 1333 | |
| 1365 | 1334 | // If there are any undefs left, flag an error. |
| 1366 | 1335 | var has_unresolved = false; |
| 1367 | 1336 | for (self.symtab.items()) |entry| { |
| 1368 | 1337 | if (entry.value.tag != .undef) continue; |
| 1338 | |
| 1369 | 1339 | has_unresolved = true; |
| 1370 | | log.err("undefined reference to symbol '{s}'", .{entry.key}); |
| 1340 | log.err("undefined reference to symbol '{s}'", .{entry.value.name}); |
| 1371 | 1341 | } |
| 1372 | 1342 | if (has_unresolved) { |
| 1373 | 1343 | return error.UndefinedSymbolReference; |
| ... | ... | @@ -1377,20 +1347,16 @@ fn resolveSymbols(self: *Zld) !void { |
| 1377 | 1347 | var name = try self.allocator.dupe(u8, "dyld_stub_binder"); |
| 1378 | 1348 | try self.symtab.putNoClobber(self.allocator, name, .{ |
| 1379 | 1349 | .tag = .import, |
| 1380 | | .inner = .{ |
| 1381 | | .n_strx = 0, // This will be populated once we write the string table. |
| 1382 | | .n_type = macho.N_UNDF | macho.N_EXT, |
| 1383 | | .n_sect = 0, |
| 1384 | | .n_desc = macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY | macho.N_SYMBOL_RESOLVER, |
| 1385 | | .n_value = 0, |
| 1386 | | }, |
| 1350 | .name = name, |
| 1351 | .address = 0, |
| 1352 | .section = 0, |
| 1387 | 1353 | .file = 0, |
| 1388 | 1354 | }); |
| 1389 | 1355 | } |
| 1390 | 1356 | |
| 1391 | 1357 | fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1392 | 1358 | for (self.objects.items) |object, object_id| { |
| 1393 | | log.warn("resolving stubs and got entries from {s}", .{object.name}); |
| 1359 | log.debug("resolving stubs and got entries from {s}", .{object.name}); |
| 1394 | 1360 | |
| 1395 | 1361 | for (object.sections.items) |sect| { |
| 1396 | 1362 | const relocs = sect.relocs orelse continue; |
| ... | ... | @@ -1399,7 +1365,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1399 | 1365 | .unsigned => continue, |
| 1400 | 1366 | .got_page, .got_page_off => { |
| 1401 | 1367 | const sym = object.symtab.items[reloc.target.symbol]; |
| 1402 | | const sym_name = object.getString(sym.inner.n_strx); |
| 1368 | const sym_name = object.getString(sym.n_strx); |
| 1403 | 1369 | |
| 1404 | 1370 | if (self.got_entries.contains(sym_name)) continue; |
| 1405 | 1371 | |
| ... | ... | @@ -1412,16 +1378,15 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1412 | 1378 | .index = index, |
| 1413 | 1379 | .target_addr = 0, |
| 1414 | 1380 | .file = if (is_import) 0 else @intCast(u16, object_id), |
| 1415 | | .local_index = if (is_import) 0 else reloc.target.symbol, |
| 1416 | 1381 | }); |
| 1417 | 1382 | |
| 1418 | | log.warn(" | found GOT entry {s}: {}", .{ sym_name, self.got_entries.get(sym_name) }); |
| 1383 | log.debug(" | found GOT entry {s}: {}", .{ sym_name, self.got_entries.get(sym_name) }); |
| 1419 | 1384 | }, |
| 1420 | 1385 | else => { |
| 1421 | 1386 | const sym = object.symtab.items[reloc.target.symbol]; |
| 1422 | | const sym_name = object.getString(sym.inner.n_strx); |
| 1387 | const sym_name = object.getString(sym.n_strx); |
| 1423 | 1388 | |
| 1424 | | if (sym.tag != .undef) continue; |
| 1389 | if (!Symbol.isUndef(sym)) continue; |
| 1425 | 1390 | |
| 1426 | 1391 | const in_globals = self.symtab.get(sym_name) orelse unreachable; |
| 1427 | 1392 | |
| ... | ... | @@ -1432,7 +1397,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1432 | 1397 | const index = @intCast(u32, self.stubs.items().len); |
| 1433 | 1398 | try self.stubs.putNoClobber(self.allocator, name, index); |
| 1434 | 1399 | |
| 1435 | | log.warn(" | found stub {s}: {}", .{ sym_name, self.stubs.get(sym_name) }); |
| 1400 | log.debug(" | found stub {s}: {}", .{ sym_name, self.stubs.get(sym_name) }); |
| 1436 | 1401 | }, |
| 1437 | 1402 | } |
| 1438 | 1403 | } |
| ... | ... | @@ -1447,15 +1412,14 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1447 | 1412 | .index = index, |
| 1448 | 1413 | .target_addr = 0, |
| 1449 | 1414 | .file = 0, |
| 1450 | | .local_index = 0, |
| 1451 | 1415 | }); |
| 1452 | 1416 | |
| 1453 | | log.warn(" | found GOT entry dyld_stub_binder: {}", .{self.got_entries.get("dyld_stub_binder")}); |
| 1417 | log.debug(" | found GOT entry dyld_stub_binder: {}", .{self.got_entries.get("dyld_stub_binder")}); |
| 1454 | 1418 | } |
| 1455 | 1419 | |
| 1456 | 1420 | fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1457 | 1421 | for (self.objects.items) |object, object_id| { |
| 1458 | | log.warn("relocating object {s}", .{object.name}); |
| 1422 | log.debug("relocating object {s}", .{object.name}); |
| 1459 | 1423 | |
| 1460 | 1424 | for (object.sections.items) |sect, source_sect_id| { |
| 1461 | 1425 | const segname = parseName(&sect.inner.segname); |
| ... | ... | @@ -1466,7 +1430,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1466 | 1430 | .object_id = @intCast(u16, object_id), |
| 1467 | 1431 | .source_sect_id = @intCast(u16, source_sect_id), |
| 1468 | 1432 | }) orelse { |
| 1469 | | log.warn("no mapping for {s},{s}; skipping", .{ segname, sectname }); |
| 1433 | log.debug("no mapping for {s},{s}; skipping", .{ segname, sectname }); |
| 1470 | 1434 | continue; |
| 1471 | 1435 | }; |
| 1472 | 1436 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; |
| ... | ... | @@ -1517,7 +1481,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1517 | 1481 | // Calculate the offset to the initializer. |
| 1518 | 1482 | if (target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) tlv: { |
| 1519 | 1483 | const sym = object.symtab.items[rel.target.symbol]; |
| 1520 | | const sym_name = object.getString(sym.inner.n_strx); |
| 1484 | const sym_name = object.getString(sym.n_strx); |
| 1521 | 1485 | |
| 1522 | 1486 | // TODO we don't want to save offset to tlv_bootstrap |
| 1523 | 1487 | if (mem.eql(u8, sym_name, "__tlv_bootstrap")) break :tlv; |
| ... | ... | @@ -1540,7 +1504,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1540 | 1504 | const dc_seg = self.load_commands.items[self.data_const_segment_cmd_index.?].Segment; |
| 1541 | 1505 | const got = dc_seg.sections.items[self.got_section_index.?]; |
| 1542 | 1506 | const sym = object.symtab.items[rel.target.symbol]; |
| 1543 | | const sym_name = object.getString(sym.inner.n_strx); |
| 1507 | const sym_name = object.getString(sym.n_strx); |
| 1544 | 1508 | const entry = self.got_entries.get(sym_name) orelse unreachable; |
| 1545 | 1509 | args.target_addr = got.addr + entry.index * @sizeOf(u64); |
| 1546 | 1510 | }, |
| ... | ... | @@ -1553,7 +1517,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1553 | 1517 | } |
| 1554 | 1518 | } |
| 1555 | 1519 | |
| 1556 | | log.warn("writing contents of '{s},{s}' section from '{s}' from 0x{x} to 0x{x}", .{ |
| 1520 | log.debug("writing contents of '{s},{s}' section from '{s}' from 0x{x} to 0x{x}", .{ |
| 1557 | 1521 | segname, |
| 1558 | 1522 | sectname, |
| 1559 | 1523 | object.name, |
| ... | ... | @@ -1565,7 +1529,7 @@ fn resolveRelocsAndWriteSections(self: *Zld) !void { |
| 1565 | 1529 | target_sect.flags == macho.S_THREAD_LOCAL_ZEROFILL or |
| 1566 | 1530 | target_sect.flags == macho.S_THREAD_LOCAL_VARIABLES) |
| 1567 | 1531 | { |
| 1568 | | log.warn("zeroing out '{s},{s}' from 0x{x} to 0x{x}", .{ |
| 1532 | log.debug("zeroing out '{s},{s}' from 0x{x} to 0x{x}", .{ |
| 1569 | 1533 | parseName(&target_sect.segname), |
| 1570 | 1534 | parseName(&target_sect.sectname), |
| 1571 | 1535 | target_sect_off, |
| ... | ... | @@ -1589,33 +1553,46 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: Relocation.Target) !u64 { |
| 1589 | 1553 | switch (target) { |
| 1590 | 1554 | .symbol => |sym_id| { |
| 1591 | 1555 | const sym = object.symtab.items[sym_id]; |
| 1592 | | const sym_name = object.getString(sym.inner.n_strx); |
| 1556 | const sym_name = object.getString(sym.n_strx); |
| 1593 | 1557 | |
| 1594 | | switch (sym.tag) { |
| 1595 | | .stab, .local, .weak, .strong => { |
| 1596 | | log.warn(" | local symbol '{s}'", .{sym_name}); |
| 1597 | | break :blk sym.inner.n_value; |
| 1598 | | }, |
| 1599 | | else => { |
| 1600 | | if (self.stubs.get(sym_name)) |index| { |
| 1601 | | log.warn(" | symbol stub '{s}'", .{sym_name}); |
| 1602 | | const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1603 | | const stubs = segment.sections.items[self.stubs_section_index.?]; |
| 1604 | | break :blk stubs.addr + index * stubs.reserved2; |
| 1605 | | } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) { |
| 1606 | | log.warn(" | symbol '__tlv_bootstrap'", .{}); |
| 1607 | | const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1608 | | const tlv = segment.sections.items[self.tlv_section_index.?]; |
| 1609 | | break :blk tlv.addr; |
| 1610 | | } else { |
| 1611 | | const global = self.symtab.get(sym_name) orelse { |
| 1612 | | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); |
| 1613 | | return error.FailedToResolveRelocationTarget; |
| 1614 | | }; |
| 1615 | | log.warn(" | global symbol '{s}'", .{sym_name}); |
| 1616 | | break :blk global.inner.n_value; |
| 1617 | | } |
| 1618 | | }, |
| 1558 | if (Symbol.isSect(sym)) { |
| 1559 | log.debug(" | local symbol '{s}'", .{sym_name}); |
| 1560 | if (object.locals.get(sym_name)) |local| { |
| 1561 | break :blk local.address; |
| 1562 | } |
| 1563 | // For temp locals, i.e., symbols prefixed with l... we relocate |
| 1564 | // based on section addressing. |
| 1565 | const source_sect_id = sym.n_sect - 1; |
| 1566 | const target_mapping = self.mappings.get(.{ |
| 1567 | .object_id = object_id, |
| 1568 | .source_sect_id = source_sect_id, |
| 1569 | }) orelse unreachable; |
| 1570 | |
| 1571 | const source_seg = object.load_commands.items[object.segment_cmd_index.?].Segment; |
| 1572 | const source_sect = source_seg.sections.items[source_sect_id]; |
| 1573 | const target_seg = self.load_commands.items[target_mapping.target_seg_id].Segment; |
| 1574 | const target_sect = target_seg.sections.items[target_mapping.target_sect_id]; |
| 1575 | const target_addr = target_sect.addr + target_mapping.offset; |
| 1576 | break :blk sym.n_value - source_sect.addr + target_addr; |
| 1577 | } else { |
| 1578 | if (self.stubs.get(sym_name)) |index| { |
| 1579 | log.debug(" | symbol stub '{s}'", .{sym_name}); |
| 1580 | const segment = self.load_commands.items[self.text_segment_cmd_index.?].Segment; |
| 1581 | const stubs = segment.sections.items[self.stubs_section_index.?]; |
| 1582 | break :blk stubs.addr + index * stubs.reserved2; |
| 1583 | } else if (mem.eql(u8, sym_name, "__tlv_bootstrap")) { |
| 1584 | log.debug(" | symbol '__tlv_bootstrap'", .{}); |
| 1585 | const segment = self.load_commands.items[self.data_segment_cmd_index.?].Segment; |
| 1586 | const tlv = segment.sections.items[self.tlv_section_index.?]; |
| 1587 | break :blk tlv.addr; |
| 1588 | } else { |
| 1589 | const global = self.symtab.get(sym_name) orelse { |
| 1590 | log.err("failed to resolve symbol '{s}' as a relocation target", .{sym_name}); |
| 1591 | return error.FailedToResolveRelocationTarget; |
| 1592 | }; |
| 1593 | log.debug(" | global symbol '{s}'", .{sym_name}); |
| 1594 | break :blk global.address; |
| 1595 | } |
| 1619 | 1596 | } |
| 1620 | 1597 | }, |
| 1621 | 1598 | .section => |sect_id| { |
| ... | ... | @@ -2082,7 +2059,6 @@ fn flush(self: *Zld) !void { |
| 2082 | 2059 | symtab.symoff = @intCast(u32, seg.inner.fileoff + seg.inner.filesize); |
| 2083 | 2060 | } |
| 2084 | 2061 | |
| 2085 | | try self.populateStringTable(); |
| 2086 | 2062 | try self.writeDebugInfo(); |
| 2087 | 2063 | try self.writeSymbolTable(); |
| 2088 | 2064 | try self.writeStringTable(); |
| ... | ... | @@ -2123,7 +2099,7 @@ fn writeGotEntries(self: *Zld) !void { |
| 2123 | 2099 | try writer.writeIntLittle(u64, entry.value.target_addr); |
| 2124 | 2100 | } |
| 2125 | 2101 | |
| 2126 | | log.warn("writing GOT pointers at 0x{x} to 0x{x}", .{ sect.offset, sect.offset + buffer.len }); |
| 2102 | log.debug("writing GOT pointers at 0x{x} to 0x{x}", .{ sect.offset, sect.offset + buffer.len }); |
| 2127 | 2103 | |
| 2128 | 2104 | try self.file.?.pwriteAll(buffer, sect.offset); |
| 2129 | 2105 | } |
| ... | ... | @@ -2135,7 +2111,7 @@ fn setEntryPoint(self: *Zld) !void { |
| 2135 | 2111 | const text = seg.sections.items[self.text_section_index.?]; |
| 2136 | 2112 | const entry_sym = self.symtab.get("_main") orelse return error.MissingMainEntrypoint; |
| 2137 | 2113 | const ec = &self.load_commands.items[self.main_cmd_index.?].Main; |
| 2138 | | ec.entryoff = @intCast(u32, entry_sym.inner.n_value - seg.inner.vmaddr); |
| 2114 | ec.entryoff = @intCast(u32, entry_sym.address - seg.inner.vmaddr); |
| 2139 | 2115 | } |
| 2140 | 2116 | |
| 2141 | 2117 | fn writeRebaseInfoTable(self: *Zld) !void { |
| ... | ... | @@ -2228,7 +2204,7 @@ fn writeRebaseInfoTable(self: *Zld) !void { |
| 2228 | 2204 | dyld_info.rebase_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @sizeOf(u64))); |
| 2229 | 2205 | seg.inner.filesize += dyld_info.rebase_size; |
| 2230 | 2206 | |
| 2231 | | log.warn("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size }); |
| 2207 | log.debug("writing rebase info from 0x{x} to 0x{x}", .{ dyld_info.rebase_off, dyld_info.rebase_off + dyld_info.rebase_size }); |
| 2232 | 2208 | |
| 2233 | 2209 | try self.file.?.pwriteAll(buffer, dyld_info.rebase_off); |
| 2234 | 2210 | } |
| ... | ... | @@ -2291,7 +2267,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2291 | 2267 | dyld_info.bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 2292 | 2268 | seg.inner.filesize += dyld_info.bind_size; |
| 2293 | 2269 | |
| 2294 | | log.warn("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size }); |
| 2270 | log.debug("writing binding info from 0x{x} to 0x{x}", .{ dyld_info.bind_off, dyld_info.bind_off + dyld_info.bind_size }); |
| 2295 | 2271 | |
| 2296 | 2272 | try self.file.?.pwriteAll(buffer, dyld_info.bind_off); |
| 2297 | 2273 | } |
| ... | ... | @@ -2337,7 +2313,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { |
| 2337 | 2313 | dyld_info.lazy_bind_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 2338 | 2314 | seg.inner.filesize += dyld_info.lazy_bind_size; |
| 2339 | 2315 | |
| 2340 | | log.warn("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size }); |
| 2316 | log.debug("writing lazy binding info from 0x{x} to 0x{x}", .{ dyld_info.lazy_bind_off, dyld_info.lazy_bind_off + dyld_info.lazy_bind_size }); |
| 2341 | 2317 | |
| 2342 | 2318 | try self.file.?.pwriteAll(buffer, dyld_info.lazy_bind_off); |
| 2343 | 2319 | try self.populateLazyBindOffsetsInStubHelper(buffer); |
| ... | ... | @@ -2416,11 +2392,11 @@ fn writeExportInfo(self: *Zld) !void { |
| 2416 | 2392 | |
| 2417 | 2393 | // TODO export items for dylibs |
| 2418 | 2394 | const sym = self.symtab.get("_main") orelse return error.MissingMainEntrypoint; |
| 2419 | | assert(sym.inner.n_value >= text_segment.inner.vmaddr); |
| 2395 | assert(sym.address >= text_segment.inner.vmaddr); |
| 2420 | 2396 | |
| 2421 | 2397 | try trie.put(.{ |
| 2422 | 2398 | .name = "_main", |
| 2423 | | .vmaddr_offset = sym.inner.n_value - text_segment.inner.vmaddr, |
| 2399 | .vmaddr_offset = sym.address - text_segment.inner.vmaddr, |
| 2424 | 2400 | .export_flags = macho.EXPORT_SYMBOL_FLAGS_KIND_REGULAR, |
| 2425 | 2401 | }); |
| 2426 | 2402 | |
| ... | ... | @@ -2439,7 +2415,7 @@ fn writeExportInfo(self: *Zld) !void { |
| 2439 | 2415 | dyld_info.export_size = @intCast(u32, mem.alignForwardGeneric(u64, buffer.len, @alignOf(u64))); |
| 2440 | 2416 | seg.inner.filesize += dyld_info.export_size; |
| 2441 | 2417 | |
| 2442 | | log.warn("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size }); |
| 2418 | log.debug("writing export info from 0x{x} to 0x{x}", .{ dyld_info.export_off, dyld_info.export_off + dyld_info.export_size }); |
| 2443 | 2419 | |
| 2444 | 2420 | try self.file.?.pwriteAll(buffer, dyld_info.export_off); |
| 2445 | 2421 | } |
| ... | ... | @@ -2478,31 +2454,24 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2478 | 2454 | }); |
| 2479 | 2455 | |
| 2480 | 2456 | for (object.stabs.items) |stab| { |
| 2481 | | const sym = object.symtab.items[stab.symbol]; |
| 2482 | | |
| 2483 | | // TODO We should clean this up. |
| 2484 | | if (self.unhandled_sections.contains(.{ |
| 2485 | | .object_id = @intCast(u16, object_id), |
| 2486 | | .source_sect_id = stab.source_sect_id, |
| 2487 | | })) { |
| 2488 | | continue; |
| 2489 | | } |
| 2457 | const entry = object.locals.items()[stab.symbol]; |
| 2458 | const sym = entry.value; |
| 2490 | 2459 | |
| 2491 | 2460 | switch (stab.tag) { |
| 2492 | 2461 | .function => { |
| 2493 | 2462 | try stabs.append(.{ |
| 2494 | 2463 | .n_strx = 0, |
| 2495 | 2464 | .n_type = macho.N_BNSYM, |
| 2496 | | .n_sect = sym.inner.n_sect, |
| 2465 | .n_sect = sym.section, |
| 2497 | 2466 | .n_desc = 0, |
| 2498 | | .n_value = sym.inner.n_value, |
| 2467 | .n_value = sym.address, |
| 2499 | 2468 | }); |
| 2500 | 2469 | try stabs.append(.{ |
| 2501 | | .n_strx = sym.inner.n_strx, |
| 2470 | .n_strx = try self.makeString(sym.name), |
| 2502 | 2471 | .n_type = macho.N_FUN, |
| 2503 | | .n_sect = sym.inner.n_sect, |
| 2472 | .n_sect = sym.section, |
| 2504 | 2473 | .n_desc = 0, |
| 2505 | | .n_value = sym.inner.n_value, |
| 2474 | .n_value = sym.address, |
| 2506 | 2475 | }); |
| 2507 | 2476 | try stabs.append(.{ |
| 2508 | 2477 | .n_strx = 0, |
| ... | ... | @@ -2514,14 +2483,14 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2514 | 2483 | try stabs.append(.{ |
| 2515 | 2484 | .n_strx = 0, |
| 2516 | 2485 | .n_type = macho.N_ENSYM, |
| 2517 | | .n_sect = sym.inner.n_sect, |
| 2486 | .n_sect = sym.section, |
| 2518 | 2487 | .n_desc = 0, |
| 2519 | 2488 | .n_value = stab.size.?, |
| 2520 | 2489 | }); |
| 2521 | 2490 | }, |
| 2522 | 2491 | .global => { |
| 2523 | 2492 | try stabs.append(.{ |
| 2524 | | .n_strx = sym.inner.n_strx, |
| 2493 | .n_strx = try self.makeString(sym.name), |
| 2525 | 2494 | .n_type = macho.N_GSYM, |
| 2526 | 2495 | .n_sect = 0, |
| 2527 | 2496 | .n_desc = 0, |
| ... | ... | @@ -2530,11 +2499,11 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2530 | 2499 | }, |
| 2531 | 2500 | .static => { |
| 2532 | 2501 | try stabs.append(.{ |
| 2533 | | .n_strx = sym.inner.n_strx, |
| 2502 | .n_strx = try self.makeString(sym.name), |
| 2534 | 2503 | .n_type = macho.N_STSYM, |
| 2535 | | .n_sect = sym.inner.n_sect, |
| 2504 | .n_sect = sym.section, |
| 2536 | 2505 | .n_desc = 0, |
| 2537 | | .n_value = sym.inner.n_value, |
| 2506 | .n_value = sym.address, |
| 2538 | 2507 | }); |
| 2539 | 2508 | }, |
| 2540 | 2509 | } |
| ... | ... | @@ -2560,7 +2529,7 @@ fn writeDebugInfo(self: *Zld) !void { |
| 2560 | 2529 | |
| 2561 | 2530 | const stabs_off = symtab.symoff; |
| 2562 | 2531 | const stabs_size = symtab.nsyms * @sizeOf(macho.nlist_64); |
| 2563 | | log.warn("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off }); |
| 2532 | log.debug("writing symbol stabs from 0x{x} to 0x{x}", .{ stabs_off, stabs_size + stabs_off }); |
| 2564 | 2533 | try self.file.?.pwriteAll(mem.sliceAsBytes(stabs.items), stabs_off); |
| 2565 | 2534 | |
| 2566 | 2535 | linkedit.inner.filesize += stabs_size; |
| ... | ... | @@ -2599,13 +2568,17 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2599 | 2568 | defer locals.deinit(); |
| 2600 | 2569 | |
| 2601 | 2570 | for (self.objects.items) |object| { |
| 2602 | | for (object.symtab.items) |sym| { |
| 2603 | | switch (sym.tag) { |
| 2604 | | .stab, .local => {}, |
| 2605 | | else => continue, |
| 2606 | | } |
| 2607 | | |
| 2608 | | try locals.append(sym.inner); |
| 2571 | for (object.locals.items()) |entry| { |
| 2572 | const sym = entry.value; |
| 2573 | if (sym.tag != .local) continue; |
| 2574 | |
| 2575 | try locals.append(.{ |
| 2576 | .n_strx = try self.makeString(sym.name), |
| 2577 | .n_type = macho.N_SECT, |
| 2578 | .n_sect = sym.section, |
| 2579 | .n_desc = 0, |
| 2580 | .n_value = sym.address, |
| 2581 | }); |
| 2609 | 2582 | } |
| 2610 | 2583 | } |
| 2611 | 2584 | |
| ... | ... | @@ -2620,13 +2593,26 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2620 | 2593 | |
| 2621 | 2594 | var undef_id: u32 = 0; |
| 2622 | 2595 | for (self.symtab.items()) |entry| { |
| 2623 | | switch (entry.value.tag) { |
| 2596 | const sym = entry.value; |
| 2597 | switch (sym.tag) { |
| 2624 | 2598 | .weak, .strong => { |
| 2625 | | try exports.append(entry.value.inner); |
| 2599 | try exports.append(.{ |
| 2600 | .n_strx = try self.makeString(sym.name), |
| 2601 | .n_type = macho.N_SECT | macho.N_EXT, |
| 2602 | .n_sect = sym.section, |
| 2603 | .n_desc = 0, |
| 2604 | .n_value = sym.address, |
| 2605 | }); |
| 2626 | 2606 | }, |
| 2627 | 2607 | .import => { |
| 2628 | | try undefs.append(entry.value.inner); |
| 2629 | | try undefs_ids.putNoClobber(entry.key, undef_id); |
| 2608 | try undefs.append(.{ |
| 2609 | .n_strx = try self.makeString(sym.name), |
| 2610 | .n_type = macho.N_UNDF | macho.N_EXT, |
| 2611 | .n_sect = 0, |
| 2612 | .n_desc = macho.N_SYMBOL_RESOLVER | macho.REFERENCE_FLAG_UNDEFINED_NON_LAZY, |
| 2613 | .n_value = 0, |
| 2614 | }); |
| 2615 | try undefs_ids.putNoClobber(sym.name, undef_id); |
| 2630 | 2616 | undef_id += 1; |
| 2631 | 2617 | }, |
| 2632 | 2618 | else => unreachable, |
| ... | ... | @@ -2639,17 +2625,17 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2639 | 2625 | |
| 2640 | 2626 | const locals_off = symtab.symoff + symtab.nsyms * @sizeOf(macho.nlist_64); |
| 2641 | 2627 | const locals_size = nlocals * @sizeOf(macho.nlist_64); |
| 2642 | | log.warn("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); |
| 2628 | log.debug("writing local symbols from 0x{x} to 0x{x}", .{ locals_off, locals_size + locals_off }); |
| 2643 | 2629 | try self.file.?.pwriteAll(mem.sliceAsBytes(locals.items), locals_off); |
| 2644 | 2630 | |
| 2645 | 2631 | const exports_off = locals_off + locals_size; |
| 2646 | 2632 | const exports_size = nexports * @sizeOf(macho.nlist_64); |
| 2647 | | log.warn("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); |
| 2633 | log.debug("writing exported symbols from 0x{x} to 0x{x}", .{ exports_off, exports_size + exports_off }); |
| 2648 | 2634 | try self.file.?.pwriteAll(mem.sliceAsBytes(exports.items), exports_off); |
| 2649 | 2635 | |
| 2650 | 2636 | const undefs_off = exports_off + exports_size; |
| 2651 | 2637 | const undefs_size = nundefs * @sizeOf(macho.nlist_64); |
| 2652 | | log.warn("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 2638 | log.debug("writing undefined symbols from 0x{x} to 0x{x}", .{ undefs_off, undefs_size + undefs_off }); |
| 2653 | 2639 | try self.file.?.pwriteAll(mem.sliceAsBytes(undefs.items), undefs_off); |
| 2654 | 2640 | |
| 2655 | 2641 | symtab.nsyms += @intCast(u32, nlocals + nexports + nundefs); |
| ... | ... | @@ -2679,7 +2665,7 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2679 | 2665 | const needed_size = dysymtab.nindirectsyms * @sizeOf(u32); |
| 2680 | 2666 | seg.inner.filesize += needed_size; |
| 2681 | 2667 | |
| 2682 | | log.warn("writing indirect symbol table from 0x{x} to 0x{x}", .{ |
| 2668 | log.debug("writing indirect symbol table from 0x{x} to 0x{x}", .{ |
| 2683 | 2669 | dysymtab.indirectsymoff, |
| 2684 | 2670 | dysymtab.indirectsymoff + needed_size, |
| 2685 | 2671 | }); |
| ... | ... | @@ -2722,7 +2708,7 @@ fn writeStringTable(self: *Zld) !void { |
| 2722 | 2708 | symtab.strsize = @intCast(u32, mem.alignForwardGeneric(u64, self.strtab.items.len, @alignOf(u64))); |
| 2723 | 2709 | seg.inner.filesize += symtab.strsize; |
| 2724 | 2710 | |
| 2725 | | log.warn("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| 2711 | log.debug("writing string table from 0x{x} to 0x{x}", .{ symtab.stroff, symtab.stroff + symtab.strsize }); |
| 2726 | 2712 | |
| 2727 | 2713 | try self.file.?.pwriteAll(self.strtab.items, symtab.stroff); |
| 2728 | 2714 | |
| ... | ... | @@ -2768,7 +2754,7 @@ fn writeDataInCode(self: *Zld) !void { |
| 2768 | 2754 | dice_cmd.datasize = datasize; |
| 2769 | 2755 | seg.inner.filesize += datasize; |
| 2770 | 2756 | |
| 2771 | | log.warn("writing data-in-code from 0x{x} to 0x{x}", .{ fileoff, fileoff + datasize }); |
| 2757 | log.debug("writing data-in-code from 0x{x} to 0x{x}", .{ fileoff, fileoff + datasize }); |
| 2772 | 2758 | |
| 2773 | 2759 | try self.file.?.pwriteAll(buf.items, fileoff); |
| 2774 | 2760 | } |
| ... | ... | @@ -2789,7 +2775,7 @@ fn writeCodeSignaturePadding(self: *Zld) !void { |
| 2789 | 2775 | seg.inner.filesize += needed_size; |
| 2790 | 2776 | seg.inner.vmsize = mem.alignForwardGeneric(u64, seg.inner.filesize, self.page_size.?); |
| 2791 | 2777 | |
| 2792 | | log.warn("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size }); |
| 2778 | log.debug("writing code signature padding from 0x{x} to 0x{x}", .{ fileoff, fileoff + needed_size }); |
| 2793 | 2779 | |
| 2794 | 2780 | // Pad out the space. We need to do this to calculate valid hashes for everything in the file |
| 2795 | 2781 | // except for code signature data. |
| ... | ... | @@ -2815,7 +2801,7 @@ fn writeCodeSignature(self: *Zld) !void { |
| 2815 | 2801 | var stream = std.io.fixedBufferStream(buffer); |
| 2816 | 2802 | try code_sig.write(stream.writer()); |
| 2817 | 2803 | |
| 2818 | | log.warn("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len }); |
| 2804 | log.debug("writing code signature from 0x{x} to 0x{x}", .{ code_sig_cmd.dataoff, code_sig_cmd.dataoff + buffer.len }); |
| 2819 | 2805 | try self.file.?.pwriteAll(buffer, code_sig_cmd.dataoff); |
| 2820 | 2806 | } |
| 2821 | 2807 | |
| ... | ... | @@ -2833,7 +2819,7 @@ fn writeLoadCommands(self: *Zld) !void { |
| 2833 | 2819 | } |
| 2834 | 2820 | |
| 2835 | 2821 | const off = @sizeOf(macho.mach_header_64); |
| 2836 | | log.warn("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds }); |
| 2822 | log.debug("writing {} load commands from 0x{x} to 0x{x}", .{ self.load_commands.items.len, off, off + sizeofcmds }); |
| 2837 | 2823 | try self.file.?.pwriteAll(buffer, off); |
| 2838 | 2824 | } |
| 2839 | 2825 | |
| ... | ... | @@ -2871,7 +2857,7 @@ fn writeHeader(self: *Zld) !void { |
| 2871 | 2857 | for (self.load_commands.items) |cmd| { |
| 2872 | 2858 | header.sizeofcmds += cmd.cmdsize(); |
| 2873 | 2859 | } |
| 2874 | | log.warn("writing Mach-O header {}", .{header}); |
| 2860 | log.debug("writing Mach-O header {}", .{header}); |
| 2875 | 2861 | try self.file.?.pwriteAll(mem.asBytes(&header), 0); |
| 2876 | 2862 | } |
| 2877 | 2863 | |
| ... | ... | @@ -2883,11 +2869,17 @@ pub fn makeStaticString(bytes: []const u8) [16]u8 { |
| 2883 | 2869 | } |
| 2884 | 2870 | |
| 2885 | 2871 | fn makeString(self: *Zld, bytes: []const u8) !u32 { |
| 2872 | if (self.strtab_dir.get(bytes)) |offset| { |
| 2873 | log.debug("reusing '{s}' from string table at offset 0x{x}", .{ bytes, offset }); |
| 2874 | return offset; |
| 2875 | } |
| 2876 | |
| 2886 | 2877 | try self.strtab.ensureCapacity(self.allocator, self.strtab.items.len + bytes.len + 1); |
| 2887 | 2878 | const offset = @intCast(u32, self.strtab.items.len); |
| 2888 | | log.warn("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset }); |
| 2879 | log.debug("writing new string '{s}' into string table at offset 0x{x}", .{ bytes, offset }); |
| 2889 | 2880 | self.strtab.appendSliceAssumeCapacity(bytes); |
| 2890 | 2881 | self.strtab.appendAssumeCapacity(0); |
| 2882 | try self.strtab_dir.putNoClobber(self.allocator, try self.allocator.dupe(u8, bytes), offset); |
| 2891 | 2883 | return offset; |
| 2892 | 2884 | } |
| 2893 | 2885 | |