| ... | @@ -83,8 +83,8 @@ strtab_dir: std.StringHashMapUnmanaged(u32) = .{}, | ... | @@ -83,8 +83,8 @@ strtab_dir: std.StringHashMapUnmanaged(u32) = .{}, |
| 83 | | 83 | |
| 84 | threadlocal_offsets: std.ArrayListUnmanaged(u64) = .{}, | 84 | threadlocal_offsets: std.ArrayListUnmanaged(u64) = .{}, |
| 85 | local_rebases: std.ArrayListUnmanaged(Pointer) = .{}, | 85 | local_rebases: std.ArrayListUnmanaged(Pointer) = .{}, |
| 86 | stubs: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 86 | stubs: std.ArrayListUnmanaged(*Symbol) = .{}, |
| 87 | got_entries: std.StringArrayHashMapUnmanaged(*Symbol) = .{}, | 87 | got_entries: std.ArrayListUnmanaged(*Symbol) = .{}, |
| 88 | | 88 | |
| 89 | stub_helper_stubs_start_off: ?u64 = null, | 89 | stub_helper_stubs_start_off: ?u64 = null, |
| 90 | | 90 | |
| ... | @@ -200,9 +200,9 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { | ... | @@ -200,9 +200,9 @@ pub fn link(self: *Zld, files: []const []const u8, out_path: []const u8) !void { |
| 200 | try self.populateMetadata(); | 200 | try self.populateMetadata(); |
| 201 | try self.parseInputFiles(files); | 201 | try self.parseInputFiles(files); |
| 202 | try self.resolveSymbols(); | 202 | try self.resolveSymbols(); |
| 203 | self.printSymbols(); | 203 | // self.printSymbols(); |
| | 204 | try self.resolveStubsAndGotEntries(); |
| 204 | return error.Unfinished; | 205 | return error.Unfinished; |
| 205 | // try self.resolveStubsAndGotEntries(); | | |
| 206 | // try self.updateMetadata(); | 206 | // try self.updateMetadata(); |
| 207 | // try self.sortSections(); | 207 | // try self.sortSections(); |
| 208 | // try self.allocateTextSegment(); | 208 | // try self.allocateTextSegment(); |
| ... | @@ -1413,8 +1413,8 @@ fn resolveSymbols(self: *Zld) !void { | ... | @@ -1413,8 +1413,8 @@ fn resolveSymbols(self: *Zld) !void { |
| 1413 | } | 1413 | } |
| 1414 | | 1414 | |
| 1415 | fn resolveStubsAndGotEntries(self: *Zld) !void { | 1415 | fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1416 | for (self.objects.items) |object, object_id| { | 1416 | for (self.objects.items) |object| { |
| 1417 | log.debug("resolving stubs and got entries from {s}", .{object.name}); | 1417 | log.warn("resolving stubs and got entries from {s}", .{object.name}); |
| 1418 | | 1418 | |
| 1419 | for (object.sections.items) |sect| { | 1419 | for (object.sections.items) |sect| { |
| 1420 | const relocs = sect.relocs orelse continue; | 1420 | const relocs = sect.relocs orelse continue; |
| ... | @@ -1422,42 +1422,31 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { | ... | @@ -1422,42 +1422,31 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1422 | switch (rel.@"type") { | 1422 | switch (rel.@"type") { |
| 1423 | .unsigned => continue, | 1423 | .unsigned => continue, |
| 1424 | .got_page, .got_page_off, .got_load, .got => { | 1424 | .got_page, .got_page_off, .got_load, .got => { |
| 1425 | const sym = object.symtab.items[rel.target.symbol]; | 1425 | const sym = rel.target.symbol.getTopmostAlias(); |
| 1426 | const sym_name = object.getString(sym.n_strx); | 1426 | if (sym.got_index != null) continue; |
| 1427 | | 1427 | |
| 1428 | if (self.got_entries.contains(sym_name)) continue; | 1428 | const index = @intCast(u32, self.got_entries.items.len); |
| 1429 | | 1429 | sym.got_index = index; |
| 1430 | // TODO clean this up | 1430 | try self.got_entries.append(self.allocator, sym); |
| 1431 | const is_import = self.symtab.get(sym_name).?.tag == .import; | | |
| 1432 | var name = try self.allocator.dupe(u8, sym_name); | | |
| 1433 | const index = @intCast(u32, self.got_entries.items().len); | | |
| 1434 | try self.got_entries.putNoClobber(self.allocator, name, .{ | | |
| 1435 | .tag = if (is_import) .import else .local, | | |
| 1436 | .index = index, | | |
| 1437 | .target_addr = 0, | | |
| 1438 | .file = if (is_import) 0 else @intCast(u16, object_id), | | |
| 1439 | }); | | |
| 1440 | | 1431 | |
| 1441 | log.debug(" | found GOT entry {s}: {}", .{ sym_name, self.got_entries.get(sym_name) }); | 1432 | log.warn(" | found GOT entry {s}: {*}", .{ sym.name, sym }); |
| 1442 | }, | 1433 | }, |
| 1443 | else => { | 1434 | else => { |
| 1444 | if (rel.target != .symbol) continue; | 1435 | if (rel.target != .symbol) continue; |
| 1445 | | 1436 | |
| 1446 | const sym = object.symtab.items[rel.target.symbol]; | 1437 | const sym = rel.target.symbol.getTopmostAlias(); |
| 1447 | const sym_name = object.getString(sym.n_strx); | 1438 | assert(sym.@"type" != .unresolved); |
| 1448 | | 1439 | |
| 1449 | if (!Symbol.isUndef(sym)) continue; | 1440 | if (sym.stubs_index != null) continue; |
| | 1441 | if (sym.cast(Symbol.Regular)) |reg| { |
| | 1442 | if (!reg.weak_ref) continue; |
| | 1443 | } |
| 1450 | | 1444 | |
| 1451 | const in_globals = self.symtab.get(sym_name) orelse unreachable; | 1445 | const index = @intCast(u32, self.stubs.items.len); |
| | 1446 | sym.stubs_index = index; |
| | 1447 | try self.stubs.append(self.allocator, sym); |
| 1452 | | 1448 | |
| 1453 | if (in_globals.tag != .import) continue; | 1449 | log.warn(" | found stub {s}: {*}", .{ sym.name, sym }); |
| 1454 | if (self.stubs.contains(sym_name)) continue; | | |
| 1455 | | | |
| 1456 | var name = try self.allocator.dupe(u8, sym_name); | | |
| 1457 | const index = @intCast(u32, self.stubs.items().len); | | |
| 1458 | try self.stubs.putNoClobber(self.allocator, name, index); | | |
| 1459 | | | |
| 1460 | log.debug(" | found stub {s}: {}", .{ sym_name, self.stubs.get(sym_name) }); | | |
| 1461 | }, | 1450 | }, |
| 1462 | } | 1451 | } |
| 1463 | } | 1452 | } |
| ... | @@ -1465,16 +1454,12 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { | ... | @@ -1465,16 +1454,12 @@ fn resolveStubsAndGotEntries(self: *Zld) !void { |
| 1465 | } | 1454 | } |
| 1466 | | 1455 | |
| 1467 | // Finally, put dyld_stub_binder as the final GOT entry | 1456 | // Finally, put dyld_stub_binder as the final GOT entry |
| 1468 | var name = try self.allocator.dupe(u8, "dyld_stub_binder"); | 1457 | const sym = self.imports.get("dyld_stub_binder") orelse unreachable; |
| 1469 | const index = @intCast(u32, self.got_entries.items().len); | 1458 | const index = @intCast(u32, self.got_entries.items.len); |
| 1470 | try self.got_entries.putNoClobber(self.allocator, name, .{ | 1459 | sym.got_index = index; |
| 1471 | .tag = .import, | 1460 | try self.got_entries.append(self.allocator, sym); |
| 1472 | .index = index, | | |
| 1473 | .target_addr = 0, | | |
| 1474 | .file = 0, | | |
| 1475 | }); | | |
| 1476 | | 1461 | |
| 1477 | log.debug(" | found GOT entry dyld_stub_binder: {}", .{self.got_entries.get("dyld_stub_binder")}); | 1462 | log.warn(" | found GOT entry {s}: {*}", .{ sym.name, sym }); |
| 1478 | } | 1463 | } |
| 1479 | | 1464 | |
| 1480 | fn resolveRelocsAndWriteSections(self: *Zld) !void { | 1465 | fn resolveRelocsAndWriteSections(self: *Zld) !void { |