| ... | @@ -876,8 +876,8 @@ fn allocateSymbols(self: *Zld) !void { | ... | @@ -876,8 +876,8 @@ fn allocateSymbols(self: *Zld) !void { |
| 876 | for (self.objects.items) |*object, object_id| { | 876 | for (self.objects.items) |*object, object_id| { |
| 877 | for (object.symtab.items) |*sym| { | 877 | for (object.symtab.items) |*sym| { |
| 878 | switch (sym.tag) { | 878 | switch (sym.tag) { |
| 879 | .Import => unreachable, | 879 | .import => unreachable, |
| 880 | .Undef => continue, | 880 | .undef => continue, |
| 881 | else => {}, | 881 | else => {}, |
| 882 | } | 882 | } |
| 883 | | 883 | |
| ... | @@ -924,7 +924,7 @@ fn allocateSymbols(self: *Zld) !void { | ... | @@ -924,7 +924,7 @@ fn allocateSymbols(self: *Zld) !void { |
| 924 | } | 924 | } |
| 925 | | 925 | |
| 926 | for (self.symtab.items()) |*entry| { | 926 | for (self.symtab.items()) |*entry| { |
| 927 | if (entry.value.tag == .Import) continue; | 927 | if (entry.value.tag == .import) continue; |
| 928 | | 928 | |
| 929 | const object_id = entry.value.file orelse unreachable; | 929 | const object_id = entry.value.file orelse unreachable; |
| 930 | const index = entry.value.index orelse unreachable; | 930 | const index = entry.value.index orelse unreachable; |
| ... | @@ -949,7 +949,7 @@ fn allocateStubsAndGotEntries(self: *Zld) !void { | ... | @@ -949,7 +949,7 @@ fn allocateStubsAndGotEntries(self: *Zld) !void { |
| 949 | assert(mem.eql(u8, sym_name, entry.key)); | 949 | assert(mem.eql(u8, sym_name, entry.key)); |
| 950 | | 950 | |
| 951 | entry.value.target_addr = target_addr: { | 951 | entry.value.target_addr = target_addr: { |
| 952 | if (sym.tag == .Undef) { | 952 | if (sym.tag == .undef) { |
| 953 | const glob = self.symtab.get(sym_name) orelse unreachable; | 953 | const glob = self.symtab.get(sym_name) orelse unreachable; |
| 954 | break :target_addr glob.inner.n_value; | 954 | break :target_addr glob.inner.n_value; |
| 955 | } | 955 | } |
| ... | @@ -1236,8 +1236,8 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { | ... | @@ -1236,8 +1236,8 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1236 | | 1236 | |
| 1237 | for (object.symtab.items) |sym, sym_id| { | 1237 | for (object.symtab.items) |sym, sym_id| { |
| 1238 | switch (sym.tag) { | 1238 | switch (sym.tag) { |
| 1239 | .Local, .Stab => continue, // If symbol is local to CU, we don't put it in the global symbol table. | 1239 | .local, .stab => continue, // If symbol is local to CU, we don't put it in the global symbol table. |
| 1240 | .Weak, .Strong => { | 1240 | .weak, .strong => { |
| 1241 | const sym_name = object.getString(sym.inner.n_strx); | 1241 | const sym_name = object.getString(sym.inner.n_strx); |
| 1242 | const global = self.symtab.getEntry(sym_name) orelse { | 1242 | const global = self.symtab.getEntry(sym_name) orelse { |
| 1243 | // Put new global symbol into the symbol table. | 1243 | // Put new global symbol into the symbol table. |
| ... | @@ -1257,14 +1257,17 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { | ... | @@ -1257,14 +1257,17 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1257 | continue; | 1257 | continue; |
| 1258 | }; | 1258 | }; |
| 1259 | | 1259 | |
| 1260 | if (global.value.tag == .Weak) continue; // If symbol is weak, nothing to do. | 1260 | switch (global.value.tag) { |
| 1261 | if (global.value.tag == .Strong) { // If both symbols are strong, we have a collision. | 1261 | .weak => continue, // If symbol is weak, nothing to do. |
| 1262 | log.err("symbol '{s}' defined multiple times", .{sym_name}); | 1262 | .strong => { |
| 1263 | return error.MultipleSymbolDefinitions; | 1263 | log.err("symbol '{s}' defined multiple times", .{sym_name}); |
| | 1264 | return error.MultipleSymbolDefinitions; |
| | 1265 | }, |
| | 1266 | else => {}, |
| 1264 | } | 1267 | } |
| 1265 | | 1268 | |
| 1266 | global.value = .{ | 1269 | global.value = .{ |
| 1267 | .tag = .Strong, | 1270 | .tag = .strong, |
| 1268 | .inner = .{ | 1271 | .inner = .{ |
| 1269 | .n_strx = 0, // This will be populated later. | 1272 | .n_strx = 0, // This will be populated later. |
| 1270 | .n_value = 0, // This will be populated later, | 1273 | .n_value = 0, // This will be populated later, |
| ... | @@ -1276,13 +1279,13 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { | ... | @@ -1276,13 +1279,13 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1276 | .index = @intCast(u32, sym_id), | 1279 | .index = @intCast(u32, sym_id), |
| 1277 | }; | 1280 | }; |
| 1278 | }, | 1281 | }, |
| 1279 | .Undef => { | 1282 | .undef => { |
| 1280 | const sym_name = object.getString(sym.inner.n_strx); | 1283 | const sym_name = object.getString(sym.inner.n_strx); |
| 1281 | if (self.symtab.contains(sym_name)) continue; // Nothing to do if we already found a definition. | 1284 | if (self.symtab.contains(sym_name)) continue; // Nothing to do if we already found a definition. |
| 1282 | | 1285 | |
| 1283 | const name = try self.allocator.dupe(u8, sym_name); | 1286 | const name = try self.allocator.dupe(u8, sym_name); |
| 1284 | try self.symtab.putNoClobber(self.allocator, name, .{ | 1287 | try self.symtab.putNoClobber(self.allocator, name, .{ |
| 1285 | .tag = .Undef, | 1288 | .tag = .undef, |
| 1286 | .inner = .{ | 1289 | .inner = .{ |
| 1287 | .n_strx = 0, | 1290 | .n_strx = 0, |
| 1288 | .n_value = 0, | 1291 | .n_value = 0, |
| ... | @@ -1292,7 +1295,7 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { | ... | @@ -1292,7 +1295,7 @@ fn resolveSymbolsInObject(self: *Zld, object_id: u16) !void { |
| 1292 | }, | 1295 | }, |
| 1293 | }); | 1296 | }); |
| 1294 | }, | 1297 | }, |
| 1295 | .Import => unreachable, // We don't expect any imports just yet. | 1298 | .import => unreachable, // We don't expect any imports just yet. |
| 1296 | } | 1299 | } |
| 1297 | } | 1300 | } |
| 1298 | } | 1301 | } |
| ... | @@ -1311,7 +1314,7 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1311,7 +1314,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 1311 | hit = false; | 1314 | hit = false; |
| 1312 | | 1315 | |
| 1313 | for (self.symtab.items()) |entry| { | 1316 | for (self.symtab.items()) |entry| { |
| 1314 | if (entry.value.tag != .Undef) continue; | 1317 | if (entry.value.tag != .undef) continue; |
| 1315 | | 1318 | |
| 1316 | const sym_name = entry.key; | 1319 | const sym_name = entry.key; |
| 1317 | | 1320 | |
| ... | @@ -1345,9 +1348,9 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1345,9 +1348,9 @@ fn resolveSymbols(self: *Zld) !void { |
| 1345 | // TODO Implement libSystem as a hard-coded library, or ship with | 1348 | // TODO Implement libSystem as a hard-coded library, or ship with |
| 1346 | // a libSystem.B.tbd definition file? | 1349 | // a libSystem.B.tbd definition file? |
| 1347 | for (self.symtab.items()) |*entry| { | 1350 | for (self.symtab.items()) |*entry| { |
| 1348 | if (entry.value.tag != .Undef) continue; | 1351 | if (entry.value.tag != .undef) continue; |
| 1349 | entry.value = .{ | 1352 | entry.value = .{ |
| 1350 | .tag = .Import, | 1353 | .tag = .import, |
| 1351 | .inner = .{ | 1354 | .inner = .{ |
| 1352 | .n_strx = 0, // This will be populated once we write the string table. | 1355 | .n_strx = 0, // This will be populated once we write the string table. |
| 1353 | .n_type = macho.N_UNDF | macho.N_EXT, | 1356 | .n_type = macho.N_UNDF | macho.N_EXT, |
| ... | @@ -1362,7 +1365,7 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1362,7 +1365,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 1362 | // If there are any undefs left, flag an error. | 1365 | // If there are any undefs left, flag an error. |
| 1363 | var has_unresolved = false; | 1366 | var has_unresolved = false; |
| 1364 | for (self.symtab.items()) |entry| { | 1367 | for (self.symtab.items()) |entry| { |
| 1365 | if (entry.value.tag != .Undef) continue; | 1368 | if (entry.value.tag != .undef) continue; |
| 1366 | has_unresolved = true; | 1369 | has_unresolved = true; |
| 1367 | log.err("undefined reference to symbol '{s}'", .{entry.key}); | 1370 | log.err("undefined reference to symbol '{s}'", .{entry.key}); |
| 1368 | } | 1371 | } |
| ... | @@ -1373,7 +1376,7 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1373,7 +1376,7 @@ fn resolveSymbols(self: *Zld) !void { |
| 1373 | // Finally put dyld_stub_binder as an Import | 1376 | // Finally put dyld_stub_binder as an Import |
| 1374 | var name = try self.allocator.dupe(u8, "dyld_stub_binder"); | 1377 | var name = try self.allocator.dupe(u8, "dyld_stub_binder"); |
| 1375 | try self.symtab.putNoClobber(self.allocator, name, .{ | 1378 | try self.symtab.putNoClobber(self.allocator, name, .{ |
| 1376 | .tag = .Import, | 1379 | .tag = .import, |
| 1377 | .inner = .{ | 1380 | .inner = .{ |
| 1378 | .n_strx = 0, // This will be populated once we write the string table. | 1381 | .n_strx = 0, // This will be populated once we write the string table. |
| 1379 | .n_type = macho.N_UNDF | macho.N_EXT, | 1382 | .n_type = macho.N_UNDF | macho.N_EXT, |
| ... | @@ -1401,7 +1404,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { | ... | @@ -1401,7 +1404,7 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1401 | if (self.got_entries.contains(sym_name)) continue; | 1404 | if (self.got_entries.contains(sym_name)) continue; |
| 1402 | | 1405 | |
| 1403 | // TODO clean this up | 1406 | // TODO clean this up |
| 1404 | const is_import = self.symtab.get(sym_name).?.tag == .Import; | 1407 | const is_import = self.symtab.get(sym_name).?.tag == .import; |
| 1405 | var name = try self.allocator.dupe(u8, sym_name); | 1408 | var name = try self.allocator.dupe(u8, sym_name); |
| 1406 | const index = @intCast(u32, self.got_entries.items().len); | 1409 | const index = @intCast(u32, self.got_entries.items().len); |
| 1407 | try self.got_entries.putNoClobber(self.allocator, name, .{ | 1410 | try self.got_entries.putNoClobber(self.allocator, name, .{ |
| ... | @@ -1418,11 +1421,11 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { | ... | @@ -1418,11 +1421,11 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1418 | const sym = object.symtab.items[reloc.target.symbol]; | 1421 | const sym = object.symtab.items[reloc.target.symbol]; |
| 1419 | const sym_name = object.getString(sym.inner.n_strx); | 1422 | const sym_name = object.getString(sym.inner.n_strx); |
| 1420 | | 1423 | |
| 1421 | if (sym.tag != .Undef) continue; | 1424 | if (sym.tag != .undef) continue; |
| 1422 | | 1425 | |
| 1423 | const in_globals = self.symtab.get(sym_name) orelse unreachable; | 1426 | const in_globals = self.symtab.get(sym_name) orelse unreachable; |
| 1424 | | 1427 | |
| 1425 | if (in_globals.tag != .Import) continue; | 1428 | if (in_globals.tag != .import) continue; |
| 1426 | if (self.stubs.contains(sym_name)) continue; | 1429 | if (self.stubs.contains(sym_name)) continue; |
| 1427 | | 1430 | |
| 1428 | var name = try self.allocator.dupe(u8, sym_name); | 1431 | var name = try self.allocator.dupe(u8, sym_name); |
| ... | @@ -1589,7 +1592,7 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: Relocation.Target) !u64 { | ... | @@ -1589,7 +1592,7 @@ fn relocTargetAddr(self: *Zld, object_id: u16, target: Relocation.Target) !u64 { |
| 1589 | const sym_name = object.getString(sym.inner.n_strx); | 1592 | const sym_name = object.getString(sym.inner.n_strx); |
| 1590 | | 1593 | |
| 1591 | switch (sym.tag) { | 1594 | switch (sym.tag) { |
| 1592 | .Stab, .Local, .Weak, .Strong => { | 1595 | .stab, .local, .weak, .strong => { |
| 1593 | log.warn(" | local symbol '{s}'", .{sym_name}); | 1596 | log.warn(" | local symbol '{s}'", .{sym_name}); |
| 1594 | break :blk sym.inner.n_value; | 1597 | break :blk sym.inner.n_value; |
| 1595 | }, | 1598 | }, |
| ... | @@ -2245,7 +2248,7 @@ fn writeBindInfoTable(self: *Zld) !void { | ... | @@ -2245,7 +2248,7 @@ fn writeBindInfoTable(self: *Zld) !void { |
| 2245 | | 2248 | |
| 2246 | const dylib_ordinal = dylib_ordinal: { | 2249 | const dylib_ordinal = dylib_ordinal: { |
| 2247 | const sym = self.symtab.get(entry.key) orelse continue; // local indirection | 2250 | const sym = self.symtab.get(entry.key) orelse continue; // local indirection |
| 2248 | if (sym.tag != .Import) continue; // local indirection | 2251 | if (sym.tag != .import) continue; // local indirection |
| 2249 | break :dylib_ordinal sym.file.? + 1; | 2252 | break :dylib_ordinal sym.file.? + 1; |
| 2250 | }; | 2253 | }; |
| 2251 | | 2254 | |
| ... | @@ -2308,7 +2311,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { | ... | @@ -2308,7 +2311,7 @@ fn writeLazyBindInfoTable(self: *Zld) !void { |
| 2308 | for (self.stubs.items()) |entry| { | 2311 | for (self.stubs.items()) |entry| { |
| 2309 | const dylib_ordinal = dylib_ordinal: { | 2312 | const dylib_ordinal = dylib_ordinal: { |
| 2310 | const sym = self.symtab.get(entry.key) orelse unreachable; | 2313 | const sym = self.symtab.get(entry.key) orelse unreachable; |
| 2311 | assert(sym.tag == .Import); | 2314 | assert(sym.tag == .import); |
| 2312 | break :dylib_ordinal sym.file.? + 1; | 2315 | break :dylib_ordinal sym.file.? + 1; |
| 2313 | }; | 2316 | }; |
| 2314 | | 2317 | |
| ... | @@ -2562,7 +2565,7 @@ fn populateStringTable(self: *Zld) !void { | ... | @@ -2562,7 +2565,7 @@ fn populateStringTable(self: *Zld) !void { |
| 2562 | for (self.objects.items) |*object| { | 2565 | for (self.objects.items) |*object| { |
| 2563 | for (object.symtab.items) |*sym| { | 2566 | for (object.symtab.items) |*sym| { |
| 2564 | switch (sym.tag) { | 2567 | switch (sym.tag) { |
| 2565 | .Undef, .Import => continue, | 2568 | .undef, .import => continue, |
| 2566 | else => {}, | 2569 | else => {}, |
| 2567 | } | 2570 | } |
| 2568 | const sym_name = object.getString(sym.inner.n_strx); | 2571 | const sym_name = object.getString(sym.inner.n_strx); |
| ... | @@ -2572,7 +2575,7 @@ fn populateStringTable(self: *Zld) !void { | ... | @@ -2572,7 +2575,7 @@ fn populateStringTable(self: *Zld) !void { |
| 2572 | } | 2575 | } |
| 2573 | | 2576 | |
| 2574 | for (self.symtab.items()) |*entry| { | 2577 | for (self.symtab.items()) |*entry| { |
| 2575 | if (entry.value.tag != .Import) continue; | 2578 | if (entry.value.tag != .import) continue; |
| 2576 | | 2579 | |
| 2577 | const n_strx = try self.makeString(entry.key); | 2580 | const n_strx = try self.makeString(entry.key); |
| 2578 | entry.value.inner.n_strx = n_strx; | 2581 | entry.value.inner.n_strx = n_strx; |
| ... | @@ -2589,7 +2592,7 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2589,7 +2592,7 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2589 | for (self.objects.items) |object| { | 2592 | for (self.objects.items) |object| { |
| 2590 | for (object.symtab.items) |sym| { | 2593 | for (object.symtab.items) |sym| { |
| 2591 | switch (sym.tag) { | 2594 | switch (sym.tag) { |
| 2592 | .Stab, .Local => {}, | 2595 | .stab, .local => {}, |
| 2593 | else => continue, | 2596 | else => continue, |
| 2594 | } | 2597 | } |
| 2595 | | 2598 | |
| ... | @@ -2609,10 +2612,10 @@ fn writeSymbolTable(self: *Zld) !void { | ... | @@ -2609,10 +2612,10 @@ fn writeSymbolTable(self: *Zld) !void { |
| 2609 | var undef_id: u32 = 0; | 2612 | var undef_id: u32 = 0; |
| 2610 | for (self.symtab.items()) |entry| { | 2613 | for (self.symtab.items()) |entry| { |
| 2611 | switch (entry.value.tag) { | 2614 | switch (entry.value.tag) { |
| 2612 | .Weak, .Strong => { | 2615 | .weak, .strong => { |
| 2613 | try exports.append(entry.value.inner); | 2616 | try exports.append(entry.value.inner); |
| 2614 | }, | 2617 | }, |
| 2615 | .Import => { | 2618 | .import => { |
| 2616 | try undefs.append(entry.value.inner); | 2619 | try undefs.append(entry.value.inner); |
| 2617 | try undefs_ids.putNoClobber(entry.key, undef_id); | 2620 | try undefs_ids.putNoClobber(entry.key, undef_id); |
| 2618 | undef_id += 1; | 2621 | undef_id += 1; |